From 9109c2dda8664f5c823aa0b9a6e03156ad01c49d Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 22 May 2025 15:37:25 +0200 Subject: [PATCH 01/34] refactor(ui)!: re-wrote message actions and modals (#2156) Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com> --- .../stream_chat/lib/src/client/channel.dart | 25 +- packages/stream_chat_flutter/CHANGELOG.md | 28 + packages/stream_chat_flutter/dart_test.yaml | 5 + .../src/channel/stream_channel_avatar.dart | 2 +- .../context_menu_reaction_picker.dart | 168 ---- .../download_menu_item.dart | 32 - .../stream_chat_context_menu_item.dart | 51 - .../full_screen_media_desktop.dart | 62 +- .../lib/src/localization/translations.dart | 7 +- .../src/message_action/message_action.dart | 70 ++ .../message_action/message_action_item.dart | 81 ++ .../message_action/message_action_type.dart | 131 +++ .../message_actions_builder.dart | 248 +++++ .../copy_message_button.dart | 43 - .../delete_message_button.dart | 50 - .../edit_message_button.dart | 42 - .../flag_message_button.dart | 42 - .../message_actions_modal/mam_widgets.dart | 8 - .../mark_unread_message_button.dart | 43 - .../message_actions_modal/message_action.dart | 23 - .../message_actions_modal.dart | 425 -------- .../moderated_message_actions_modal.dart | 99 -- .../pin_message_button.dart | 49 - .../message_actions_modal/reply_button.dart | 42 - .../resend_message_button.dart | 52 - .../thread_reply_button.dart | 51 - .../message_list_view/message_list_view.dart | 34 +- .../message_action_confirmation_modal.dart | 112 +++ .../message_modal/message_actions_modal.dart | 155 +++ .../lib/src/message_modal/message_modal.dart | 165 ++++ .../message_reactions_modal.dart | 143 +++ .../moderated_message_actions_modal.dart | 87 ++ .../src/message_widget/ephemeral_message.dart | 7 +- .../src/message_widget/message_widget.dart | 878 ++++++++--------- .../message_widget_content.dart | 6 +- .../message_widget_content_components.dart | 1 - .../reactions/message_reactions_modal.dart | 129 --- .../reactions/reaction_picker.dart | 224 ++--- .../reactions/reaction_picker_icon_list.dart | 202 ++++ .../reactions/reactions_align.dart | 93 +- .../lib/src/misc/adaptive_dialog_action.dart | 71 ++ .../lib/src/theme/stream_chat_theme.dart | 9 + .../lib/src/utils/extensions.dart | 24 + .../lib/stream_chat_flutter.dart | 10 +- .../download_menu_item_test.dart | 51 - .../goldens/ci/download_menu_item_0.png | Bin 825 -> 0 bytes .../ci/stream_chat_context_menu_item_0.png | Bin 458 -> 0 bytes .../stream_chat_context_menu_item_test.dart | 51 - .../goldens/ci/delete_message_dialog_0.png | Bin 4184 -> 4314 bytes ..._message_action_item_custom_child_dark.png | Bin 0 -> 810 bytes ...message_action_item_custom_child_light.png | Bin 0 -> 820 bytes ...essage_action_item_custom_styling_dark.png | Bin 0 -> 392 bytes ...ssage_action_item_custom_styling_light.png | Bin 0 -> 399 bytes ...stream_message_action_item_delete_dark.png | Bin 0 -> 388 bytes ...tream_message_action_item_delete_light.png | Bin 0 -> 391 bytes .../stream_message_action_item_reply_dark.png | Bin 0 -> 396 bytes ...stream_message_action_item_reply_light.png | Bin 0 -> 391 bytes .../message_action_item_test.dart | 167 ++++ .../message_actions_builder_test.dart | 561 +++++++++++ .../message_actions_modal_test.dart | 916 ------------------ .../moderated_message_actions_modal_dark.png | Bin 0 -> 2458 bytes .../moderated_message_actions_modal_light.png | Bin 0 -> 2550 bytes .../ci/stream_message_actions_modal_dark.png | Bin 0 -> 5034 bytes .../ci/stream_message_actions_modal_light.png | Bin 0 -> 5140 bytes ...am_message_actions_modal_reversed_dark.png | Bin 0 -> 5081 bytes ...m_message_actions_modal_reversed_light.png | Bin 0 -> 5317 bytes ...ons_modal_reversed_with_reactions_dark.png | Bin 0 -> 8393 bytes ...ns_modal_reversed_with_reactions_light.png | Bin 0 -> 8702 bytes ...sage_actions_modal_with_reactions_dark.png | Bin 0 -> 8323 bytes ...age_actions_modal_with_reactions_light.png | Bin 0 -> 8456 bytes .../stream_message_reactions_modal_dark.png | Bin 0 -> 12082 bytes .../stream_message_reactions_modal_light.png | Bin 0 -> 13269 bytes ..._message_reactions_modal_reversed_dark.png | Bin 0 -> 11837 bytes ...message_reactions_modal_reversed_light.png | Bin 0 -> 13104 bytes .../message_actions_modal_test.dart | 258 +++++ .../message_reactions_modal_test.dart | 277 ++++++ .../moderated_message_actions_modal_test.dart | 139 +++ .../message_reactions_modal_test.dart | 121 --- .../ci/reaction_icon_button_selected_dark.png | Bin 0 -> 670 bytes .../reaction_icon_button_selected_light.png | Bin 0 -> 628 bytes .../reaction_icon_button_unselected_dark.png | Bin 0 -> 615 bytes .../reaction_icon_button_unselected_light.png | Bin 0 -> 647 bytes .../ci/reaction_picker_icon_list_dark.png | Bin 0 -> 2741 bytes .../ci/reaction_picker_icon_list_light.png | Bin 0 -> 3049 bytes ...eaction_picker_icon_list_selected_dark.png | Bin 0 -> 2843 bytes ...action_picker_icon_list_selected_light.png | Bin 0 -> 3054 bytes .../ci/stream_reaction_picker_dark.png | Bin 0 -> 3460 bytes .../ci/stream_reaction_picker_light.png | Bin 0 -> 3413 bytes .../stream_reaction_picker_selected_dark.png | Bin 0 -> 3536 bytes .../stream_reaction_picker_selected_light.png | Bin 0 -> 3451 bytes .../reaction_picker_icon_list_test.dart | 387 ++++++++ .../reactions/reaction_picker_test.dart | 198 ++++ .../lib/src/stream_chat_localizations_ca.dart | 14 +- .../lib/src/stream_chat_localizations_de.dart | 11 +- .../lib/src/stream_chat_localizations_en.dart | 14 +- .../lib/src/stream_chat_localizations_es.dart | 14 +- .../lib/src/stream_chat_localizations_fr.dart | 13 +- .../lib/src/stream_chat_localizations_hi.dart | 15 +- .../lib/src/stream_chat_localizations_it.dart | 15 +- .../lib/src/stream_chat_localizations_ja.dart | 13 +- .../lib/src/stream_chat_localizations_ko.dart | 4 +- .../lib/src/stream_chat_localizations_no.dart | 11 +- .../lib/src/stream_chat_localizations_pt.dart | 13 +- 103 files changed, 4234 insertions(+), 3258 deletions(-) create mode 100644 packages/stream_chat_flutter/dart_test.yaml delete mode 100644 packages/stream_chat_flutter/lib/src/context_menu_items/context_menu_reaction_picker.dart delete mode 100644 packages/stream_chat_flutter/lib/src/context_menu_items/download_menu_item.dart delete mode 100644 packages/stream_chat_flutter/lib/src/context_menu_items/stream_chat_context_menu_item.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_action/message_action.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_action/message_action_item.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/copy_message_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/delete_message_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/edit_message_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/flag_message_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/mam_widgets.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/mark_unread_message_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/message_action.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/message_actions_modal.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/moderated_message_actions_modal.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/pin_message_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/reply_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/resend_message_button.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_actions_modal/thread_reply_button.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_modal/message_action_confirmation_modal.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_modal/moderated_message_actions_modal.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_widget/reactions/message_reactions_modal.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart create mode 100644 packages/stream_chat_flutter/lib/src/misc/adaptive_dialog_action.dart delete mode 100644 packages/stream_chat_flutter/test/src/context_menu_items/download_menu_item_test.dart delete mode 100644 packages/stream_chat_flutter/test/src/context_menu_items/goldens/ci/download_menu_item_0.png delete mode 100644 packages/stream_chat_flutter/test/src/context_menu_items/goldens/ci/stream_chat_context_menu_item_0.png delete mode 100644 packages/stream_chat_flutter/test/src/context_menu_items/stream_chat_context_menu_item_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_child_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_child_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_styling_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_styling_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_reply_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_reply_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_action/message_action_item_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart delete mode 100644 packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_with_reactions_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_with_reactions_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_modal/message_actions_modal_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_modal/moderated_message_actions_modal_test.dart delete mode 100644 packages/stream_chat_flutter/test/src/message_reactions_modal/message_reactions_modal_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_icon_list_test.dart create mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_test.dart diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index e42cc5c777..c6471b5e92 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -987,12 +987,20 @@ class Channel { } } - /// Retry the operation on the message based on the failed state. + /// Retries operations on a message based on its failed state. /// - /// For example, if the message failed to send, it will retry sending the - /// message and vice-versa. + /// This method examines the message's state and performs the appropriate + /// retry action: + /// - For [MessageState.sendingFailed], it attempts to send the message. + /// - For [MessageState.updatingFailed], it attempts to update the message. + /// - For [MessageState.deletingFailed], it attempts to delete the message. + /// with the same 'hard' parameter that was used in the original request + /// - For messages with [isBouncedWithError], it attempts to send the message. Future retryMessage(Message message) async { - assert(message.state.isFailed, 'Message state is not failed'); + assert( + message.state.isFailed || message.isBouncedWithError, + 'Only failed or bounced messages can be retried', + ); return message.state.maybeWhen( failed: (state, _) => state.when( @@ -1000,7 +1008,14 @@ class Channel { updatingFailed: () => updateMessage(message), deletingFailed: (hard) => deleteMessage(message, hard: hard), ), - orElse: () => throw StateError('Message state is not failed'), + orElse: () { + // Check if the message is bounced with error. + if (message.isBouncedWithError) return sendMessage(message); + + throw StateError( + 'Only failed or bounced messages can be retried', + ); + }, ); } diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index ca5f445327..c4b7b47881 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,31 @@ +## Upcoming Beta + +🛑️ Breaking + +- `StreamReactionPicker` now requires reactions to be explicitly handled via `onReactionPicked`. *(Automatic handling is no longer supported.)* +- `StreamMessageAction` is now generic `(StreamMessageAction)`, enhancing type safety. Individual onTap callbacks have been removed; actions are now handled centrally by widgets like `StreamMessageWidget.onCustomActionTap` or modals using action types. +- `StreamMessageReactionsModal` no longer requires the `messageTheme` parameter. The theme now automatically derives from the `reverse` property. + +For more details, please refer to the [migration guide](Unpublished). + +✅ Added + +- Added new `StreamMessageActionsBuilder` which provides a list of actions to be displayed in the message actions modal. +- Added new `StreamMessageActionConfirmationModal` for confirming destructive actions like delete or flag. +- Added new `StreamMessageModal` and `showStreamMessageModal` for consistent message-related modals with improved transitions and backdrop effects. + ```dart + showStreamMessageModal( + context: context, + ...other parameters, + builder: (context) => StreamMessageModal( + ...other parameters, + headerBuilder: (context) => YourCustomHeader(), + contentBuilder: (context) => YourCustomContent(), + ), + ); + ``` +- Exported `StreamMessageActionsModal` and `StreamModeratedMessageActionsModal` which are now based on `StreamMessageModal` for consistent styling and behavior. + ## Upcoming 🐞 Fixed diff --git a/packages/stream_chat_flutter/dart_test.yaml b/packages/stream_chat_flutter/dart_test.yaml new file mode 100644 index 0000000000..c329c9c85d --- /dev/null +++ b/packages/stream_chat_flutter/dart_test.yaml @@ -0,0 +1,5 @@ +# The existence of this file prevents warnings about unrecognized tags when running Alchemist tests. + +tags: + golden: + timeout: 15s \ No newline at end of file diff --git a/packages/stream_chat_flutter/lib/src/channel/stream_channel_avatar.dart b/packages/stream_chat_flutter/lib/src/channel/stream_channel_avatar.dart index 6c71eee4ee..536a45ff7a 100644 --- a/packages/stream_chat_flutter/lib/src/channel/stream_channel_avatar.dart +++ b/packages/stream_chat_flutter/lib/src/channel/stream_channel_avatar.dart @@ -108,7 +108,7 @@ class StreamChannelAvatar extends StatelessWidget { final fallbackWidget = Center( child: Text( - channel.name?[0] ?? '', + channel.name?.characters.firstOrNull ?? '', style: TextStyle( color: colorTheme.barsBg, fontWeight: FontWeight.bold, diff --git a/packages/stream_chat_flutter/lib/src/context_menu_items/context_menu_reaction_picker.dart b/packages/stream_chat_flutter/lib/src/context_menu_items/context_menu_reaction_picker.dart deleted file mode 100644 index fb22d44d27..0000000000 --- a/packages/stream_chat_flutter/lib/src/context_menu_items/context_menu_reaction_picker.dart +++ /dev/null @@ -1,168 +0,0 @@ -import 'package:ezanimation/ezanimation.dart'; -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template contextMenuReactionPicker} -/// Allows the user to select reactions to a message on desktop & web via -/// context menu. -/// -/// This differs slightly from [StreamReactionPicker] in order to match our -/// design spec. -/// -/// Used by the `_buildContextMenu()` function found in `message_widget.dart`. -/// It is not recommended to use this widget directly. -/// {@endtemplate} -class ContextMenuReactionPicker extends StatefulWidget { - /// {@macro contextMenuReactionPicker} - const ContextMenuReactionPicker({ - super.key, - required this.message, - }); - - /// The message to react to. - final Message message; - - @override - State createState() => - _ContextMenuReactionPickerState(); -} - -class _ContextMenuReactionPickerState extends State - with TickerProviderStateMixin { - List animations = []; - - Future triggerAnimations() async { - for (final a in animations) { - a.start(); - await Future.delayed(const Duration(milliseconds: 100)); - } - } - - Future pop() async { - for (final a in animations) { - a.stop(); - } - Navigator.of(context).pop(); - } - - /// Add a reaction to the message - void sendReaction(BuildContext context, String reactionType) { - StreamChannel.of(context).channel.sendReaction( - widget.message, - reactionType, - enforceUnique: - StreamChatConfiguration.of(context).enforceUniqueReactions, - ); - pop(); - } - - /// Remove a reaction from the message - void removeReaction(BuildContext context, Reaction reaction) { - StreamChannel.of(context).channel.deleteReaction(widget.message, reaction); - pop(); - } - - @override - void dispose() { - for (final a in animations) { - a.dispose(); - } - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final reactionIcons = StreamChatConfiguration.of(context).reactionIcons; - - if (animations.isEmpty && reactionIcons.isNotEmpty) { - reactionIcons.forEach((element) { - animations.add( - EzAnimation.tween( - Tween(begin: 0.0, end: 1.0), - const Duration(milliseconds: 250), - curve: Curves.easeInOutBack, - ), - ); - }); - - triggerAnimations(); - } - - final child = Material( - color: StreamChatTheme.of(context).messageListViewTheme.backgroundColor ?? - Theme.of(context).scaffoldBackgroundColor, - //clipBehavior: Clip.hardEdge, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Row( - spacing: 16, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceAround, - mainAxisSize: MainAxisSize.min, - children: reactionIcons.map((reactionIcon) { - final ownReactionIndex = widget.message.ownReactions?.indexWhere( - (reaction) => reaction.type == reactionIcon.type, - ) ?? - -1; - final index = reactionIcons.indexOf(reactionIcon); - - final child = reactionIcon.builder( - context, - ownReactionIndex != -1, - 24, - ); - - return ConstrainedBox( - constraints: const BoxConstraints.tightFor( - height: 24, - width: 24, - ), - child: RawMaterialButton( - elevation: 0, - shape: ContinuousRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - constraints: const BoxConstraints.tightFor( - height: 24, - width: 24, - ), - onPressed: () { - if (ownReactionIndex != -1) { - removeReaction( - context, - widget.message.ownReactions![ownReactionIndex], - ); - } else { - sendReaction( - context, - reactionIcon.type, - ); - } - }, - child: AnimatedBuilder( - animation: animations[index], - builder: (context, child) => Transform.scale( - scale: animations[index].value, - child: child, - ), - child: child, - ), - ), - ); - }).toList(), - ), - ), - ); - - return TweenAnimationBuilder( - tween: Tween(begin: 0, end: 1), - curve: Curves.easeInOutBack, - duration: const Duration(milliseconds: 500), - builder: (context, val, widget) => Transform.scale( - scale: val, - child: widget, - ), - child: child, - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/context_menu_items/download_menu_item.dart b/packages/stream_chat_flutter/lib/src/context_menu_items/download_menu_item.dart deleted file mode 100644 index a3f4d5a207..0000000000 --- a/packages/stream_chat_flutter/lib/src/context_menu_items/download_menu_item.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/stream_chat_context_menu_item.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template downloadMenuItem} -/// Defines a "download" context menu item that allows a user to download -/// a given attachment. -/// -/// Used in [DesktopFullscreenMedia]. -/// {@endtemplate} -class DownloadMenuItem extends StatelessWidget { - /// {@macro downloadMenuItem} - const DownloadMenuItem({ - super.key, - required this.attachment, - }); - - /// The attachment to download. - final Attachment attachment; - - @override - Widget build(BuildContext context) { - return StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.download), - title: Text(context.translations.downloadLabel), - onClick: () async { - Navigator.of(context).pop(); - StreamAttachmentHandler.instance.downloadAttachment(attachment); - }, - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/context_menu_items/stream_chat_context_menu_item.dart b/packages/stream_chat_flutter/lib/src/context_menu_items/stream_chat_context_menu_item.dart deleted file mode 100644 index dfe64684e2..0000000000 --- a/packages/stream_chat_flutter/lib/src/context_menu_items/stream_chat_context_menu_item.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template streamChatContextMenuItem} -/// Builds a context menu item according to Stream design specification. -/// {@endtemplate} -class StreamChatContextMenuItem extends StatelessWidget { - /// {@macro streamChatContextMenuItem} - const StreamChatContextMenuItem({ - super.key, - this.child, - this.leading, - this.title, - this.onClick, - }); - - /// The child widget for this menu item. Usually a [DesktopReactionPicker]. - /// - /// Leave null in order to use the default menu item widget. - final Widget? child; - - /// The widget to lead the menu item with. Usually an [Icon]. - /// - /// If [child] is specified, this will be ignored. - final Widget? leading; - - /// The title of the menu item. Usually a [Text]. - /// - /// If [child] is specified, this will be ignored. - final Widget? title; - - /// The action to perform when the menu item is clicked. - /// - /// If [child] is specified, this will be ignored. - final VoidCallback? onClick; - - @override - Widget build(BuildContext context) { - return Ink( - color: StreamChatTheme.of(context).messageListViewTheme.backgroundColor ?? - Theme.of(context).scaffoldBackgroundColor, - child: child ?? - ListTile( - dense: true, - leading: leading, - title: title, - onTap: onClick, - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart b/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart index acfc26477d..ed3ebcbcea 100644 --- a/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart +++ b/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:media_kit/media_kit.dart'; import 'package:media_kit_video/media_kit_video.dart'; import 'package:photo_view/photo_view.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart'; import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart'; import 'package:stream_chat_flutter/src/fullscreen_media/gallery_navigation_item.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; @@ -123,12 +122,11 @@ class _FullScreenMediaDesktopState extends State { children: [ ContextMenuArea( verticalPadding: 0, - builder: (_) => [ - DownloadMenuItem( - attachment: - widget.mediaAttachmentPackages[_currentPage.value].attachment, - ), - ], + builder: (context) { + final index = _currentPage.value; + final mediaAttachment = widget.mediaAttachmentPackages[index]; + return [_DownloadMenuItem(mediaAttachment: mediaAttachment)]; + }, child: _PlaylistPlayer( packages: videoPackages.values.toList(), autoStart: widget.autoplayVideos, @@ -359,8 +357,8 @@ class _FullScreenMediaDesktopState extends State { child: ContextMenuArea( verticalPadding: 0, builder: (_) => [ - DownloadMenuItem( - attachment: attachment, + _DownloadMenuItem( + mediaAttachment: currentAttachmentPackage, ), ], child: Video( @@ -384,6 +382,52 @@ class _FullScreenMediaDesktopState extends State { } } +/// {@template streamDownloadMenuItem} +/// A context menu item for downloading an attachment from a message. +/// +/// This widget displays a download option in a context menu, allowing users to +/// download the attachment associated with a message. +/// +/// It uses [StreamMessageActionItem] and [StreamMessageAction] to create a +/// consistent UI with other message actions. +/// {@endtemplate} +class _DownloadMenuItem extends StatelessWidget { + /// {@macro streamDownloadMenuItem} + const _DownloadMenuItem({ + required this.mediaAttachment, + }); + + /// The attachment package containing the message and attachment to download. + final StreamAttachmentPackage mediaAttachment; + static const String _attachmentKey = 'attachment'; + + @override + Widget build(BuildContext context) { + return StreamMessageActionItem( + action: StreamMessageAction( + leading: const StreamSvgIcon(icon: StreamSvgIcons.download), + title: Text(context.translations.downloadLabel), + action: CustomMessageAction( + message: mediaAttachment.message, + extraData: {_attachmentKey: mediaAttachment.attachment}, + ), + ), + // TODO: Use a callback to handle the action instead of onTap. + onTap: (action) async { + if (action is! CustomMessageAction) return; + final attachment = action.extraData[_attachmentKey] as Attachment?; + if (attachment == null) return; + + final popped = await Navigator.of(context).maybePop(); + if (popped) { + final handler = StreamAttachmentHandler.instance; + return handler.downloadAttachment(attachment).ignore(); + } + }, + ); + } +} + /// Class for packaging up things required for videos class DesktopVideoPackage { /// Constructor for creating [VideoPackage] diff --git a/packages/stream_chat_flutter/lib/src/localization/translations.dart b/packages/stream_chat_flutter/lib/src/localization/translations.dart index 87437b86a5..e08562e7a7 100644 --- a/packages/stream_chat_flutter/lib/src/localization/translations.dart +++ b/packages/stream_chat_flutter/lib/src/localization/translations.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + import 'package:jiffy/jiffy.dart'; import 'package:stream_chat_flutter/src/message_list_view/message_list_view.dart'; import 'package:stream_chat_flutter/src/misc/connection_status_builder.dart'; @@ -727,8 +729,7 @@ class DefaultTranslations implements Translations { @override String get flagMessageQuestion => - 'Do you want to send a copy of this message to a' - '\nmoderator for further investigation?'; + 'Do you want to send a copy of this message to a moderator for further investigation?'; @override String get flagLabel => 'FLAG'; @@ -751,7 +752,7 @@ class DefaultTranslations implements Translations { @override String get deleteMessageQuestion => - 'Are you sure you want to permanently delete this\nmessage?'; + 'Are you sure you want to permanently delete this message?'; @override String get operationCouldNotBeCompletedText => diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_action.dart b/packages/stream_chat_flutter/lib/src/message_action/message_action.dart new file mode 100644 index 0000000000..27e4fb00fa --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_action/message_action.dart @@ -0,0 +1,70 @@ +import 'package:flutter/widgets.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +part 'message_action_type.dart'; + +/// {@template streamMessageAction} +/// A class that represents an action that can be performed on a message. +/// +/// This class is used to define actions that appear in message action menus +/// or option lists, providing a consistent structure for message-related +/// actions including their visual representation and behavior. +/// {@endtemplate} +class StreamMessageAction { + /// {@macro streamMessageAction} + const StreamMessageAction({ + required this.action, + this.isDestructive = false, + this.leading, + this.iconColor, + this.title, + this.titleTextColor, + this.titleTextStyle, + this.backgroundColor, + }); + + /// The [MessageAction] that this item represents. + final T action; + + /// Whether the action is destructive. + /// + /// Destructive actions are typically displayed with a red color to indicate + /// that they will remove or delete content. + /// + /// Defaults to `false`. + final bool isDestructive; + + /// A widget to display before the title. + /// + /// Typically an [Icon] or a [CircleAvatar] widget. + final Widget? leading; + + /// The color for the [leading] icon. + /// + /// If this property is null, the icon will use the default color provided by + /// the theme or parent widget. + final Color? iconColor; + + /// The primary content of the action item. + /// + /// Typically a [Text] widget. + /// + /// This should not wrap. To enforce the single line limit, use + /// [Text.maxLines]. + final Widget? title; + + /// The color for the text in the [title]. + /// + /// If this property is null, the text will use the default color provided by + /// the theme or parent widget. + final Color? titleTextColor; + + /// The text style for the [title]. + /// + /// If this property is null, the title will use the default text style + /// provided by the theme or parent widget. + final TextStyle? titleTextStyle; + + /// Defines the background color of the action item. + final Color? backgroundColor; +} diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_action_item.dart b/packages/stream_chat_flutter/lib/src/message_action/message_action_item.dart new file mode 100644 index 0000000000..fa4af9328c --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_action/message_action_item.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/message_action/message_action.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; + +/// {@template streamMessageActionItem} +/// A widget that represents an action item within a message interface. +/// +/// This widget is typically used in action menus or option lists related to +/// messages, providing a consistent appearance for selectable actions with an +/// optional icon and title. +/// {@endtemplate} +class StreamMessageActionItem extends StatelessWidget { + /// {@macro streamMessageActionItem} + const StreamMessageActionItem({ + super.key, + required this.action, + this.onTap, + }); + + /// The underlying action that this item represents. + final StreamMessageAction action; + + /// Called when the user taps this action item. + /// + /// This callback provides the tap handling for the action item, and is + /// typically used to execute the associated action or dismiss menus. + final OnMessageActionTap? onTap; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final textTheme = theme.textTheme; + final colorTheme = theme.colorTheme; + + final iconColor = switch (action.isDestructive) { + true => action.iconColor ?? colorTheme.accentError, + false => action.iconColor ?? colorTheme.textLowEmphasis, + }; + + final titleTextColor = switch (action.isDestructive) { + true => action.titleTextColor ?? colorTheme.accentError, + false => action.titleTextColor ?? colorTheme.textHighEmphasis, + }; + + final titleTextStyle = action.titleTextStyle ?? textTheme.body; + final backgroundColor = action.backgroundColor ?? colorTheme.barsBg; + + return InkWell( + onTap: switch (onTap) { + final onTap? => () => onTap(action.action), + _ => null, + }, + child: Ink( + color: backgroundColor, + child: IconTheme.merge( + data: IconThemeData(color: iconColor), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 9, + horizontal: 16, + ), + child: Row( + spacing: 16, + mainAxisSize: MainAxisSize.min, + children: [ + if (action.leading case final leading?) leading, + if (action.title case final title?) + DefaultTextStyle( + style: titleTextStyle.copyWith( + color: titleTextColor, + ), + child: title, + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart b/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart new file mode 100644 index 0000000000..e92ed7da6b --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart @@ -0,0 +1,131 @@ +part of 'message_action.dart'; + +/// {@template onMessageActionTap} +/// Signature for a function that is called when a message action is tapped. +/// {@endtemplate} +typedef OnMessageActionTap = void Function(T action); + +/// {@template messageAction} +/// A sealed class that represents different actions that can be performed on a +/// message. +/// {@endtemplate} +sealed class MessageAction { + /// {@macro messageAction} + const MessageAction({required this.message}); + + /// The message this action applies to. + final Message message; +} + +/// Action to show reaction selector for adding reactions to a message +final class SelectReaction extends MessageAction { + /// Create a new select reaction action + const SelectReaction({ + required super.message, + required this.reaction, + this.enforceUnique = false, + }); + + /// The reaction to be added or removed from the message. + final Reaction reaction; + + /// Whether to enforce unique reactions. + final bool enforceUnique; +} + +/// Action to copy message content to clipboard +final class CopyMessage extends MessageAction { + /// Create a new copy message action + const CopyMessage({required super.message}); +} + +/// Action to delete a message from the conversation +final class DeleteMessage extends MessageAction { + /// Create a new delete message action + const DeleteMessage({required super.message}); +} + +/// Action to hard delete a message permanently from the conversation +final class HardDeleteMessage extends MessageAction { + /// Create a new hard delete message action + const HardDeleteMessage({required super.message}); +} + +/// Action to modify content of an existing message +final class EditMessage extends MessageAction { + /// Create a new edit message action + const EditMessage({required super.message}); +} + +/// Action to flag a message for moderator review +final class FlagMessage extends MessageAction { + /// Create a new flag message action + const FlagMessage({required super.message}); +} + +/// Action to mark a message as unread for later viewing +final class MarkUnread extends MessageAction { + /// Create a new mark unread action + const MarkUnread({required super.message}); +} + +/// Action to mute a user to prevent notifications from their messages +final class MuteUser extends MessageAction { + /// Create a new mute user action + const MuteUser({required super.message, required this.user}); + + /// The user to be muted. + final User user; +} + +/// Action to unmute a user to receive notifications from their messages +final class UnmuteUser extends MessageAction { + /// Create a new unmute user action + const UnmuteUser({required super.message, required this.user}); + + /// The user to be unmuted. + final User user; +} + +/// Action to pin a message to make it prominently visible in the channel +final class PinMessage extends MessageAction { + /// Create a new pin message action + const PinMessage({required super.message}); +} + +/// Action to remove a previously pinned message +final class UnpinMessage extends MessageAction { + /// Create a new unpin message action + const UnpinMessage({required super.message}); +} + +/// Action to attempt to resend a message that failed to send +final class ResendMessage extends MessageAction { + /// Create a new resend message action + const ResendMessage({required super.message}); +} + +/// Action to create a reply with quoted original message content +final class QuotedReply extends MessageAction { + /// Create a new quoted reply action + const QuotedReply({required super.message}); +} + +/// Action to start a threaded conversation from a message +final class ThreadReply extends MessageAction { + /// Create a new thread reply action + const ThreadReply({required super.message}); +} + +/// Custom message action that allows for additional data to be passed +/// along with the message. +final class CustomMessageAction extends MessageAction { + /// Create a new custom message action + const CustomMessageAction({ + required super.message, + this.extraData = const {}, + }); + + /// Map of extra data associated with the action. + final Map extraData; +} diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart new file mode 100644 index 0000000000..d7bc0aafea --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart @@ -0,0 +1,248 @@ +import 'package:flutter/widgets.dart'; +import 'package:stream_chat_flutter/src/icons/stream_svg_icon.dart'; +import 'package:stream_chat_flutter/src/message_action/message_action.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_chat_flutter/src/utils/extensions.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// {@template streamMessageActionsBuilder} +/// A utility class that provides a builder for message actions +/// which can be reused across mobile platforms. +/// {@endtemplate} +class StreamMessageActionsBuilder { + /// Private constructor to prevent instantiation + StreamMessageActionsBuilder._(); + + /// Returns a list of message actions for the "bounced with error" state. + /// + /// This method builds a list of [StreamMessageAction]s that are applicable to + /// the given [message] when it is in the "bounced with error" state. + /// + /// The actions include options to retry sending the message, edit or delete + /// the message. + static List buildBouncedErrorActions({ + required BuildContext context, + required Message message, + }) { + // If the message is not bounced with an error, we don't show any actions. + if (!message.isBouncedWithError) return []; + + return [ + StreamMessageAction( + action: ResendMessage(message: message), + iconColor: StreamChatTheme.of(context).colorTheme.accentPrimary, + title: Text(context.translations.sendAnywayLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.circleUp), + ), + StreamMessageAction( + action: EditMessage(message: message), + title: Text(context.translations.editMessageLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.edit), + ), + StreamMessageAction( + isDestructive: true, + action: HardDeleteMessage(message: message), + title: Text(context.translations.deleteMessageLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.delete), + ), + ]; + } + + /// Returns a list of message actions based on the provided message and + /// channel capabilities. + /// + /// This method builds a list of [StreamMessageAction]s that are applicable to + /// the given [message] in the [channel], considering the permissions of the + /// [currentUser] and the current state of the message. + static List buildActions({ + required BuildContext context, + required Message message, + required Channel channel, + OwnUser? currentUser, + Iterable? customActions, + }) { + // If the message is deleted, we don't show any actions. + if (message.isDeleted) return []; + + final messageState = message.state; + if (messageState.isFailed) { + return [ + if (messageState.isSendingFailed || messageState.isUpdatingFailed) ...[ + StreamMessageAction( + action: ResendMessage(message: message), + leading: const StreamSvgIcon(icon: StreamSvgIcons.circleUp), + iconColor: StreamChatTheme.of(context).colorTheme.accentPrimary, + title: Text( + context.translations.toggleResendOrResendEditedMessage( + isUpdateFailed: messageState.isUpdatingFailed, + ), + ), + ), + ], + if (message.state.isDeletingFailed) + StreamMessageAction( + isDestructive: true, + action: ResendMessage(message: message), + leading: const StreamSvgIcon(icon: StreamSvgIcons.delete), + title: Text( + context.translations.toggleDeleteRetryDeleteMessageText( + isDeleteFailed: true, + ), + ), + ), + ]; + } + + final isSentByCurrentUser = message.user?.id == currentUser?.id; + final isThreadMessage = message.parentId != null; + final isParentMessage = (message.replyCount ?? 0) > 0; + final canShowInChannel = message.showInChannel ?? true; + final isPrivateMessage = message.hasRestrictedVisibility; + final canSendReply = channel.canSendReply; + final canPinMessage = channel.canPinMessage; + final canQuoteMessage = channel.canQuoteMessage; + final canReceiveReadEvents = channel.canReceiveReadEvents; + final canUpdateAnyMessage = channel.canUpdateAnyMessage; + final canUpdateOwnMessage = channel.canUpdateOwnMessage; + final canDeleteAnyMessage = channel.canDeleteAnyMessage; + final canDeleteOwnMessage = channel.canDeleteOwnMessage; + final containsPoll = message.poll != null; + final containsGiphy = message.attachments.any( + (attachment) => attachment.type == AttachmentType.giphy, + ); + + final messageActions = []; + + if (canQuoteMessage) { + messageActions.add( + StreamMessageAction( + action: QuotedReply(message: message), + title: Text(context.translations.replyLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.reply), + ), + ); + } + + if (canSendReply && !isThreadMessage) { + messageActions.add( + StreamMessageAction( + action: ThreadReply(message: message), + title: Text(context.translations.threadReplyLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.threadReply), + ), + ); + } + + if (canReceiveReadEvents) { + StreamMessageAction markUnreadAction() { + return StreamMessageAction( + action: MarkUnread(message: message), + title: Text(context.translations.markAsUnreadLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.messageUnread), + ); + } + + // If message is a parent message, it can be marked unread independent of + // other logic. + if (isParentMessage) { + messageActions.add(markUnreadAction()); + } + // If the message is in the channel view, only other user messages can be + // marked unread. + else if (!isSentByCurrentUser && (!isThreadMessage || canShowInChannel)) { + messageActions.add(markUnreadAction()); + } + } + + if (message.text case final text? when text.isNotEmpty) { + messageActions.add( + StreamMessageAction( + action: CopyMessage(message: message), + title: Text(context.translations.copyMessageLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.copy), + ), + ); + } + + if (!containsPoll && !containsGiphy) { + if (canUpdateAnyMessage || (canUpdateOwnMessage && isSentByCurrentUser)) { + messageActions.add( + StreamMessageAction( + action: EditMessage(message: message), + title: Text(context.translations.editMessageLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.edit), + ), + ); + } + } + + // Pinning a private message is not allowed, simply because pinning a + // message is meant to bring attention to that message, that is not possible + // with a message that is only visible to a subset of users. + if (canPinMessage && !isPrivateMessage) { + final isPinned = message.pinned; + final label = context.translations.togglePinUnpinText; + + final action = switch (isPinned) { + true => UnpinMessage(message: message), + false => PinMessage(message: message) + }; + + messageActions.add( + StreamMessageAction( + action: action, + title: Text(label.call(pinned: isPinned)), + leading: const StreamSvgIcon(icon: StreamSvgIcons.pin), + ), + ); + } + + if (canDeleteAnyMessage || (canDeleteOwnMessage && isSentByCurrentUser)) { + final label = context.translations.toggleDeleteRetryDeleteMessageText; + + messageActions.add( + StreamMessageAction( + isDestructive: true, + action: DeleteMessage(message: message), + leading: const StreamSvgIcon(icon: StreamSvgIcons.delete), + title: Text(label.call(isDeleteFailed: false)), + ), + ); + } + + if (!isSentByCurrentUser) { + messageActions.add( + StreamMessageAction( + action: FlagMessage(message: message), + title: Text(context.translations.flagMessageLabel), + leading: const StreamSvgIcon(icon: StreamSvgIcons.flag), + ), + ); + } + + if (message.user case final messageUser? + when channel.config?.mutes == true && !isSentByCurrentUser) { + final mutedUsers = currentUser?.mutes.map((mute) => mute.target.id); + final isMuted = mutedUsers?.contains(messageUser.id) ?? false; + final label = context.translations.toggleMuteUnmuteUserText; + + final action = switch (isMuted) { + true => UnmuteUser(message: message, user: messageUser), + false => MuteUser(message: message, user: messageUser), + }; + + messageActions.add( + StreamMessageAction( + action: action, + title: Text(label.call(isMuted: isMuted)), + leading: const StreamSvgIcon(icon: StreamSvgIcons.mute), + ), + ); + } + + // Add all the remaining custom actions if provided. + if (customActions case final actions?) messageActions.addAll(actions); + + return messageActions; + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/copy_message_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/copy_message_button.dart deleted file mode 100644 index cdb7415f21..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/copy_message_button.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template copyMessageButton} -/// Allows a user to copy the text of a message. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class CopyMessageButton extends StatelessWidget { - /// {@macro copyMessageButton} - const CopyMessageButton({ - super.key, - required this.onTap, - }); - - /// The callback to perform when the button is tapped. - final VoidCallback onTap; - - @override - Widget build(BuildContext context) { - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - size: 24, - icon: StreamSvgIcons.copy, - color: streamChatThemeData.primaryIconTheme.color, - ), - const SizedBox(width: 16), - Text( - context.translations.copyMessageLabel, - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/delete_message_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/delete_message_button.dart deleted file mode 100644 index 45e0477a5d..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/delete_message_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template deleteMessageButton} -/// A button that allows a user to delete the selected message. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class DeleteMessageButton extends StatelessWidget { - /// {@macro deleteMessageButton} - const DeleteMessageButton({ - super.key, - required this.isDeleteFailed, - required this.onTap, - }); - - /// Indicates whether the deletion has failed or not. - final bool isDeleteFailed; - - /// The action (deleting the message) to be performed on tap. - final VoidCallback onTap; - - @override - Widget build(BuildContext context) { - final theme = StreamChatTheme.of(context); - return InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.delete, - color: theme.colorTheme.accentError, - ), - const SizedBox(width: 16), - Text( - context.translations.toggleDeleteRetryDeleteMessageText( - isDeleteFailed: isDeleteFailed, - ), - style: theme.textTheme.body.copyWith( - color: theme.colorTheme.accentError, - ), - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/edit_message_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/edit_message_button.dart deleted file mode 100644 index 33165ac8a4..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/edit_message_button.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template editMessageButton} -/// Allows a user to edit a message. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class EditMessageButton extends StatelessWidget { - /// {@macro editMessageButton} - const EditMessageButton({ - super.key, - required this.onTap, - }); - - /// The callback to perform when the button is tapped. - final VoidCallback? onTap; - - @override - Widget build(BuildContext context) { - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.edit, - color: streamChatThemeData.primaryIconTheme.color, - ), - const SizedBox(width: 16), - Text( - context.translations.editMessageLabel, - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/flag_message_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/flag_message_button.dart deleted file mode 100644 index 5c57547108..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/flag_message_button.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template flagMessageButton} -/// Allows a user to flag a message. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class FlagMessageButton extends StatelessWidget { - /// {@macro flagMessageButton} - const FlagMessageButton({ - super.key, - required this.onTap, - }); - - /// The callback to perform when the button is tapped. - final VoidCallback onTap; - - @override - Widget build(BuildContext context) { - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.flag, - color: streamChatThemeData.primaryIconTheme.color, - ), - const SizedBox(width: 16), - Text( - context.translations.flagMessageLabel, - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/mam_widgets.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/mam_widgets.dart deleted file mode 100644 index e756d682b2..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/mam_widgets.dart +++ /dev/null @@ -1,8 +0,0 @@ -export 'copy_message_button.dart'; -export 'delete_message_button.dart'; -export 'edit_message_button.dart'; -export 'flag_message_button.dart'; -export 'pin_message_button.dart'; -export 'reply_button.dart'; -export 'resend_message_button.dart'; -export 'thread_reply_button.dart'; diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/mark_unread_message_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/mark_unread_message_button.dart deleted file mode 100644 index 12c38d0210..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/mark_unread_message_button.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template markUnreadMessageButton} -/// Allows a user to mark message (and all messages onwards) as unread. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class MarkUnreadMessageButton extends StatelessWidget { - /// {@macro markUnreadMessageButton} - const MarkUnreadMessageButton({ - super.key, - required this.onTap, - }); - - /// The callback to perform when the button is tapped. - final VoidCallback onTap; - - @override - Widget build(BuildContext context) { - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.messageUnread, - color: streamChatThemeData.primaryIconTheme.color, - size: 24, - ), - const SizedBox(width: 16), - Text( - context.translations.markAsUnreadLabel, - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/message_action.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/message_action.dart deleted file mode 100644 index f3acaac964..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/message_action.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:stream_chat_flutter/src/utils/typedefs.dart'; - -/// {@template streamMessageAction} -/// Class describing a message action -/// {@endtemplate} -class StreamMessageAction { - /// {@macro streamMessageAction} - StreamMessageAction({ - this.leading, - this.title, - this.onTap, - }); - - /// leading widget - final Widget? leading; - - /// title widget - final Widget? title; - - /// {@macro onMessageTap} - final OnMessageTap? onTap; -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/message_actions_modal.dart deleted file mode 100644 index 069c1aea51..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/message_actions_modal.dart +++ /dev/null @@ -1,425 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart' hide ButtonStyle; -import 'package:stream_chat_flutter/src/message_actions_modal/mam_widgets.dart'; -import 'package:stream_chat_flutter/src/message_actions_modal/mark_unread_message_button.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_align.dart'; -import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template messageActionsModal} -/// Constructs a modal with actions for a message -/// {@endtemplate} -class MessageActionsModal extends StatefulWidget { - /// {@macro messageActionsModal} - const MessageActionsModal({ - super.key, - required this.message, - required this.messageWidget, - required this.messageTheme, - this.showReactionPicker = true, - this.showDeleteMessage = true, - this.showEditMessage = true, - this.onReplyTap, - this.onEditMessageTap, - this.onConfirmDeleteTap, - this.onThreadReplyTap, - this.showCopyMessage = true, - this.showReplyMessage = true, - this.showResendMessage = true, - this.showThreadReplyMessage = true, - this.showMarkUnreadMessage = true, - this.showFlagButton = true, - this.showPinButton = true, - this.editMessageInputBuilder, - this.reverse = false, - this.customActions = const [], - this.onCopyTap, - }); - - /// Widget that shows the message - final Widget messageWidget; - - /// Builder for edit message - final EditMessageInputBuilder? editMessageInputBuilder; - - /// The action to perform when "thread reply" is tapped - final OnMessageTap? onThreadReplyTap; - - /// The action to perform when "reply" is tapped - final OnMessageTap? onReplyTap; - - /// The action to perform when "Edit Message" is tapped. - final OnMessageTap? onEditMessageTap; - - /// The action to perform when delete confirmation button is tapped. - final Future Function(Message)? onConfirmDeleteTap; - - /// Message in focus for actions - final Message message; - - /// [StreamMessageThemeData] for message - final StreamMessageThemeData messageTheme; - - /// Flag for showing reaction picker. - final bool showReactionPicker; - - /// Callback when copy is tapped - final OnMessageTap? onCopyTap; - - /// Callback when delete is tapped - final bool showDeleteMessage; - - /// Flag for showing copy action - final bool showCopyMessage; - - /// Flag for showing edit action - final bool showEditMessage; - - /// Flag for showing resend action - final bool showResendMessage; - - /// Flag for showing mark unread action - final bool showMarkUnreadMessage; - - /// Flag for showing reply action - final bool showReplyMessage; - - /// Flag for showing thread reply action - final bool showThreadReplyMessage; - - /// Flag for showing flag action - final bool showFlagButton; - - /// Flag for showing pin action - final bool showPinButton; - - /// Flag for reversing message - final bool reverse; - - /// List of custom actions - final List customActions; - - @override - _MessageActionsModalState createState() => _MessageActionsModalState(); -} - -class _MessageActionsModalState extends State { - bool _showActions = true; - - @override - Widget build(BuildContext context) { - final mediaQueryData = MediaQuery.of(context); - final user = StreamChat.of(context).currentUser; - final orientation = mediaQueryData.orientation; - - final fontSize = widget.messageTheme.messageTextStyle?.fontSize; - final streamChatThemeData = StreamChatTheme.of(context); - - final channel = StreamChannel.of(context).channel; - - final canSendReaction = channel.canSendReaction; - - final child = Center( - child: SingleChildScrollView( - child: SafeArea( - child: Padding( - padding: const EdgeInsets.all(8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (widget.showReactionPicker && canSendReaction) - LayoutBuilder( - builder: (context, constraints) { - return Align( - alignment: Alignment( - calculateReactionsHorizontalAlignment( - user, - widget.message, - constraints, - fontSize, - orientation, - ), - 0, - ), - child: StreamReactionPicker( - message: widget.message, - ), - ); - }, - ), - const SizedBox(height: 10), - IgnorePointer( - child: widget.messageWidget, - ), - const SizedBox(height: 8), - Padding( - padding: EdgeInsets.only( - left: widget.reverse ? 0 : 40, - ), - child: SizedBox( - width: mediaQueryData.size.width * 0.75, - child: Material( - color: streamChatThemeData.colorTheme.appBg, - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (widget.showReplyMessage && - widget.message.state.isCompleted) - ReplyButton( - onTap: () { - Navigator.of(context).pop(); - if (widget.onReplyTap != null) { - widget.onReplyTap?.call(widget.message); - } - }, - ), - if (widget.showThreadReplyMessage && - (widget.message.state.isCompleted) && - widget.message.parentId == null) - ThreadReplyButton( - message: widget.message, - onThreadReplyTap: widget.onThreadReplyTap, - ), - if (widget.showMarkUnreadMessage) - MarkUnreadMessageButton(onTap: () async { - try { - await channel.markUnread(widget.message.id); - } catch (ex) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - context.translations.markUnreadError, - ), - ), - ); - } - - Navigator.of(context).pop(); - }), - if (widget.showResendMessage) - ResendMessageButton( - message: widget.message, - channel: channel, - ), - if (widget.showEditMessage) - EditMessageButton( - onTap: switch (widget.onEditMessageTap) { - final onTap? => () => onTap(widget.message), - _ => null, - }, - ), - if (widget.showCopyMessage) - CopyMessageButton( - onTap: () { - widget.onCopyTap?.call(widget.message); - }, - ), - if (widget.showFlagButton) - FlagMessageButton( - onTap: _showFlagDialog, - ), - if (widget.showPinButton) - PinMessageButton( - onTap: _togglePin, - pinned: widget.message.pinned, - ), - if (widget.showDeleteMessage) - DeleteMessageButton( - isDeleteFailed: - widget.message.state.isDeletingFailed, - onTap: _showDeleteBottomSheet, - ), - ...widget.customActions - .map((action) => _buildCustomAction( - context, - action, - )), - ].insertBetween( - Container( - height: 1, - color: streamChatThemeData.colorTheme.borders, - ), - ), - ), - ), - ), - ), - ], - ), - ), - ), - ), - ); - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => Navigator.of(context).maybePop(), - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: ColoredBox( - color: streamChatThemeData.colorTheme.overlay, - ), - ), - ), - if (_showActions) - TweenAnimationBuilder( - tween: Tween(begin: 0, end: 1), - duration: const Duration(milliseconds: 300), - curve: Curves.easeInOutBack, - builder: (context, val, child) => Transform.scale( - scale: val, - child: child, - ), - child: child, - ), - ], - ), - ); - } - - InkWell _buildCustomAction( - BuildContext context, - StreamMessageAction messageAction, - ) { - return InkWell( - onTap: () => messageAction.onTap?.call(widget.message), - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - messageAction.leading ?? const Empty(), - const SizedBox(width: 16), - messageAction.title ?? const Empty(), - ], - ), - ), - ); - } - - Future _showFlagDialog() async { - final client = StreamChat.of(context).client; - - final streamChatThemeData = StreamChatTheme.of(context); - final answer = await showConfirmationBottomSheet( - context, - title: context.translations.flagMessageLabel, - icon: StreamSvgIcon( - icon: StreamSvgIcons.flag, - color: streamChatThemeData.colorTheme.accentError, - size: 24, - ), - question: context.translations.flagMessageQuestion, - okText: context.translations.flagLabel, - cancelText: context.translations.cancelLabel, - ); - - final theme = streamChatThemeData; - if (answer == true) { - try { - await client.flagMessage(widget.message.id); - await showInfoBottomSheet( - context, - icon: StreamSvgIcon( - icon: StreamSvgIcons.flag, - color: theme.colorTheme.accentError, - size: 24, - ), - details: context.translations.flagMessageSuccessfulText, - title: context.translations.flagMessageSuccessfulLabel, - okText: context.translations.okLabel, - ); - } catch (err) { - if (err is StreamChatNetworkError && - err.errorCode == ChatErrorCode.inputError) { - await showInfoBottomSheet( - context, - icon: StreamSvgIcon( - icon: StreamSvgIcons.flag, - color: theme.colorTheme.accentError, - size: 24, - ), - details: context.translations.flagMessageSuccessfulText, - title: context.translations.flagMessageSuccessfulLabel, - okText: context.translations.okLabel, - ); - } else { - _showErrorAlertBottomSheet(); - } - } - } - } - - Future _togglePin() async { - final channel = StreamChannel.of(context).channel; - - Navigator.of(context).pop(); - try { - if (!widget.message.pinned) { - await channel.pinMessage(widget.message); - } else { - await channel.unpinMessage(widget.message); - } - } catch (e) { - _showErrorAlertBottomSheet(); - } - } - - /// Shows a "delete message" bottom sheet on mobile platforms. - Future _showDeleteBottomSheet() async { - setState(() => _showActions = false); - final answer = await showConfirmationBottomSheet( - context, - title: context.translations.deleteMessageLabel, - icon: StreamSvgIcon( - icon: StreamSvgIcons.flag, - color: StreamChatTheme.of(context).colorTheme.accentError, - size: 24, - ), - question: context.translations.deleteMessageQuestion, - okText: context.translations.deleteLabel, - cancelText: context.translations.cancelLabel, - ); - - if (answer == true) { - try { - Navigator.of(context).pop(); - final onConfirmDeleteTap = widget.onConfirmDeleteTap; - if (onConfirmDeleteTap != null) { - await onConfirmDeleteTap(widget.message); - } else { - await StreamChannel.of(context).channel.deleteMessage(widget.message); - } - } catch (err) { - _showErrorAlertBottomSheet(); - } - } else { - setState(() => _showActions = true); - } - } - - void _showErrorAlertBottomSheet() { - showInfoBottomSheet( - context, - icon: StreamSvgIcon( - icon: StreamSvgIcons.error, - color: StreamChatTheme.of(context).colorTheme.accentError, - size: 24, - ), - details: context.translations.operationCouldNotBeCompletedText, - title: context.translations.somethingWentWrongError, - okText: context.translations.okLabel, - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/moderated_message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/moderated_message_actions_modal.dart deleted file mode 100644 index 6d9669e5d1..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/moderated_message_actions_modal.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/icons/stream_svg_icon.dart'; -import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; -import 'package:stream_chat_flutter/src/utils/extensions.dart'; - -/// {@template moderatedMessageActionsModal} -/// A modal that is shown when a message is flagged by moderation policies. -/// -/// This modal allows users to: -/// - Send the message anyway, overriding the moderation warning -/// - Edit the message to comply with community guidelines -/// - Delete the message -/// -/// The modal provides clear guidance to users about the moderation issue -/// and options to address it. -/// {@endtemplate} -class ModeratedMessageActionsModal extends StatelessWidget { - /// {@macro moderatedMessageActionsModal} - const ModeratedMessageActionsModal({ - super.key, - this.onSendAnyway, - this.onEditMessage, - this.onDeleteMessage, - }); - - /// Callback function called when the user chooses to send the message - /// despite the moderation warning. - final VoidCallback? onSendAnyway; - - /// Callback function called when the user chooses to edit the message. - final VoidCallback? onEditMessage; - - /// Callback function called when the user chooses to delete the message. - final VoidCallback? onDeleteMessage; - - @override - Widget build(BuildContext context) { - final theme = StreamChatTheme.of(context); - final textTheme = theme.textTheme; - final colorTheme = theme.colorTheme; - - final actions = [ - TextButton( - onPressed: onSendAnyway, - style: TextButton.styleFrom( - textStyle: theme.textTheme.body, - foregroundColor: theme.colorTheme.accentPrimary, - disabledForegroundColor: theme.colorTheme.disabled, - ), - child: Text(context.translations.sendAnywayLabel), - ), - TextButton( - onPressed: onEditMessage, - style: TextButton.styleFrom( - textStyle: theme.textTheme.body, - foregroundColor: theme.colorTheme.accentPrimary, - disabledForegroundColor: theme.colorTheme.disabled, - ), - child: Text(context.translations.editMessageLabel), - ), - TextButton( - onPressed: onDeleteMessage, - style: TextButton.styleFrom( - textStyle: theme.textTheme.body, - foregroundColor: theme.colorTheme.accentPrimary, - disabledForegroundColor: theme.colorTheme.disabled, - ), - child: Text(context.translations.deleteMessageLabel), - ), - ]; - - return BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: AlertDialog( - clipBehavior: Clip.antiAlias, - backgroundColor: colorTheme.appBg, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - icon: const StreamSvgIcon(icon: StreamSvgIcons.flag), - iconColor: colorTheme.accentPrimary, - title: Text(context.translations.moderationReviewModalTitle), - titleTextStyle: textTheme.headline.copyWith( - color: colorTheme.textHighEmphasis, - ), - content: Text( - context.translations.moderationReviewModalDescription, - textAlign: TextAlign.center, - ), - contentTextStyle: textTheme.body.copyWith( - color: colorTheme.textLowEmphasis, - ), - actions: actions, - actionsAlignment: MainAxisAlignment.center, - actionsOverflowAlignment: OverflowBarAlignment.center, - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/pin_message_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/pin_message_button.dart deleted file mode 100644 index 07313065ae..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/pin_message_button.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template pinMessageButton} -/// Allows a user to pin or unpin a message. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class PinMessageButton extends StatelessWidget { - /// {@macro pinMessageButton} - const PinMessageButton({ - super.key, - required this.onTap, - required this.pinned, - }); - - /// The callback to perform when the button is tapped. - final VoidCallback onTap; - - /// Whether the selected message is currently pinned or not. - final bool pinned; - - @override - Widget build(BuildContext context) { - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.pin, - color: streamChatThemeData.primaryIconTheme.color, - size: 24, - ), - const SizedBox(width: 16), - Text( - context.translations.togglePinUnpinText( - pinned: pinned, - ), - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/reply_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/reply_button.dart deleted file mode 100644 index b4340d8f96..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/reply_button.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template replyButton} -/// Allows a user to reply to a message. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class ReplyButton extends StatelessWidget { - /// {@macro replyButton} - const ReplyButton({ - super.key, - required this.onTap, - }); - - /// The callback to perform when the button is tapped. - final VoidCallback onTap; - - @override - Widget build(BuildContext context) { - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.reply, - color: streamChatThemeData.primaryIconTheme.color, - ), - const SizedBox(width: 16), - Text( - context.translations.replyLabel, - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/resend_message_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/resend_message_button.dart deleted file mode 100644 index 8c94c621ad..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/resend_message_button.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template resendMessageButton} -/// Allows a user to resend a message that has failed to be sent. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class ResendMessageButton extends StatelessWidget { - /// {@macro resendMessageButton} - const ResendMessageButton({ - super.key, - required this.message, - required this.channel, - }); - - /// The message to resend. - final Message message; - - /// The [StreamChannel] above this widget. - final Channel channel; - - @override - Widget build(BuildContext context) { - final isUpdateFailed = message.state.isUpdatingFailed; - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: () { - Navigator.of(context).pop(); - channel.retryMessage(message); - }, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.circleUp, - color: streamChatThemeData.colorTheme.accentPrimary, - ), - const SizedBox(width: 16), - Text( - context.translations.toggleResendOrResendEditedMessage( - isUpdateFailed: isUpdateFailed, - ), - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal/thread_reply_button.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal/thread_reply_button.dart deleted file mode 100644 index f5ffb4a357..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal/thread_reply_button.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template threadReplyButton} -/// Allows a user to start a thread reply to a message. -/// -/// Used by [MessageActionsModal]. Should not be used by itself. -/// {@endtemplate} -class ThreadReplyButton extends StatelessWidget { - /// {@macro threadReplyButton} - const ThreadReplyButton({ - super.key, - required this.message, - this.onThreadReplyTap, - }); - - /// The message to start a thread reply to. - final Message message; - - /// The action to perform when "thread reply" is tapped - final OnMessageTap? onThreadReplyTap; - - @override - Widget build(BuildContext context) { - final streamChatThemeData = StreamChatTheme.of(context); - return InkWell( - onTap: () { - Navigator.of(context).pop(); - if (onThreadReplyTap != null) { - onThreadReplyTap?.call(message); - } - }, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16), - child: Row( - children: [ - StreamSvgIcon( - icon: StreamSvgIcons.threadReply, - color: streamChatThemeData.primaryIconTheme.color, - ), - const SizedBox(width: 16), - Text( - context.translations.threadReplyLabel, - style: streamChatThemeData.textTheme.body, - ), - ], - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index ff5a617bee..5ed61a4f61 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -1005,10 +1005,6 @@ class _StreamMessageListViewState extends State { final isMyMessage = message.user!.id == StreamChat.of(context).currentUser!.id; final isOnlyEmoji = message.text?.isOnlyEmoji ?? false; - final currentUser = StreamChat.of(context).currentUser; - final members = StreamChannel.of(context).channel.state?.members ?? []; - final currentUserMember = - members.firstWhereOrNull((e) => e.user!.id == currentUser!.id); final hasFileAttachment = message.attachments.any((it) => it.type == AttachmentType.file); @@ -1025,6 +1021,11 @@ class _StreamMessageListViewState extends State { final borderSide = isOnlyEmoji ? BorderSide.none : null; final defaultMessageWidget = StreamMessageWidget( + message: message, + reverse: isMyMessage, + showUsername: !isMyMessage, + showReactions: !message.isDeleted && !message.state.isDeletingFailed, + showReactionPicker: !message.isDeleted && !message.state.isDeletingFailed, showReplyMessage: false, showResendMessage: false, showThreadReplyMessage: false, @@ -1032,9 +1033,6 @@ class _StreamMessageListViewState extends State { showDeleteMessage: false, showEditMessage: false, showMarkUnreadMessage: false, - message: message, - reverse: isMyMessage, - showUsername: !isMyMessage, padding: const EdgeInsets.all(8), showSendingIndicator: false, attachmentPadding: EdgeInsets.all( @@ -1077,13 +1075,6 @@ class _StreamMessageListViewState extends State { : _streamTheme.otherMessageTheme, onMessageTap: widget.onMessageTap, onMessageLongPress: widget.onMessageLongPress, - showPinButton: currentUserMember != null && - streamChannel?.channel.canPinMessage == true && - // Pinning a restricted visibility message is not allowed, simply - // because pinning a message is meant to bring attention to that - // message, that is not possible with a message that is only visible - // to a subset of users. - !message.hasRestrictedVisibility, ); if (widget.parentMessageBuilder != null) { @@ -1286,15 +1277,11 @@ class _StreamMessageListViewState extends State { final borderSide = isOnlyEmoji ? BorderSide.none : null; - final currentUser = StreamChat.of(context).currentUser; - final members = StreamChannel.of(context).channel.state?.members ?? []; - final currentUserMember = - members.firstWhereOrNull((e) => e.user!.id == currentUser!.id); - Widget messageWidget = StreamMessageWidget( message: message, reverse: isMyMessage, - showReactions: !message.isDeleted, + showReactions: !message.isDeleted && !message.state.isDeletingFailed, + showReactionPicker: !message.isDeleted && !message.state.isDeletingFailed, padding: const EdgeInsets.symmetric(horizontal: 8), showInChannelIndicator: showInChannelIndicator, showThreadReplyIndicator: showThreadReplyIndicator, @@ -1396,13 +1383,6 @@ class _StreamMessageListViewState extends State { : _streamTheme.otherMessageTheme, onMessageTap: widget.onMessageTap, onMessageLongPress: widget.onMessageLongPress, - showPinButton: currentUserMember != null && - streamChannel?.channel.canPinMessage == true && - // Pinning a restricted visibility message is not allowed, simply - // because pinning a message is meant to bring attention to that - // message, that is not possible with a message that is only visible - // to a subset of users. - !message.hasRestrictedVisibility, ); if (widget.messageBuilder != null) { diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_action_confirmation_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_action_confirmation_modal.dart new file mode 100644 index 0000000000..ec79afc166 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_action_confirmation_modal.dart @@ -0,0 +1,112 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/misc/adaptive_dialog_action.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; + +/// {@template streamMessageActionConfirmationModal} +/// A confirmation modal dialog for message actions in Stream Chat. +/// +/// This widget creates a platform-adaptive confirmation dialog that can be used +/// when a user attempts to perform an action on a message that requires +/// confirmation (like delete, flag, etc). +/// +/// The dialog presents two options: cancel and confirm, with customizable text +/// for both actions. The confirm action can be styled as destructive for +/// actions like deletion. +/// +/// Example usage: +/// +/// ```dart +/// showDialog( +/// context: context, +/// builder: (context) => StreamMessageActionConfirmationModal( +/// title: Text('Delete Message'), +/// content: Text('Are you sure you want to delete this message?'), +/// confirmActionTitle: Text('Delete'), +/// isDestructiveAction: true, +/// ), +/// ).then((confirmed) { +/// if (confirmed == true) { +/// // Perform the action +/// } +/// }); +/// ``` +/// {@endtemplate} +class StreamMessageActionConfirmationModal extends StatelessWidget { + /// Creates a message action confirmation modal. + /// + /// The [cancelActionTitle] defaults to a Text widget with 'Cancel'. + /// The [confirmActionTitle] defaults to a Text widget with 'Confirm'. + /// Set [isDestructiveAction] to true for actions like deletion that should + /// be highlighted as destructive. + const StreamMessageActionConfirmationModal({ + super.key, + this.title, + this.content, + this.cancelActionTitle = const Text('Cancel'), + this.confirmActionTitle = const Text('Confirm'), + this.isDestructiveAction = false, + }); + + /// The title of the dialog. + /// + /// Typically a [Text] widget. + final Widget? title; + + /// The content of the dialog, displayed below the title. + /// + /// Typically a [Text] widget that provides more details about the action. + final Widget? content; + + /// The widget to display as the cancel action button. + /// + /// Defaults to a [Text] widget with 'Cancel'. + /// When pressed, this action dismisses the dialog and returns false. + final Widget cancelActionTitle; + + /// The widget to display as the confirm action button. + /// + /// Defaults to a [Text] widget with 'Confirm'. + /// When pressed, this action dismisses the dialog and returns true. + final Widget confirmActionTitle; + + /// Whether the confirm action is destructive (like deletion). + /// + /// When true, the confirm action will be styled accordingly + /// (e.g., in red on iOS/macOS). + final bool isDestructiveAction; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + final textTheme = theme.textTheme; + + final actions = [ + AdaptiveDialogAction( + onPressed: () => Navigator.of(context).maybePop(false), + child: cancelActionTitle, + ), + AdaptiveDialogAction( + onPressed: () => Navigator.of(context).maybePop(true), + isDefaultAction: true, + isDestructiveAction: isDestructiveAction, + child: confirmActionTitle, + ), + ]; + + return AlertDialog.adaptive( + clipBehavior: Clip.antiAlias, + backgroundColor: colorTheme.barsBg, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + title: title, + titleTextStyle: textTheme.headline.copyWith( + color: colorTheme.textHighEmphasis, + ), + content: content, + contentTextStyle: textTheme.body.copyWith( + color: colorTheme.textLowEmphasis, + ), + actions: actions, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart new file mode 100644 index 0000000000..5b45f9360f --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart @@ -0,0 +1,155 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_align.dart'; + +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// {@template streamMessageActionsModal} +/// A modal that displays a list of actions that can be performed on a message. +/// +/// This widget presents a customizable menu of actions for a message, such as +/// reply, edit, delete, etc., along with an optional reaction picker. +/// +/// Typically used when a user long-presses on a message to see available +/// actions. +/// {@endtemplate} +class StreamMessageActionsModal extends StatelessWidget { + /// {@macro streamMessageActionsModal} + const StreamMessageActionsModal({ + super.key, + required this.message, + required this.messageActions, + required this.messageWidget, + this.reverse = false, + this.showReactionPicker = false, + this.onActionTap, + }); + + /// The message object that actions will be performed on. + /// + /// This is the message the user selected to see available actions. + final Message message; + + /// List of custom actions that will be displayed in the modal. + /// + /// Each action is represented by a [StreamMessageAction] object which defines + /// the action's appearance and behavior. + final List messageActions; + + /// The widget representing the message being acted upon. + /// + /// This is typically displayed at the top of the modal as a reference for the + /// user. + final Widget messageWidget; + + /// Whether the message should be displayed in reverse direction. + /// + /// This affects how the modal and reactions are displayed and aligned. + /// Set to `true` for right-aligned messages (typically the current user's). + /// Set to `false` for left-aligned messages (typically other users'). + /// + /// Defaults to `false`. + final bool reverse; + + /// Controls whether to show the reaction picker at the top of the modal. + /// + /// When `true`, users can add reactions directly from the modal. + /// When `false`, the reaction picker is hidden. + /// + /// Defaults to `false`. + final bool showReactionPicker; + + /// Callback triggered when a message action is tapped. + /// + /// Provides the tapped [MessageAction] object to the callback. + final OnMessageActionTap? onActionTap; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + + final Widget? reactionPicker = switch (showReactionPicker) { + false => null, + true => LayoutBuilder( + builder: (context, constraints) { + final orientation = MediaQuery.of(context).orientation; + final messageTheme = theme.getMessageTheme(reverse: reverse); + final messageFontSize = messageTheme.messageTextStyle?.fontSize; + + final alignment = message.calculateReactionPickerAlignment( + constraints: constraints, + fontSize: messageFontSize, + orientation: orientation, + reverse: reverse, + ); + + final onReactionPicked = switch (onActionTap) { + null => null, + final onActionTap => (reaction) { + return onActionTap.call( + SelectReaction(message: message, reaction: reaction), + ); + }, + }; + + final config = StreamChatConfiguration.of(context); + final reactionIcons = config.reactionIcons; + + return Align( + alignment: alignment, + child: StreamReactionPicker( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: onReactionPicked, + ), + ); + }, + ), + }; + + final alignment = switch (reverse) { + true => AlignmentDirectional.centerEnd, + false => AlignmentDirectional.centerStart, + }; + + return StreamMessageModal( + alignment: alignment, + headerBuilder: (context) { + return Column( + spacing: 10, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: alignment.toColumnCrossAxisAlignment(), + children: [ + reactionPicker, + IgnorePointer(child: messageWidget), + ].nonNulls.toList(growable: false), + ); + }, + contentBuilder: (context) { + final actions = Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: { + ...messageActions.map( + (action) => StreamMessageActionItem( + action: action, + onTap: onActionTap, + ), + ), + }.insertBetween(Divider(height: 1, color: theme.colorTheme.borders)), + ); + + return FractionallySizedBox( + widthFactor: 0.78, + child: Material( + type: MaterialType.transparency, + clipBehavior: Clip.antiAlias, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: actions, + ), + ); + }, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart new file mode 100644 index 0000000000..377d162857 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart @@ -0,0 +1,165 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_chat_flutter/src/utils/extensions.dart'; + +/// Shows a modal dialog with customized transitions and backdrop effects. +/// +/// This function is a wrapper around [showGeneralDialog] that provides +/// a consistent look and feel for message-related modals in Stream Chat. +/// +/// Returns a [Future] that resolves to the value passed to [Navigator.pop] +/// when the dialog is closed. +Future showStreamMessageModal({ + required BuildContext context, + required WidgetBuilder builder, + bool useSafeArea = true, + bool barrierDismissible = true, + String? barrierLabel, + Color? barrierColor, + Duration transitionDuration = const Duration(milliseconds: 300), + RouteTransitionsBuilder? transitionBuilder, + bool useRootNavigator = true, + RouteSettings? routeSettings, + Offset? anchorPoint, +}) { + assert(debugCheckHasMaterialLocalizations(context), ''); + final localizations = MaterialLocalizations.of(context); + + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + final capturedThemes = InheritedTheme.capture( + from: context, + to: Navigator.of(context, rootNavigator: useRootNavigator).context, + ); + + return showGeneralDialog( + context: context, + useRootNavigator: useRootNavigator, + anchorPoint: anchorPoint, + routeSettings: routeSettings, + transitionDuration: transitionDuration, + barrierDismissible: barrierDismissible, + barrierColor: barrierColor ?? colorTheme.overlay, + barrierLabel: barrierLabel ?? localizations.modalBarrierDismissLabel, + transitionBuilder: (context, animation, secondaryAnimation, child) { + final sigma = 10 * animation.value; + final scaleAnimation = Tween(begin: 0, end: 1).animate( + CurvedAnimation(parent: animation, curve: Curves.easeInOutBack), + ); + + return BackdropFilter( + filter: ImageFilter.blur(sigmaX: sigma, sigmaY: sigma), + child: ScaleTransition(scale: scaleAnimation, child: child), + ); + }, + pageBuilder: (context, animation, secondaryAnimation) { + final pageChild = Builder(builder: builder); + + var dialog = capturedThemes.wrap(pageChild); + if (useSafeArea) dialog = SafeArea(child: dialog); + return dialog; + }, + ); +} + +/// {@template streamMessageModal} +/// A customizable modal widget for displaying message-related content. +/// +/// This widget provides a consistent container for message actions and other +/// message-related modal content. It handles layout, animation, and keyboard +/// adjustments automatically. +/// +/// The modal can contain a header (optional) and content section (required), +/// and will adjust its position when the keyboard appears. +/// {@endtemplate} +class StreamMessageModal extends StatelessWidget { + /// Creates a Stream message modal. + /// + /// The [contentBuilder] parameter is required to build the main content + /// of the modal. The [headerBuilder] is optional and can be used to add + /// a header above the main content. + const StreamMessageModal({ + super.key, + this.spacing = 8.0, + this.headerBuilder, + required this.contentBuilder, + this.insetAnimationDuration = const Duration(milliseconds: 100), + this.insetAnimationCurve = Curves.decelerate, + this.insetPadding = const EdgeInsets.all(8), + this.alignment = Alignment.center, + }); + + /// Vertical spacing between header and content sections. + final double spacing; + + /// Optional builder for the header section of the modal. + final WidgetBuilder? headerBuilder; + + /// Required builder for the main content of the modal. + final WidgetBuilder contentBuilder; + + /// The duration of the animation to show when the system keyboard intrudes + /// into the space that the modal is placed in. + /// + /// Defaults to 100 milliseconds. + final Duration insetAnimationDuration; + + /// The curve to use for the animation shown when the system keyboard intrudes + /// into the space that the modal is placed in. + /// + /// Defaults to [Curves.decelerate]. + final Curve insetAnimationCurve; + + /// The amount of padding added to [MediaQueryData.viewInsets] on the outside + /// of the modal. This defines the minimum space between the screen's edges + /// and the modal. + /// + /// Defaults to `EdgeInsets.zero`. + final EdgeInsets insetPadding; + + /// How to align the [StreamMessageModal]. + /// + /// Defaults to [Alignment.center]. + final AlignmentGeometry alignment; + + @override + Widget build(BuildContext context) { + final effectivePadding = MediaQuery.viewInsetsOf(context) + insetPadding; + + final child = Align( + alignment: alignment, + child: ConstrainedBox( + constraints: const BoxConstraints(minWidth: 280), + child: Material( + type: MaterialType.transparency, + child: Column( + spacing: spacing, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: alignment.toColumnCrossAxisAlignment(), + children: [ + if (headerBuilder case final builder?) builder(context), + contentBuilder(context), + ], + ), + ), + ), + ); + + return AnimatedPadding( + padding: effectivePadding, + duration: insetAnimationDuration, + curve: insetAnimationCurve, + child: MediaQuery.removeViewInsets( + removeLeft: true, + removeTop: true, + removeRight: true, + removeBottom: true, + context: context, + child: child, + ), + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart new file mode 100644 index 0000000000..ef230bc596 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart @@ -0,0 +1,143 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_align.dart'; +import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_card.dart'; +import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// {@template streamMessageReactionsModal} +/// A modal that displays message reactions and allows users to add reactions. +/// +/// This modal contains: +/// 1. A reaction picker (optional) that appears at the top +/// 2. The original message widget +/// 3. A display of all current reactions with user avatars +/// +/// The modal uses [StreamMessageModal] as its base layout and customizes +/// both the header and content sections to display reaction-specific +/// information. +/// {@endtemplate} +class StreamMessageReactionsModal extends StatelessWidget { + /// {@macro streamMessageReactionsModal} + const StreamMessageReactionsModal({ + super.key, + required this.message, + required this.messageWidget, + this.reverse = false, + this.showReactionPicker = true, + this.onReactionPicked, + this.onUserAvatarTap, + }); + + /// The message for which to display and manage reactions. + final Message message; + + /// The original message widget that will be displayed in the modal. + final Widget messageWidget; + + /// Whether the message should be displayed in reverse direction. + /// + /// This affects how the modal and reactions are displayed and aligned. + /// Set to `true` for right-aligned messages (typically the current user's). + /// Set to `false` for left-aligned messages (typically other users'). + /// + /// Defaults to `false`. + final bool reverse; + + /// Controls whether to show the reaction picker at the top of the modal. + /// + /// When `true`, users can add reactions directly from the modal. + /// When `false`, the reaction picker is hidden. + final bool showReactionPicker; + + /// Callback triggered when a user adds or toggles a reaction. + /// + /// Provides the selected [Reaction] object to the callback. + final OnMessageActionTap? onReactionPicked; + + /// Callback triggered when a user avatar is tapped in the reactions list. + /// + /// Provides the [User] object associated with the tapped avatar. + final void Function(User)? onUserAvatarTap; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final messageTheme = theme.getMessageTheme(reverse: reverse); + + final Widget? reactionPicker = switch (showReactionPicker) { + false => null, + true => LayoutBuilder( + builder: (context, constraints) { + final orientation = MediaQuery.of(context).orientation; + final messageFontSize = messageTheme.messageTextStyle?.fontSize; + + final alignment = message.calculateReactionPickerAlignment( + constraints: constraints, + fontSize: messageFontSize, + orientation: orientation, + reverse: reverse, + ); + + final onReactionPicked = switch (this.onReactionPicked) { + null => null, + final onPicked => (reaction) { + return onPicked.call( + SelectReaction(message: message, reaction: reaction), + ); + }, + }; + + final config = StreamChatConfiguration.of(context); + final reactionIcons = config.reactionIcons; + + return Align( + alignment: alignment, + child: StreamReactionPicker( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: onReactionPicked, + ), + ); + }, + ), + }; + + final alignment = switch (reverse) { + true => AlignmentDirectional.centerEnd, + false => AlignmentDirectional.centerStart, + }; + + return StreamMessageModal( + alignment: alignment, + headerBuilder: (context) { + return Column( + spacing: 10, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: alignment.toColumnCrossAxisAlignment(), + children: [ + reactionPicker, + IgnorePointer(child: messageWidget), + ].nonNulls.toList(growable: false), + ); + }, + contentBuilder: (context) { + final currentUser = StreamChat.of(context).currentUser; + if (currentUser == null) return const Empty(); + + final reactions = message.latestReactions; + final hasReactions = reactions != null && reactions.isNotEmpty; + if (!hasReactions) return const Empty(); + + return FractionallySizedBox( + widthFactor: 0.78, + child: ReactionsCard( + message: message, + currentUser: currentUser, + messageTheme: messageTheme, + onUserAvatarTap: onUserAvatarTap, + ), + ); + }, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_modal/moderated_message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/moderated_message_actions_modal.dart new file mode 100644 index 0000000000..da655979a7 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_modal/moderated_message_actions_modal.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/icons/stream_svg_icon.dart'; +import 'package:stream_chat_flutter/src/message_action/message_action.dart'; +import 'package:stream_chat_flutter/src/misc/adaptive_dialog_action.dart'; +import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_chat_flutter/src/utils/extensions.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// {@template moderatedMessageActionsModal} +/// A modal that is shown when a message is flagged by moderation policies. +/// +/// This modal allows users to: +/// - Send the message anyway, overriding the moderation warning +/// - Edit the message to comply with community guidelines +/// - Delete the message +/// +/// The modal provides clear guidance to users about the moderation issue +/// and options to address it. +/// {@endtemplate} +class ModeratedMessageActionsModal extends StatelessWidget { + /// {@macro moderatedMessageActionsModal} + const ModeratedMessageActionsModal({ + super.key, + required this.message, + required this.messageActions, + this.onActionTap, + }); + + /// The message object that actions will be performed on. + /// + /// This is the message the user selected to see available actions. + final Message message; + + /// List of custom actions that will be displayed in the modal. + /// + /// Each action is represented by a [StreamMessageAction] object which defines + /// the action's appearance and behavior. + final List messageActions; + + /// Callback triggered when a moderated message action is tapped. + /// + /// Provides the tapped [MessageAction] object to the callback. + final OnMessageActionTap? onActionTap; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final textTheme = theme.textTheme; + final colorTheme = theme.colorTheme; + + final actions = [ + ...messageActions.map( + (action) => AdaptiveDialogAction( + onPressed: switch (onActionTap) { + final onTap? => () => onTap.call(action.action), + _ => null, + }, + isDestructiveAction: action.isDestructive, + child: action.title ?? const Empty(), + ), + ), + ]; + + return AlertDialog.adaptive( + clipBehavior: Clip.antiAlias, + backgroundColor: colorTheme.barsBg, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + icon: const StreamSvgIcon(icon: StreamSvgIcons.flag), + iconColor: colorTheme.accentPrimary, + title: Text(context.translations.moderationReviewModalTitle), + titleTextStyle: textTheme.headline.copyWith( + color: colorTheme.textHighEmphasis, + ), + content: Text( + context.translations.moderationReviewModalDescription, + textAlign: TextAlign.center, + ), + contentTextStyle: textTheme.body.copyWith( + color: colorTheme.textLowEmphasis, + ), + actions: actions, + actionsAlignment: MainAxisAlignment.center, + actionsOverflowAlignment: OverflowBarAlignment.center, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_widget/ephemeral_message.dart b/packages/stream_chat_flutter/lib/src/message_widget/ephemeral_message.dart index 076cb4117d..4f27668bb3 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/ephemeral_message.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/ephemeral_message.dart @@ -39,10 +39,9 @@ class StreamEphemeralMessage extends StatelessWidget { child: GiphyEphemeralMessage( message: message, onActionPressed: (name, value) { - streamChannel.channel.sendAction( - message, - {name: value}, - ); + return streamChannel.channel.sendAction(message, { + name: value, + }).ignore(); }, ), ), diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index b8ac368678..87cba1c2e0 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -1,14 +1,11 @@ +import 'dart:async'; + import 'package:contextmenu/contextmenu.dart'; import 'package:flutter/material.dart' hide ButtonStyle; import 'package:flutter/services.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:stream_chat_flutter/conditional_parent_builder/conditional_parent_builder.dart'; import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/context_menu_reaction_picker.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/stream_chat_context_menu_item.dart'; -import 'package:stream_chat_flutter/src/dialogs/dialogs.dart'; -import 'package:stream_chat_flutter/src/message_actions_modal/message_actions_modal.dart'; -import 'package:stream_chat_flutter/src/message_actions_modal/moderated_message_actions_modal.dart'; import 'package:stream_chat_flutter/src/message_widget/message_widget_content.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -97,6 +94,7 @@ class StreamMessageWidget extends StatefulWidget { this.widthFactor = 0.78, this.onQuotedMessageTap, this.customActions = const [], + this.onCustomActionTap, this.onAttachmentTap, this.imageAttachmentThumbnailSize = const Size(400, 400), this.imageAttachmentThumbnailResizeType = 'clip', @@ -256,7 +254,7 @@ class StreamMessageWidget extends StatefulWidget { /// {@template showReactionPicker} /// Whether or not to show the reaction picker. - /// Used in [StreamMessageReactionsModal] and [MessageActionsModal]. + /// Used in [StreamMessageReactionsModal] and [StreamMessageActionsModal]. /// {@endtemplate} final bool showReactionPicker; @@ -375,6 +373,11 @@ class StreamMessageWidget extends StatefulWidget { /// {@endtemplate} final List customActions; + /// Callback for when a custom message action is tapped. + /// + /// {@macro onMessageActionTap} + final OnMessageActionTap? onCustomActionTap; + /// {@macro onMessageWidgetAttachmentTap} final StreamAttachmentWidgetTapCallback? onAttachmentTap; @@ -456,6 +459,7 @@ class StreamMessageWidget extends StatefulWidget { OnReactionsTap? onReactionsTap, OnReactionsHover? onReactionsHover, List? customActions, + OnMessageActionTap? onCustomActionTap, void Function(Message message, Attachment attachment)? onAttachmentTap, Widget Function(BuildContext, User)? userAvatarBuilder, Size? imageAttachmentThumbnailSize, @@ -524,6 +528,7 @@ class StreamMessageWidget extends StatefulWidget { onReactionsTap: onReactionsTap ?? this.onReactionsTap, onReactionsHover: onReactionsHover ?? this.onReactionsHover, customActions: customActions ?? this.customActions, + onCustomActionTap: onCustomActionTap ?? this.onCustomActionTap, onAttachmentTap: onAttachmentTap ?? this.onAttachmentTap, userAvatarBuilder: userAvatarBuilder ?? this.userAvatarBuilder, imageAttachmentThumbnailSize: @@ -640,54 +645,20 @@ class _StreamMessageWidgetState extends State (widget.message.latestReactions?.isNotEmpty == true) && !widget.message.isDeleted; - bool get shouldShowReplyAction => - widget.showReplyMessage && !isFailedState && widget.onReplyTap != null; - - bool get shouldShowEditAction => - widget.showEditMessage && - !isDeleteFailed && - !hasPoll && - !widget.message.attachments - .any((element) => element.type == AttachmentType.giphy); - - bool get shouldShowResendAction => - widget.showResendMessage && (isSendFailed || isUpdateFailed); - - bool get shouldShowCopyAction => - widget.showCopyMessage && - !isFailedState && - widget.message.text?.trim().isNotEmpty == true; - - bool get shouldShowThreadReplyAction => - widget.showThreadReplyMessage && - !isFailedState && - widget.onThreadTap != null; - - bool get shouldShowDeleteAction => widget.showDeleteMessage || isDeleteFailed; - @override bool get wantKeepAlive => widget.message.attachments.isNotEmpty; - late StreamChatThemeData _streamChatTheme; - late StreamChatState _streamChat; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _streamChatTheme = StreamChatTheme.of(context); - _streamChat = StreamChat.of(context); - } - @override Widget build(BuildContext context) { super.build(context); + final theme = StreamChatTheme.of(context); + final streamChat = StreamChat.of(context); + final avatarWidth = widget.messageTheme.avatarTheme?.constraints.maxWidth ?? 40; final bottomRowPadding = widget.showUserAvatar != DisplayWidget.gone ? avatarWidth + 8.5 : 0.5; - final showReactions = shouldShowReactions; - return ConditionalParentBuilder( builder: (context, child) { final message = widget.message; @@ -703,107 +674,102 @@ class _StreamMessageWidgetState extends State ); }, child: Material( - type: MaterialType.transparency, - child: AnimatedContainer( - duration: const Duration(seconds: 1), - color: isPinned && widget.showPinHighlight - ? _streamChatTheme.colorTheme.highlight - // ignore: deprecated_member_use - : _streamChatTheme.colorTheme.barsBg.withOpacity(0), - child: Portal( - child: PlatformWidgetBuilder( - mobile: (context, child) { - final message = widget.message; - return InkWell( - onTap: switch (widget.onMessageTap) { - final onTap? => () => onTap(message), - _ => null, - }, - onLongPress: switch (widget.onMessageLongPress) { - final onLongPress? => () => onLongPress(message), - // If the message is not yet sent or deleted, we don't want - // to handle long press events by default. - _ when message.state.isDeleted => null, - _ when message.state.isOutgoing => null, - _ => () => _onMessageLongPressed(context, message), - }, - child: child, - ); - }, - desktop: (_, child) => MouseRegion(child: child), - web: (_, child) => MouseRegion(child: child), - child: Padding( - padding: widget.padding ?? const EdgeInsets.all(8), - child: FractionallySizedBox( - alignment: widget.reverse - ? Alignment.centerRight - : Alignment.centerLeft, - widthFactor: widget.widthFactor, - child: Builder(builder: (context) { - return MessageWidgetContent( - streamChatTheme: _streamChatTheme, - showUsername: showUsername, - showTimeStamp: showTimeStamp, - showEditedLabel: showEditedLabel, - showThreadReplyIndicator: showThreadReplyIndicator, - showSendingIndicator: showSendingIndicator, - showInChannel: showInChannel, - isGiphy: isGiphy, - isOnlyEmoji: isOnlyEmoji, - hasUrlAttachments: hasUrlAttachments, - messageTheme: widget.messageTheme, - reverse: widget.reverse, - message: widget.message, - hasNonUrlAttachments: hasNonUrlAttachments, - hasPoll: hasPoll, - hasQuotedMessage: hasQuotedMessage, - textPadding: widget.textPadding, - attachmentBuilders: widget.attachmentBuilders, - attachmentPadding: widget.attachmentPadding, - attachmentShape: widget.attachmentShape, - onAttachmentTap: widget.onAttachmentTap, - onReplyTap: widget.onReplyTap, - onThreadTap: widget.onThreadTap, - onShowMessage: widget.onShowMessage, - attachmentActionsModalBuilder: - widget.attachmentActionsModalBuilder, - avatarWidth: avatarWidth, - bottomRowPadding: bottomRowPadding, - isFailedState: isFailedState, - isPinned: isPinned, - messageWidget: widget, - showBottomRow: showBottomRow, - showPinHighlight: widget.showPinHighlight, - showReactionPickerTail: calculateReactionTailEnabled( - ReactionTailType.list, - ), - showReactions: showReactions, - onReactionsTap: () { - final message = widget.message; - return switch (widget.onReactionsTap) { - final onReactionsTap? => onReactionsTap(message), - _ => _showMessageReactionsModal(context, message), - }; - }, - onReactionsHover: widget.onReactionsHover, - showUserAvatar: widget.showUserAvatar, - streamChat: _streamChat, - translateUserAvatar: widget.translateUserAvatar, - shape: widget.shape, - borderSide: widget.borderSide, - borderRadiusGeometry: widget.borderRadiusGeometry, - textBuilder: widget.textBuilder, - quotedMessageBuilder: widget.quotedMessageBuilder, - onLinkTap: widget.onLinkTap, - onMentionTap: widget.onMentionTap, - onQuotedMessageTap: widget.onQuotedMessageTap, - bottomRowBuilderWithDefaultWidget: - widget.bottomRowBuilderWithDefaultWidget, - onUserAvatarTap: widget.onUserAvatarTap, - userAvatarBuilder: widget.userAvatarBuilder, - ); - }), - ), + color: switch (isPinned && widget.showPinHighlight) { + true => theme.colorTheme.highlight, + false => Colors.transparent, + }, + child: Portal( + child: PlatformWidgetBuilder( + mobile: (context, child) { + final message = widget.message; + return InkWell( + onTap: switch (widget.onMessageTap) { + final onTap? => () => onTap(message), + _ => null, + }, + onLongPress: switch (widget.onMessageLongPress) { + final onLongPress? => () => onLongPress(message), + // If the message is not yet sent or deleted, we don't want + // to handle long press events by default. + _ when message.state.isDeleted => null, + _ when message.state.isOutgoing => null, + _ => () => _onMessageLongPressed(context, message), + }, + child: child, + ); + }, + desktop: (_, child) => MouseRegion(child: child), + web: (_, child) => MouseRegion(child: child), + child: Padding( + padding: widget.padding ?? const EdgeInsets.all(8), + child: FractionallySizedBox( + alignment: switch (widget.reverse) { + true => Alignment.centerRight, + false => Alignment.centerLeft, + }, + widthFactor: widget.widthFactor, + child: Builder(builder: (context) { + return MessageWidgetContent( + streamChatTheme: theme, + showUsername: showUsername, + showTimeStamp: showTimeStamp, + showEditedLabel: showEditedLabel, + showThreadReplyIndicator: showThreadReplyIndicator, + showSendingIndicator: showSendingIndicator, + showInChannel: showInChannel, + isGiphy: isGiphy, + isOnlyEmoji: isOnlyEmoji, + hasUrlAttachments: hasUrlAttachments, + messageTheme: widget.messageTheme, + reverse: widget.reverse, + message: widget.message, + hasNonUrlAttachments: hasNonUrlAttachments, + hasPoll: hasPoll, + hasQuotedMessage: hasQuotedMessage, + textPadding: widget.textPadding, + attachmentBuilders: widget.attachmentBuilders, + attachmentPadding: widget.attachmentPadding, + attachmentShape: widget.attachmentShape, + onAttachmentTap: widget.onAttachmentTap, + onReplyTap: widget.onReplyTap, + onThreadTap: widget.onThreadTap, + onShowMessage: widget.onShowMessage, + attachmentActionsModalBuilder: + widget.attachmentActionsModalBuilder, + avatarWidth: avatarWidth, + bottomRowPadding: bottomRowPadding, + isFailedState: isFailedState, + isPinned: isPinned, + messageWidget: widget, + showBottomRow: showBottomRow, + showPinHighlight: widget.showPinHighlight, + showReactionPickerTail: widget.showReactionTail == true, + showReactions: shouldShowReactions, + onReactionsTap: () { + final message = widget.message; + return switch (widget.onReactionsTap) { + final onReactionsTap? => onReactionsTap(message), + _ => _showMessageReactionsModal(context, message), + }; + }, + onReactionsHover: widget.onReactionsHover, + showUserAvatar: widget.showUserAvatar, + streamChat: streamChat, + translateUserAvatar: widget.translateUserAvatar, + shape: widget.shape, + borderSide: widget.borderSide, + borderRadiusGeometry: widget.borderRadiusGeometry, + textBuilder: widget.textBuilder, + quotedMessageBuilder: widget.quotedMessageBuilder, + onLinkTap: widget.onLinkTap, + onMentionTap: widget.onMentionTap, + onQuotedMessageTap: widget.onQuotedMessageTap, + bottomRowBuilderWithDefaultWidget: + widget.bottomRowBuilderWithDefaultWidget, + onUserAvatarTap: widget.onUserAvatarTap, + userAvatarBuilder: widget.userAvatarBuilder, + ); + }), ), ), ), @@ -812,6 +778,49 @@ class _StreamMessageWidgetState extends State ); } + List _buildBouncedErrorMessageActions({ + required BuildContext context, + required Message message, + }) { + final actions = StreamMessageActionsBuilder.buildBouncedErrorActions( + context: context, + message: message, + ); + + return actions; + } + + List _buildMessageActions({ + required BuildContext context, + required Message message, + required Channel channel, + OwnUser? currentUser, + List? customActions, + }) { + final actions = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + customActions: customActions, + )..retainWhere( + (it) => switch (it.action) { + QuotedReply() => widget.showReplyMessage, + ThreadReply() => widget.showThreadReplyMessage, + MarkUnread() => widget.showMarkUnreadMessage, + ResendMessage() => widget.showResendMessage, + EditMessage() => widget.showEditMessage, + CopyMessage() => widget.showCopyMessage, + FlagMessage() => widget.showFlagButton, + PinMessage() => widget.showPinButton, + DeleteMessage() => widget.showDeleteMessage, + _ => true, // Retain all the remaining actions. + }, + ); + + return actions; + } + List _buildDesktopOrWebActions( BuildContext context, Message message, @@ -827,48 +836,23 @@ class _StreamMessageWidgetState extends State BuildContext context, Message message, ) { - final theme = StreamChatTheme.of(context); final channel = StreamChannel.of(context).channel; + final actions = _buildBouncedErrorMessageActions( + context: context, + message: message, + ); + return [ - StreamChatContextMenuItem( - leading: StreamSvgIcon( - icon: StreamSvgIcons.circleUp, - color: theme.colorTheme.accentPrimary, - ), - title: Text(context.translations.sendAnywayLabel), - onClick: () { - Navigator.of(context, rootNavigator: true).pop(); - channel.sendMessage(message).ignore(); - }, - ), - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.edit), - title: Text(context.translations.editMessageLabel), - onClick: () { - Navigator.of(context, rootNavigator: true).pop(); - showEditMessageSheet( - context: context, - channel: channel, - message: message, - editMessageInputBuilder: widget.editMessageInputBuilder, - ); - }, - ), - StreamChatContextMenuItem( - leading: StreamSvgIcon( - icon: StreamSvgIcons.delete, - color: theme.colorTheme.accentError, - ), - title: Text( - context.translations.deleteMessageLabel, - style: TextStyle(color: theme.colorTheme.accentError), - ), - onClick: () { - Navigator.of(context, rootNavigator: true).pop(); - channel.deleteMessage(message, hard: true).ignore(); - }, - ), + ...actions.map((action) { + return StreamMessageActionItem( + action: action, + onTap: (action) async { + final popped = await Navigator.of(context).maybePop(); + if (popped) return _onActionTap(context, channel, action).ignore(); + }, + ); + }), ]; } @@ -876,203 +860,86 @@ class _StreamMessageWidgetState extends State BuildContext context, Message message, ) { - final theme = StreamChatTheme.of(context); final channel = StreamChannel.of(context).channel; + final currentUser = channel.client.state.currentUser; + final showPicker = widget.showReactionPicker && channel.canSendReaction; + + final actions = _buildMessageActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + customActions: widget.customActions, + ); + + void onActionTap(MessageAction action) async { + final popped = await Navigator.of(context).maybePop(); + if (popped) return _onActionTap(context, channel, action).ignore(); + } return [ - if (widget.showReactionPicker) - StreamChatContextMenuItem( - child: StreamChannel( - channel: channel, - child: ContextMenuReactionPicker(message: message), - ), - ), - if (shouldShowReplyAction) ...[ - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.reply), - title: Text(context.translations.replyLabel), - onClick: () { - Navigator.of(context, rootNavigator: true).pop(); - widget.onReplyTap?.call(message); - }, - ), - ], - if (widget.showMarkUnreadMessage) - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.messageUnread), - title: Text(context.translations.markAsUnreadLabel), - onClick: () async { - Navigator.of(context, rootNavigator: true).pop(); - try { - await channel.markUnread(message.id); - } catch (ex) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - context.translations.markUnreadError, - ), - ), - ); - } - }, - ), - if (shouldShowThreadReplyAction) - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.threadReply), - title: Text(context.translations.threadReplyLabel), - onClick: () { - Navigator.of(context, rootNavigator: true).pop(); - widget.onThreadTap?.call(message); - }, - ), - if (shouldShowCopyAction) - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.copy), - title: Text(context.translations.copyMessageLabel), - onClick: () { - Navigator.of(context, rootNavigator: true).pop(); - final copiedMessage = message.replaceMentions(linkify: false); - if (copiedMessage.text case final text?) { - Clipboard.setData(ClipboardData(text: text)); - } - }, - ), - if (shouldShowEditAction) ...[ - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.edit), - title: Text(context.translations.editMessageLabel), - onClick: () { - Navigator.of(context, rootNavigator: true).pop(); - showEditMessageSheet( - context: context, - channel: channel, - message: message, - editMessageInputBuilder: widget.editMessageInputBuilder, - ); - }, - ), - ], - if (widget.showPinButton) - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.pin), - title: Text( - context.translations.togglePinUnpinText(pinned: isPinned), - ), - onClick: () async { - Navigator.of(context, rootNavigator: true).pop(); - try { - await switch (isPinned) { - true => channel.unpinMessage(message), - false => channel.pinMessage(message), - }; - } catch (e) { - throw Exception(e); - } - }, - ), - if (shouldShowResendAction) - StreamChatContextMenuItem( - leading: const StreamSvgIcon(icon: StreamSvgIcons.sendMessage), - title: Text( - context.translations.toggleResendOrResendEditedMessage( - isUpdateFailed: message.state.isUpdatingFailed, - ), - ), - onClick: () async { - Navigator.of(context, rootNavigator: true).pop(); - await channel.retryMessage(message); - }, - ), - if (shouldShowDeleteAction) - StreamChatContextMenuItem( - leading: StreamSvgIcon( - color: theme.colorTheme.accentError, - icon: StreamSvgIcons.delete, - ), - title: Text( - context.translations.deleteMessageLabel, - style: TextStyle(color: theme.colorTheme.accentError), + if (showPicker) + StreamReactionPicker( + message: message, + scrollable: false, + borderRadius: BorderRadius.zero, + reactionIcons: StreamChatConfiguration.of(context).reactionIcons, + onReactionPicked: (reaction) => onActionTap( + SelectReaction(message: message, reaction: reaction), ), - onClick: () async { - Navigator.of(context, rootNavigator: true).pop(); - final deleted = await showDialog( - context: context, - barrierDismissible: false, - builder: (_) => const DeleteMessageDialog(), - ); - if (deleted == true) { - try { - await switch (widget.onConfirmDeleteTap) { - final onConfirmDeleteTap? => onConfirmDeleteTap(message), - _ => channel.deleteMessage(message), - }; - } catch (e) { - showDialog( - context: context, - builder: (_) => const MessageDialog(), - ); - } - } - }, ), - ...widget.customActions.map( - (e) => StreamChatContextMenuItem( - leading: e.leading, - title: e.title, - onClick: () => e.onTap?.call(message), - ), - ), + ...actions.map((action) { + return StreamMessageActionItem( + action: action, + onTap: onActionTap, + ); + }), ]; } - void _showMessageReactionsModal( + Future _showMessageReactionsModal( BuildContext context, Message message, ) { final channel = StreamChannel.of(context).channel; + final showPicker = widget.showReactionPicker && channel.canSendReaction; - showDialog( - useRootNavigator: false, + return showStreamMessageModal( context: context, - useSafeArea: false, - barrierColor: _streamChatTheme.colorTheme.overlay, - builder: (context) => StreamChannel( - channel: channel, - child: StreamMessageReactionsModal( - message: message, - showReactionPicker: widget.showReactionPicker, - messageWidget: widget.copyWith( + useRootNavigator: false, + builder: (context) => StreamMessageReactionsModal( + message: message, + reverse: widget.reverse, + onUserAvatarTap: widget.onUserAvatarTap, + showReactionPicker: showPicker, + onReactionPicked: (action) async { + final popped = await Navigator.of(context).maybePop(); + if (popped) return _onActionTap(context, channel, action).ignore(); + }, + messageWidget: StreamChannel( + channel: channel, + child: widget.copyWith( key: const Key('MessageWidget'), - message: message.copyWith( - text: (message.text?.length ?? 0) > 200 - ? '${message.text!.substring(0, 200)}...' - : message.text, - ), + message: message.trimmed, showReactions: false, - showReactionTail: calculateReactionTailEnabled( - ReactionTailType.reactions, - ), showUsername: false, showTimestamp: false, translateUserAvatar: false, showSendingIndicator: false, padding: EdgeInsets.zero, - showReactionPicker: widget.showReactionPicker, showPinHighlight: false, - showUserAvatar: - message.user!.id == channel.client.state.currentUser!.id - ? DisplayWidget.gone - : DisplayWidget.show, + showReactionTail: showPicker, + showUserAvatar: switch (widget.reverse) { + true => DisplayWidget.gone, + false => DisplayWidget.show, + }, ), - onUserAvatarTap: widget.onUserAvatarTap, - messageTheme: widget.messageTheme, - reverse: widget.reverse, ), ), ); } - void _onMessageLongPressed( + Future _onMessageLongPressed( BuildContext context, Message message, ) { @@ -1083,10 +950,10 @@ class _StreamMessageWidgetState extends State return _onMessageActions(context, message); } - void _onBouncedErrorMessageActions( + Future _onBouncedErrorMessageActions( BuildContext context, Message message, - ) { + ) async { if (widget.onBouncedErrorMessageActions case final onActions?) { return onActions(context, message); } @@ -1094,42 +961,37 @@ class _StreamMessageWidgetState extends State return _showBouncedErrorMessageActionsDialog(context, message); } - void _showBouncedErrorMessageActionsDialog( + Future _showBouncedErrorMessageActionsDialog( BuildContext context, Message message, - ) { + ) async { final channel = StreamChannel.of(context).channel; - showDialog( + final actions = _buildBouncedErrorMessageActions( context: context, - builder: (context) { - return ModeratedMessageActionsModal( - onSendAnyway: () { - Navigator.of(context).pop(); - channel.sendMessage(widget.message).ignore(); - }, - onEditMessage: () { - Navigator.of(context).pop(); - showEditMessageSheet( - context: context, - channel: channel, - message: widget.message, - editMessageInputBuilder: widget.editMessageInputBuilder, - ); - }, - onDeleteMessage: () { - Navigator.of(context).pop(); - channel.deleteMessage(message, hard: true).ignore(); - }, - ); - }, + message: message, + ); + + void onActionTap(MessageAction action) async { + final popped = await Navigator.of(context).maybePop(); + if (popped) return _onActionTap(context, channel, action).ignore(); + } + + return showStreamMessageModal( + context: context, + useRootNavigator: false, + builder: (_) => ModeratedMessageActionsModal( + message: message, + messageActions: actions, + onActionTap: onActionTap, + ), ); } - void _onMessageActions( + Future _onMessageActions( BuildContext context, Message message, - ) { + ) async { if (widget.onMessageActions case final onActions?) { return onActions(context, message); } @@ -1137,107 +999,193 @@ class _StreamMessageWidgetState extends State return _showMessageActionModalDialog(context, message); } - void _showMessageActionModalDialog( + Future _showMessageActionModalDialog( BuildContext context, Message message, ) { final channel = StreamChannel.of(context).channel; + final currentUser = channel.client.state.currentUser; + final showPicker = widget.showReactionPicker && channel.canSendReaction; - showDialog( - useRootNavigator: false, + final actions = _buildMessageActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + customActions: widget.customActions, + ); + + void onActionTap(MessageAction action) async { + final popped = await Navigator.of(context).maybePop(); + if (popped) return _onActionTap(context, channel, action).ignore(); + } + + return showStreamMessageModal( context: context, - useSafeArea: false, - barrierColor: _streamChatTheme.colorTheme.overlay, - builder: (context) { - return StreamChannel( + useRootNavigator: false, + builder: (context) => StreamMessageActionsModal( + message: message, + reverse: widget.reverse, + messageActions: actions, + showReactionPicker: showPicker, + onActionTap: onActionTap, + messageWidget: StreamChannel( channel: channel, - child: MessageActionsModal( - message: message, - messageWidget: widget.copyWith( - key: const Key('MessageWidget'), - message: message.copyWith( - text: (message.text?.length ?? 0) > 200 - ? '${message.text!.substring(0, 200)}...' - : message.text, - ), - showReactions: false, - showReactionTail: calculateReactionTailEnabled( - ReactionTailType.messageActions, - ), - showUsername: false, - showTimestamp: false, - translateUserAvatar: false, - showSendingIndicator: false, - padding: EdgeInsets.zero, - showPinHighlight: false, - showUserAvatar: - message.user!.id == channel.client.state.currentUser!.id - ? DisplayWidget.gone - : DisplayWidget.show, - ), - onEditMessageTap: (message) { - Navigator.of(context).pop(); - showEditMessageSheet( - context: context, - channel: channel, - message: message, - editMessageInputBuilder: widget.editMessageInputBuilder, - ); - }, - onCopyTap: (message) { - Navigator.of(context).pop(); - final copiedMessage = message.replaceMentions(linkify: false); - if (copiedMessage.text case final text?) { - Clipboard.setData(ClipboardData(text: text)); - } + child: widget.copyWith( + key: const Key('MessageWidget'), + message: message.trimmed, + showReactions: false, + showUsername: false, + showTimestamp: false, + translateUserAvatar: false, + showSendingIndicator: false, + padding: EdgeInsets.zero, + showPinHighlight: false, + showReactionTail: showPicker, + showUserAvatar: switch (widget.reverse) { + true => DisplayWidget.gone, + false => DisplayWidget.show, }, - messageTheme: widget.messageTheme, - reverse: widget.reverse, - showDeleteMessage: shouldShowDeleteAction, - onConfirmDeleteTap: widget.onConfirmDeleteTap, - editMessageInputBuilder: widget.editMessageInputBuilder, - onReplyTap: widget.onReplyTap, - onThreadReplyTap: widget.onThreadTap, - showResendMessage: shouldShowResendAction, - showCopyMessage: shouldShowCopyAction, - showEditMessage: shouldShowEditAction, - showReactionPicker: widget.showReactionPicker, - showReplyMessage: shouldShowReplyAction, - showThreadReplyMessage: shouldShowThreadReplyAction, - showFlagButton: widget.showFlagButton, - showPinButton: widget.showPinButton, - showMarkUnreadMessage: widget.showMarkUnreadMessage, - customActions: widget.customActions, ), - ); - }, + ), + ), + ); + } + + Future _onActionTap( + BuildContext context, + Channel channel, + MessageAction action, + ) async { + return switch (action) { + SelectReaction() => + _selectReaction(context, action.message, channel, action.reaction), + CopyMessage() => _copyMessage(action.message, channel), + DeleteMessage() => _maybeDeleteMessage(context, action.message, channel), + HardDeleteMessage() => channel.deleteMessage(action.message, hard: true), + EditMessage() => _editMessage(context, action.message, channel), + FlagMessage() => _maybeFlagMessage(context, action.message, channel), + MarkUnread() => channel.markUnread(action.message.id), + MuteUser() => channel.client.muteUser(action.user.id), + UnmuteUser() => channel.client.unmuteUser(action.user.id), + PinMessage() => channel.pinMessage(action.message), + UnpinMessage() => channel.unpinMessage(action.message), + ResendMessage() => channel.retryMessage(action.message), + QuotedReply() => widget.onReplyTap?.call(action.message), + ThreadReply() => widget.onThreadTap?.call(action.message), + CustomMessageAction() => widget.onCustomActionTap?.call(action), + }; + } + + Future _copyMessage( + Message message, + Channel channel, + ) async { + final presentableMessage = message.replaceMentions(linkify: false); + + final messageText = presentableMessage.text; + if (messageText == null || messageText.isEmpty) return; + + return Clipboard.setData(ClipboardData(text: messageText)); + } + + Future _maybeDeleteMessage( + BuildContext context, + Message message, + Channel channel, + ) async { + final confirmDelete = await showStreamMessageModal( + context: context, + builder: (context) => StreamMessageActionConfirmationModal( + title: Text(context.translations.deleteMessageLabel), + content: Text(context.translations.deleteMessageQuestion), + cancelActionTitle: Text(context.translations.cancelLabel.sentenceCase), + confirmActionTitle: Text(context.translations.deleteLabel.sentenceCase), + isDestructiveAction: true, + ), ); + + if (confirmDelete == false) return null; + + return channel.deleteMessage(message); } - /// Calculates if the reaction picker tail should be enabled. - bool calculateReactionTailEnabled(ReactionTailType type) { - if (widget.showReactionTail != null) return widget.showReactionTail!; - - switch (type) { - case ReactionTailType.list: - return false; - case ReactionTailType.messageActions: - return widget.showReactionPicker; - case ReactionTailType.reactions: - return widget.showReactionPicker; + Future _editMessage( + BuildContext context, + Message message, + Channel channel, + ) { + return showEditMessageSheet( + context: context, + channel: channel, + message: message, + editMessageInputBuilder: widget.editMessageInputBuilder, + ); + } + + Future _maybeFlagMessage( + BuildContext context, + Message message, + Channel channel, + ) async { + final confirmFlag = await showStreamMessageModal( + context: context, + builder: (context) => StreamMessageActionConfirmationModal( + title: Text(context.translations.flagMessageLabel), + content: Text(context.translations.flagMessageQuestion), + cancelActionTitle: Text(context.translations.cancelLabel.sentenceCase), + confirmActionTitle: Text(context.translations.flagLabel.sentenceCase), + isDestructiveAction: true, + ), + ); + + if (confirmFlag == false) return null; + + final messageId = message.id; + return channel.client.flagMessage(messageId); + } + + Future _selectReaction( + BuildContext context, + Message message, + Channel channel, + Reaction reaction, + ) { + final ownReactions = [...?message.ownReactions]; + final shouldDelete = ownReactions.any((it) => it.type == reaction.type); + + if (shouldDelete) { + return channel.deleteReaction(message, reaction); + } + + final configurations = StreamChatConfiguration.of(context); + final enforceUnique = configurations.enforceUniqueReactions; + + return channel.sendReaction( + message, + reaction.type, + enforceUnique: enforceUnique, + ); + } +} + +extension on Message { + Message get trimmed { + if (text case final messageText? when messageText.length > 200) { + return copyWith(text: '${messageText.substring(0, 200)}...'); } + + return this; } } -/// Enum for declaring the location of the message for which the reaction picker -/// is to be enabled. -enum ReactionTailType { - /// Message is in the [StreamMessageListView] - list, +extension on String { + String get sentenceCase { + if (isEmpty) return this; - /// Message is in the [MessageActionsModal] - messageActions, + final firstChar = this[0].toUpperCase(); + final restOfString = substring(1).toLowerCase(); - /// Message is in the message reactions modal - reactions, + return '$firstChar$restOfString'; + } } diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart index a6ae651476..7e3ae0bbc1 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart @@ -363,9 +363,9 @@ class MessageWidgetContent extends StatelessWidget { ), // TODO: Make tail part of the Reaction Picker. if (showReactionPickerTail) - Positioned( - right: reverse ? null : 4, - left: reverse ? 4 : null, + PositionedDirectional( + end: reverse ? null : 4, + start: reverse ? 4 : null, top: -8, child: CustomPaint( painter: ReactionBubblePainter( diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart index ccbd8a0e8a..33f8bc79ac 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart @@ -3,7 +3,6 @@ export 'message_card.dart'; export 'parse_attachments.dart'; export 'pinned_message.dart'; export 'quoted_message.dart'; -export 'reactions/message_reactions_modal.dart'; export 'reactions/reaction_bubble.dart'; export 'reactions/reaction_indicator.dart'; export 'user_avatar_transform.dart'; diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/message_reactions_modal.dart b/packages/stream_chat_flutter/lib/src/message_widget/reactions/message_reactions_modal.dart deleted file mode 100644 index a3eed77874..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/message_reactions_modal.dart +++ /dev/null @@ -1,129 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_align.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_card.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template streamMessageReactionsModal} -/// Modal widget for displaying message reactions -/// {@endtemplate} -class StreamMessageReactionsModal extends StatelessWidget { - /// {@macro streamMessageReactionsModal} - const StreamMessageReactionsModal({ - super.key, - required this.message, - required this.messageWidget, - required this.messageTheme, - this.showReactionPicker = true, - this.reverse = false, - this.onUserAvatarTap, - }); - - /// Widget that shows the message - final Widget messageWidget; - - /// Message to display reactions of - final Message message; - - /// [StreamMessageThemeData] to apply to [message] - final StreamMessageThemeData messageTheme; - - /// {@macro reverse} - final bool reverse; - - /// Flag for showing reaction picker. - final bool showReactionPicker; - - /// {@macro onUserAvatarTap} - final void Function(User)? onUserAvatarTap; - - @override - Widget build(BuildContext context) { - final user = StreamChat.of(context).currentUser; - final channel = StreamChannel.of(context).channel; - final orientation = MediaQuery.of(context).orientation; - final canSendReaction = channel.canSendReaction; - final fontSize = messageTheme.messageTextStyle?.fontSize; - - final child = Center( - child: SingleChildScrollView( - child: SafeArea( - child: Padding( - padding: const EdgeInsets.all(8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (showReactionPicker && canSendReaction) - LayoutBuilder( - builder: (context, constraints) { - return Align( - alignment: Alignment( - calculateReactionsHorizontalAlignment( - user, - message, - constraints, - fontSize, - orientation, - ), - 0, - ), - child: StreamReactionPicker( - message: message, - ), - ); - }, - ), - const SizedBox(height: 10), - IgnorePointer( - child: messageWidget, - ), - if (message.latestReactions?.isNotEmpty == true) ...[ - const SizedBox(height: 8), - ReactionsCard( - currentUser: user!, - message: message, - messageTheme: messageTheme, - ), - ], - ], - ), - ), - ), - ), - ); - - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => Navigator.of(context).maybePop(), - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: DecoratedBox( - decoration: BoxDecoration( - color: StreamChatTheme.of(context).colorTheme.overlay, - ), - ), - ), - ), - TweenAnimationBuilder( - tween: Tween(begin: 0, end: 1), - duration: const Duration(milliseconds: 300), - curve: Curves.easeInOutBack, - builder: (context, val, widget) => Transform.scale( - scale: val, - child: widget, - ), - child: child, - ), - ], - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart index 5f61d1dfcc..440843b447 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart @@ -1,170 +1,112 @@ -import 'package:ezanimation/ezanimation.dart'; import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/message_widget/reactions/reaction_picker_icon_list.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamReactionPicker} /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/packages/stream_chat_flutter/screenshots/reaction_picker.png) /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/packages/stream_chat_flutter/screenshots/reaction_picker_paint.png) /// -/// Allows the user to select reactions to a message on mobile. +/// A widget that displays a horizontal list of reaction icons that users can +/// select to react to a message. /// -/// It is not recommended to use this widget directly as it's one of the -/// default widgets used by [StreamMessageWidget.onMessageActions]. +/// The reaction picker can be configured with custom reaction icons, padding, +/// border radius, and can be made scrollable or static depending on the +/// specific needs. /// {@endtemplate} -class StreamReactionPicker extends StatefulWidget { +class StreamReactionPicker extends StatelessWidget { /// {@macro streamReactionPicker} const StreamReactionPicker({ super.key, required this.message, + required this.reactionIcons, + this.onReactionPicked, + this.padding = const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + this.scrollable = true, + this.borderRadius = const BorderRadius.all(Radius.circular(24)), }); - /// Message to attach the reaction to - final Message message; + /// Creates a [StreamReactionPicker] using the default reaction icons + /// provided by the [StreamChatConfiguration]. + /// + /// This is the recommended way to create a reaction picker + /// as it ensures that the icons are consistent with the rest of the app. + /// + /// The [onReactionPicked] callback is optional and can be used to handle + /// the reaction selection. + factory StreamReactionPicker.builder( + BuildContext context, + Message message, + OnReactionPicked? onReactionPicked, + ) { + final config = StreamChatConfiguration.of(context); + final reactionIcons = config.reactionIcons; + + final platform = Theme.of(context).platform; + return switch (platform) { + TargetPlatform.iOS || TargetPlatform.android => StreamReactionPicker( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: onReactionPicked, + ), + _ => StreamReactionPicker( + message: message, + scrollable: false, + borderRadius: BorderRadius.zero, + reactionIcons: reactionIcons, + onReactionPicked: onReactionPicked, + ), + }; + } - @override - _StreamReactionPickerState createState() => _StreamReactionPickerState(); -} + /// Message to attach the reaction to. + final Message message; -class _StreamReactionPickerState extends State - with TickerProviderStateMixin { - List animations = []; + /// List of reaction icons to display. + final List reactionIcons; - @override - Widget build(BuildContext context) { - final chatThemeData = StreamChatTheme.of(context); - final reactionIcons = StreamChatConfiguration.of(context).reactionIcons; + /// {@macro onReactionPressed} + final OnReactionPicked? onReactionPicked; - if (animations.isEmpty && reactionIcons.isNotEmpty) { - reactionIcons.forEach((element) { - animations.add( - EzAnimation.tween( - Tween(begin: 0.0, end: 1.0), - const Duration(milliseconds: 500), - curve: Curves.easeInOutBack, - ), - ); - }); + /// Padding around the reaction picker. + /// + /// Defaults to `EdgeInsets.symmetric(horizontal: 8, vertical: 4)`. + final EdgeInsets padding; - triggerAnimations(); - } + /// Whether the reaction picker should be scrollable. + /// + /// Defaults to `true`. + final bool scrollable; - final child = Material( - borderRadius: BorderRadius.circular(24), - color: chatThemeData.colorTheme.barsBg, - clipBehavior: Clip.hardEdge, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, - ), - child: Row( - spacing: 16, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: reactionIcons.map((reactionIcon) { - final ownReactionIndex = widget.message.ownReactions?.indexWhere( - (reaction) => reaction.type == reactionIcon.type, - ) ?? - -1; - final index = reactionIcons.indexOf(reactionIcon); + /// Border radius for the reaction picker. + /// + /// Defaults to a circular border with a radius of 24. + final BorderRadius? borderRadius; - final child = reactionIcon.builder( - context, - ownReactionIndex != -1, - 24, - ); + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); - return ConstrainedBox( - constraints: const BoxConstraints.tightFor( - height: 24, - width: 24, - ), - child: RawMaterialButton( - elevation: 0, - shape: ContinuousRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - constraints: const BoxConstraints.tightFor( - height: 24, - width: 24, - ), - onPressed: () { - if (ownReactionIndex != -1) { - removeReaction( - context, - widget.message.ownReactions![ownReactionIndex], - ); - } else { - sendReaction( - context, - reactionIcon.type, - ); - } - }, - child: AnimatedBuilder( - animation: animations[index], - builder: (context, child) => Transform.scale( - scale: animations[index].value, - child: child, - ), - child: child, - ), - ), - ); - }).toList(), - ), - ), + final reactionPicker = ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: onReactionPicked, ); - return TweenAnimationBuilder( - tween: Tween(begin: 0, end: 1), - curve: Curves.easeInOutBack, - duration: const Duration(milliseconds: 500), - builder: (context, val, widget) => Transform.scale( - scale: val, - child: widget, + return DecoratedBox( + decoration: BoxDecoration( + color: theme.colorTheme.barsBg, + borderRadius: borderRadius, + ), + child: Padding( + padding: padding, + child: switch (scrollable) { + false => reactionPicker, + true => SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: reactionPicker, + ), + }, ), - child: child, ); } - - Future triggerAnimations() async { - for (final a in animations) { - a.start(); - await Future.delayed(const Duration(milliseconds: 100)); - } - } - - Future pop() async { - for (final a in animations) { - a.stop(); - } - Navigator.of(context).pop(); - } - - /// Add a reaction to the message - void sendReaction(BuildContext context, String reactionType) { - StreamChannel.of(context).channel.sendReaction( - widget.message, - reactionType, - enforceUnique: - StreamChatConfiguration.of(context).enforceUniqueReactions, - ); - pop(); - } - - /// Remove a reaction from the message - void removeReaction(BuildContext context, Reaction reaction) { - StreamChannel.of(context).channel.deleteReaction(widget.message, reaction); - pop(); - } - - @override - void dispose() { - for (final a in animations) { - a.dispose(); - } - super.dispose(); - } } diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart new file mode 100644 index 0000000000..98bbacaa59 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart @@ -0,0 +1,202 @@ +import 'package:collection/collection.dart'; +import 'package:ezanimation/ezanimation.dart'; +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/misc/reaction_icon.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// {@template onReactionPressed} +/// Callback called when a reaction icon is pressed. +/// {@endtemplate} +typedef OnReactionPicked = void Function(Reaction reaction); + +/// {@template reactionPickerIconList} +/// A widget that displays a list of reactionIcons that can be picked by a user. +/// +/// This widget shows a row of reaction icons with animated entry. When a user +/// taps on a reaction icon, the [onReactionPicked] callback is invoked with the +/// selected reaction. +/// +/// The reactions displayed are configured via [reactionIcons] and the widget +/// tracks which reactions the current user has already added to the [message]. +/// {@endtemplate} +class ReactionPickerIconList extends StatefulWidget { + /// {@macro reactionPickerIconList} + const ReactionPickerIconList({ + super.key, + required this.message, + required this.reactionIcons, + this.onReactionPicked, + }); + + /// The message to display reactions for. + final Message message; + + /// The list of available reaction icons. + final List reactionIcons; + + /// {@macro onReactionPressed} + final OnReactionPicked? onReactionPicked; + + @override + State createState() => _ReactionPickerIconListState(); +} + +class _ReactionPickerIconListState extends State { + List _iconAnimations = []; + + void _triggerAnimations() async { + for (final animation in _iconAnimations) { + if (mounted) animation.start(); + // Add a small delay between the start of each animation. + await Future.delayed(const Duration(milliseconds: 100)); + } + } + + void _dismissAnimations() { + for (final animation in _iconAnimations) { + animation.stop(); + } + } + + void _disposeAnimations() { + for (final animation in _iconAnimations) { + animation.dispose(); + } + } + + @override + void initState() { + super.initState(); + _iconAnimations = List.generate( + widget.reactionIcons.length, + (index) => EzAnimation.tween( + Tween(begin: 0.0, end: 1.0), + kThemeAnimationDuration, + curve: Curves.easeInOutBack, + ), + ); + + // Trigger animations at the end of the frame to avoid jank. + WidgetsBinding.instance.endOfFrame.then((_) => _triggerAnimations()); + } + + @override + void didUpdateWidget(covariant ReactionPickerIconList oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.reactionIcons.length != widget.reactionIcons.length) { + // Dismiss and dispose old animations. + _dismissAnimations(); + _disposeAnimations(); + + // Initialize new animations. + _iconAnimations = List.generate( + widget.reactionIcons.length, + (index) => EzAnimation.tween( + Tween(begin: 0.0, end: 1.0), + kThemeAnimationDuration, + curve: Curves.easeInOutBack, + ), + ); + + // Trigger animations at the end of the frame to avoid jank. + WidgetsBinding.instance.endOfFrame.then((_) => _triggerAnimations()); + } + } + + @override + void dispose() { + _dismissAnimations(); + _disposeAnimations(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final child = Wrap( + spacing: 4, + runSpacing: 4, + runAlignment: WrapAlignment.center, + alignment: WrapAlignment.spaceAround, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + ...widget.reactionIcons.mapIndexed((index, icon) { + bool reactionCheck(Reaction reaction) => reaction.type == icon.type; + + final ownReactions = [...?widget.message.ownReactions]; + final reaction = ownReactions.firstWhereOrNull(reactionCheck); + + final animation = _iconAnimations[index]; + return AnimatedBuilder( + animation: animation, + builder: (context, child) => Transform.scale( + scale: animation.value, + child: child, + ), + child: ReactionIconButton( + icon: icon, + // If the reaction is present, it is selected. + isSelected: reaction != null, + onPressed: switch (widget.onReactionPicked) { + final onPicked? => () { + final type = icon.type; + final pickedReaction = reaction ?? Reaction(type: type); + return onPicked(pickedReaction); + }, + _ => null, + }, + ), + ); + }), + ], + ); + + return TweenAnimationBuilder( + tween: Tween(begin: 0, end: 1), + curve: Curves.easeInOutBack, + duration: const Duration(milliseconds: 500), + builder: (context, scale, child) { + return Transform.scale(scale: scale, child: child); + }, + child: child, + ); + } +} + +/// {@template reactionIconButton} +/// A button that displays a reaction icon. +/// +/// This button is used in the reaction picker to display individual reaction +/// options. +/// {@endtemplate} +class ReactionIconButton extends StatelessWidget { + /// {@macro reactionIconButton} + const ReactionIconButton({ + super.key, + required this.icon, + required this.isSelected, + this.onPressed, + }); + + /// Whether this reaction is currently selected by the user. + final bool isSelected; + + /// The reaction icon to display. + final StreamReactionIcon icon; + + /// Callback triggered when the reaction icon is pressed. + final VoidCallback? onPressed; + + @override + Widget build(BuildContext context) { + return IconButton( + iconSize: 24, + icon: icon.builder(context, isSelected, 24), + padding: const EdgeInsets.all(4), + style: IconButton.styleFrom( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + minimumSize: const Size.square(24), + ), + onPressed: onPressed, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart index a7baad7eec..218ac3f866 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart @@ -1,51 +1,64 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -/// This method calculates the align that the modal of reactions should have. -/// This is an approximation based on the size of the message and the -/// available space in the screen. -double calculateReactionsHorizontalAlignment( - User? user, - Message message, - BoxConstraints constraints, - double? fontSize, - Orientation orientation, -) { - final maxWidth = constraints.maxWidth; +/// Extension on [Message] that provides alignment calculations for reaction +/// pickers. +/// +/// This extension adds functionality to determine the optimal positioning of +/// reaction pickers based on message size and available screen space. +extension ReactionPickerAlignment on Message { + /// Calculates the alignment for the reaction picker based on the message size + /// and the available space. + /// + /// The [fontSize] is used to calculate the size of the message, if not + /// provided, the font size of 1 is used. + /// + /// The [orientation] is used to calculate the size of the message, if not + /// provided, the orientation of the device is used. + AlignmentGeometry calculateReactionPickerAlignment({ + required BoxConstraints constraints, + double? fontSize, + Orientation orientation = Orientation.portrait, + bool reverse = false, + }) { + final maxWidth = constraints.maxWidth; - final roughSentenceSize = message.roughMessageSize(fontSize); - final hasAttachments = message.attachments.isNotEmpty; - final isReply = message.quotedMessageId != null; - final isAttachment = hasAttachments && !isReply; + final roughSentenceSize = roughMessageSize(fontSize); + final hasAttachments = attachments.isNotEmpty; + final isReply = quotedMessageId != null; + final isAttachment = hasAttachments && !isReply; - // divFactor is the percentage of the available space that the message takes. - // When the divFactor is bigger than 0.5 that means that the messages is - // bigger than 50% of the available space and the modal should have an offset - // in the direction that the message grows. When the divFactor is smaller - // than 0.5 then the offset should be to he side opposite of the message - // growth. - // In resume, when divFactor > 0.5 then result > 0, when divFactor < 0.5 - // then result < 0. - var divFactor = 0.5; + // divFactor is the percentage of the available space that the message + // takes. + // + // When the divFactor is bigger than 0.5 that means that the messages is + // bigger than 50% of the available space and the modal should have an + // offset in the direction that the message grows. When the divFactor is + // smaller than 0.5 then the offset should be to he side opposite of the + // message growth. + // + // In resume, when divFactor > 0.5 then result > 0, when divFactor < 0.5 + // then result < 0. + var divFactor = 0.5; - // When in portrait, attachments normally take 75% of the screen, when in - // landscape, attachments normally take 50% of the screen. - if (isAttachment) { - if (orientation == Orientation.portrait) { - divFactor = 0.75; + // When in portrait, attachments normally take 75% of the screen, when in + // landscape, attachments normally take 50% of the screen. + if (isAttachment) { + divFactor = switch (orientation) { + Orientation.portrait => 0.75, + Orientation.landscape => 0.5, + }; } else { - divFactor = 0.5; + divFactor = roughSentenceSize == 0 ? 0.5 : (roughSentenceSize / maxWidth); } - } else { - divFactor = roughSentenceSize == 0 ? 0.5 : (roughSentenceSize / maxWidth); - } - final signal = user?.id == message.user?.id ? 1 : -1; - final result = signal * (1 - divFactor * 2.0); + final signal = reverse ? 1 : -1; + final result = signal * (1 - divFactor * 2.0); - // Ensure reactions don't get pushed past the edge of the screen. - // - // This happens if divFactor is really big. When this happens, we can simply - // move the model all the way to the end of screen. - return result.clamp(-1, 1); + // Ensure reactions don't get pushed past the edge of the screen. + // + // This happens if divFactor is really big. When this happens, we can simply + // move the model all the way to the end of screen. + return AlignmentDirectional(result.clamp(-1, 1), 0); + } } diff --git a/packages/stream_chat_flutter/lib/src/misc/adaptive_dialog_action.dart b/packages/stream_chat_flutter/lib/src/misc/adaptive_dialog_action.dart new file mode 100644 index 0000000000..159c55b557 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/misc/adaptive_dialog_action.dart @@ -0,0 +1,71 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; + +/// A platform-adaptive dialog action button that renders appropriately based on +/// the platform. +/// +/// This widget uses [CupertinoDialogAction] on iOS and macOS platforms, +/// and [TextButton] on all other platforms, maintaining the appropriate +/// platform design language. +/// +/// The styling is influenced by the [StreamChatTheme] to ensure consistent +/// appearance with other Stream Chat components. +class AdaptiveDialogAction extends StatelessWidget { + /// Creates an adaptive dialog action. + const AdaptiveDialogAction({ + super.key, + this.onPressed, + this.isDefaultAction = false, + this.isDestructiveAction = false, + required this.child, + }); + + /// The callback that is called when the action is tapped. + final VoidCallback? onPressed; + + /// Whether this action is the default choice in the dialog. + /// + /// Default actions use emphasized styling (bold text) on iOS/macOS. + /// This has no effect on other platforms. + final bool isDefaultAction; + + /// Whether this action performs a destructive action like deletion. + /// + /// Destructive actions are displayed with red text on iOS/macOS. + /// This has no effect on other platforms. + final bool isDestructiveAction; + + /// The widget to display as the content of the action. + /// + /// Typically a [Text] widget. + final Widget child; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + + return switch (Theme.of(context).platform) { + TargetPlatform.iOS || TargetPlatform.macOS => CupertinoTheme( + data: CupertinoTheme.of(context).copyWith( + primaryColor: theme.colorTheme.accentPrimary, + ), + child: CupertinoDialogAction( + onPressed: onPressed, + isDefaultAction: isDefaultAction, + isDestructiveAction: isDestructiveAction, + child: child, + ), + ), + _ => TextButton( + onPressed: onPressed, + style: TextButton.styleFrom( + textStyle: theme.textTheme.body, + foregroundColor: theme.colorTheme.accentPrimary, + disabledForegroundColor: theme.colorTheme.disabled, + ), + child: child, + ), + }; + } +} diff --git a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart index 771f4ccb41..d3200ff478 100644 --- a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart @@ -673,6 +673,15 @@ class StreamChatThemeData { /// Theme configuration for the [StreamDraftListTile] widget. final StreamDraftListTileThemeData draftListTileTheme; + /// Returns the theme for the message based on the [reverse] parameter. + /// + /// If [reverse] is true, it returns the [otherMessageTheme], otherwise it + /// returns the [ownMessageTheme]. + StreamMessageThemeData getMessageTheme({bool reverse = false}) { + if (reverse) return otherMessageTheme; + return ownMessageTheme; + } + /// Creates a copy of [StreamChatThemeData] with specified attributes /// overridden. StreamChatThemeData copyWith({ diff --git a/packages/stream_chat_flutter/lib/src/utils/extensions.dart b/packages/stream_chat_flutter/lib/src/utils/extensions.dart index dd33838495..f98af3526c 100644 --- a/packages/stream_chat_flutter/lib/src/utils/extensions.dart +++ b/packages/stream_chat_flutter/lib/src/utils/extensions.dart @@ -694,3 +694,27 @@ extension AttachmentPlaylistExtension on Iterable { ]; } } + +/// Extension to convert [AlignmentGeometry] to the corresponding +/// [CrossAxisAlignment]. +extension ColumnAlignmentExtension on AlignmentGeometry { + /// Converts an [AlignmentGeometry] to the most appropriate + /// [CrossAxisAlignment] value. + CrossAxisAlignment toColumnCrossAxisAlignment() { + final x = switch (this) { + Alignment(x: final x) => x, + AlignmentDirectional(start: final start) => start, + _ => null, + }; + + // If the alignment is unknown, fallback to the center alignment. + if (x == null) return CrossAxisAlignment.center; + + return switch (x) { + 0.0 => CrossAxisAlignment.center, + < 0 => CrossAxisAlignment.start, + > 0 => CrossAxisAlignment.end, + _ => CrossAxisAlignment.center, // fallback (in case of NaN etc) + }; + } +} diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index db05edbbfd..a8887c459c 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -52,7 +52,9 @@ export 'src/indicators/upload_progress_indicator.dart'; export 'src/keyboard_shortcuts/keyboard_shortcut_runner.dart'; export 'src/localization/stream_chat_localizations.dart'; export 'src/localization/translations.dart' show DefaultTranslations; -export 'src/message_actions_modal/message_action.dart'; +export 'src/message_action/message_action.dart'; +export 'src/message_action/message_action_item.dart'; +export 'src/message_action/message_actions_builder.dart'; export 'src/message_input/attachment_picker/stream_attachment_picker.dart'; export 'src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart'; export 'src/message_input/audio_recorder/audio_recorder_controller.dart'; @@ -67,6 +69,11 @@ export 'src/message_input/stream_message_send_button.dart'; export 'src/message_input/stream_message_text_field.dart'; export 'src/message_list_view/message_details.dart'; export 'src/message_list_view/message_list_view.dart'; +export 'src/message_modal/message_action_confirmation_modal.dart'; +export 'src/message_modal/message_actions_modal.dart'; +export 'src/message_modal/message_modal.dart'; +export 'src/message_modal/message_reactions_modal.dart'; +export 'src/message_modal/moderated_message_actions_modal.dart'; export 'src/message_widget/deleted_message.dart'; export 'src/message_widget/message_text.dart'; export 'src/message_widget/message_widget.dart'; @@ -76,6 +83,7 @@ export 'src/message_widget/poll_message.dart'; export 'src/message_widget/reactions/reaction_picker.dart'; export 'src/message_widget/system_message.dart'; export 'src/message_widget/text_bubble.dart'; +export 'src/misc/adaptive_dialog_action.dart'; export 'src/misc/animated_circle_border_painter.dart'; export 'src/misc/back_button.dart'; export 'src/misc/connection_status_builder.dart'; diff --git a/packages/stream_chat_flutter/test/src/context_menu_items/download_menu_item_test.dart b/packages/stream_chat_flutter/test/src/context_menu_items/download_menu_item_test.dart deleted file mode 100644 index 23b3a4c533..0000000000 --- a/packages/stream_chat_flutter/test/src/context_menu_items/download_menu_item_test.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:alchemist/alchemist.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -import '../material_app_wrapper.dart'; -import '../mocks.dart'; - -void main() { - group('DownloadMenuItem tests', () { - testWidgets('renders ListTile widget', (tester) async { - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: MockClient(), - child: child, - ), - home: Scaffold( - body: Center( - child: DownloadMenuItem( - attachment: MockAttachment(), - ), - ), - ), - ), - ); - - expect(find.byType(ListTile), findsOneWidget); - }); - - goldenTest( - 'golden test for DownloadMenuItem', - fileName: 'download_menu_item_0', - constraints: const BoxConstraints.tightFor(width: 300, height: 100), - builder: () => MaterialAppWrapper( - builder: (context, child) => StreamChatTheme( - data: StreamChatThemeData.light(), - child: child!, - ), - home: Scaffold( - body: Center( - child: DownloadMenuItem( - attachment: MockAttachment(), - ), - ), - ), - ), - ); - }); -} diff --git a/packages/stream_chat_flutter/test/src/context_menu_items/goldens/ci/download_menu_item_0.png b/packages/stream_chat_flutter/test/src/context_menu_items/goldens/ci/download_menu_item_0.png deleted file mode 100644 index d4751f48c5d24e7c62d286e8d7faa86fd1af1636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 825 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuzq&IEGZrd3)E_?{llHapNKAT&>*j3K*`mqB^bn@-sV zmp2V8JU`Up16TjMxXka1%XQP^XIG-MV$Bu3ZbWw6lwQ zy2;zp-ah_2#|Fc5=gv*rRloG$uKoMtpBDW;a`foYUG5FN8*?_;2r(f!o2TeSU1eqD zy!rFJZ*NqT{*X`-Yj~maVZ8n;JzP{>i zjh+7Hn`>-rZKqy5k;eaHtD{z7MMcD{Wtz43r@t(T+O_WYyIJdApDMA^1qv+7JazEk zL4m~#(kT-XdXGQ8v@Lh#>s?=J!rEMjw0p5v=k;eceB+ zu+rH5?%C<-%XP%MH|^dX-PhOW6&mW?yJ5@Uzkf^n8KfTrow@QiyRF5lRj+J4;@@u& z>pp5epRwl11NFQ1RZmv0TD2utJM4gb+ zluxrg9QE?Hl+fIH^VU_fJg9Gevtix(^{4ONy(@or^Y-oHU+3v0d}Xsd{A)H_l@V** zaY-?O!~8#pPX-@>%K9(c)8O;ltv91BJdDGcUO*Jmjc-y?5T#koe6a z)zy3B9&;-^`2C8Jp-)Ih!FfXi&p{?57VZ-Q1UNmnB@S0dI5hDRq4f7n=4X|4=T+(} z?B@Tkvb&IY7-q%eFZOHvx9gm~s(j#hg^k?ued23mU+;>uWvc1fe6UEBg&3EB9K7e+ zhU8hxR=YFQabD}&d_Ixk{bMhV6b`WoiV+USa(fKd$uT|PkOp(x5*Q_$SfO$lobS1} j*Ue*mAV7>-6jSW2)1;+b^JCb7@xkEf>gTe~DWM4f<&~I5 diff --git a/packages/stream_chat_flutter/test/src/context_menu_items/stream_chat_context_menu_item_test.dart b/packages/stream_chat_flutter/test/src/context_menu_items/stream_chat_context_menu_item_test.dart deleted file mode 100644 index 798e649cfb..0000000000 --- a/packages/stream_chat_flutter/test/src/context_menu_items/stream_chat_context_menu_item_test.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:alchemist/alchemist.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/stream_chat_context_menu_item.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -import '../material_app_wrapper.dart'; -import '../mocks.dart'; - -void main() { - group('StreamChatContextMenuItem tests', () { - testWidgets('renders ListTile widget', (tester) async { - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: MockClient(), - child: child, - ), - home: const Scaffold( - body: Center( - child: StreamChatContextMenuItem(), - ), - ), - ), - ); - - expect(find.byType(ListTile), findsOneWidget); - }); - - goldenTest( - 'golden test for StreamChatContextMenuItem', - fileName: 'stream_chat_context_menu_item_0', - constraints: const BoxConstraints.tightFor(width: 300, height: 80), - builder: () => MaterialAppWrapper( - builder: (context, child) => StreamChatTheme( - data: StreamChatThemeData.light(), - child: child!, - ), - home: Scaffold( - body: Center( - child: StreamChatContextMenuItem( - leading: const Icon(Icons.download), - title: const Text('Download'), - onClick: () {}, - ), - ), - ), - ), - ); - }); -} diff --git a/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/delete_message_dialog_0.png b/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/delete_message_dialog_0.png index 9314acdc86a628540c34cc3e7294c991138c1e67..7d9d740d7789b6db478fa7bd711c08488ca04341 100644 GIT binary patch literal 4314 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 DP1oR~ delta 3409 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 Oye!UJnUVhT{P#coYZP|? diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_child_dark.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_child_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..23412da5e86f5cc3aea9ae8285802310c0435122 GIT binary patch literal 810 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Z8+F~^%@1E0^8GSDuk#@?Mu=rEB4mv@55orFSL*4Lf$g zKceA0ljrH{>$3j6k(8Zhxo)HI=GfTvKi{sl3te3mUAuPbRny!(6*o8UT_#xaYu5U_ z``0eKH@|BsbZF9F8P3y*3!Zv+@2Yt3s8;RyDB^m*-|IrUG7qXYp;0pPaxb$Eh;6*yQb>{qLL%e_Q*oaDOe*}K!(+ZdY14>3djJld>X%FAi6lNc4&`mOg!BO=Bb7sMMRG8!}|;Kq;5c@1Yv{9Dg!0!;4=p00i_>zopr E0QYBEl>h($ literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_child_light.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_child_light.png new file mode 100644 index 0000000000000000000000000000000000000000..e3ddc3bab7ab10078aae5d7152ec1d1e3a3cc2cd GIT binary patch literal 820 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Z8+F~_G*sRJcb6Qi5vJC81^bfFkDfITF~}i`kI}2QH{wPWd_^baeLJI#l#QUxnw}2`k*T zDs2rvzqH`H^GE@tMGwOcpk7ndnVG$h`crYyZQwJ>__`)RMH1BGj%D}_(!G_guN z`~1iGXY_5JlC-BUCp&Bd2^}epUAb4M)u?>)mN&m;fC5j>yM@|Z=S?kJyy@L<9-zRI zz@JH9a)1mKDf8d%$w0SG2>BONvHAF)`Mw(%nvWPCSDAOR#mIW9{tvt61je?LV#}H4 zOIpvEGI6!*{pSKY2Mm@k%l9;rexs|Bo}TAzH2ZTc-$5oG;f=YL_S+T0Or%ci3E8Kx zbES0S8KsDZ#=ai^6GykdSD7aFDYxx<-szLGFBd&L`uf156S=$%3;BBIP5AT1_UF!D zfl7w;>!zQ)zw`d~&)=F77}+)}30hj&UEKcs?Y=lQo;^ZL0m%={*W9|Eb;F(Eg0h(o zLsrDuWtTs;{}tlgyni-J!vBIf=ce;*N@NTGx*8{5{5rgNSM3CDhNeSptPZ?QxN-0Q Y_Wp@1!D%y?fhnKC)78&qol`;+0HNJpIsgCw literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_styling_dark.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_custom_styling_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f212165ce536752082435acbc0011395c5bde1a8 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Z8+F~yqA%Mv7wnpeK?ciHyyNcGo~ z`(9mMKe;sSn8a%ajta{vW`@ly+$RKd6r49S@El|^f^&KGx9|eXcgQu&X%Q~loCIH54Rf22(@FW_Y{k-WO1Irz`y^IZkO{^&#ViOc29NH2XCE=W7nI#YJUjMz#n(^P- zr~fiD=5lhM5YSO@-q65vkjaPznbT%3v-jHb)2WxA+wYlYUTariBMdih_uRz4rI#On zz8KxG=Ii6!>ECByF#yFhbWVZ%wf?>DJ~P&xZ-F`VSYCR>KWUDb({K?Kr-L|`ZS-GX koXsGScnHn0aN~ROPiu=j%(I;K4H&2lp00i_>zopr00e7|^Z)<= literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_dark.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ceb15cacddfa7bdfd7277e858bced6bf9383b46f GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Z8+F~^1ZGe?^}K9<_y6v-=}ZAezlBb>u%>W`O;C(* zXiH#}Y{JL+5q(%ct$r?_%?xDMCI4Eu+c`HuQy8ZqZ;nZ9zd4&B;t+1D%Jqu**;%dI RP69)c!PC{xWt~$(699S=hui=F literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_light.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_light.png new file mode 100644 index 0000000000000000000000000000000000000000..57f4026a0239b18d79ba54479ffff3159c4be535 GIT binary patch literal 391 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Z8+F~OLn`LHy<^yS$Uwxw(LsBncJA4o+n;$DidM5s@ZsP;`(O*S!`@B~bO3 z#od?xjoTLc|JU}nzYg4ro%IZ(v)qWH!piR5ObX(~z0$7YBnu`<>_I(uv@m&Cd2 z&y09BM`q6zcQ|nO3q!+wAsq$h4Gla8nT%MtPYA#{@0PPq$u0l=l9Od_U;9hWNIkd= ziZUSQ!^0N~u1|ly+V20`zmHd)Z{Ppy5VBeNcXz({{kpj7kZ)B*&8&GJ@^@mf4c$zr zJLOLn`LHz3Z5D*g(MH;wq6x*41x~qa$~!b4;1y^7F$z#v^O&nhic# zoUg29WT{y%$M9f13-<{D9R=qN4Lk>#jNqJ}`B#~z<{`YBzk&NM){?5kaScL5%_g#AR$D)t6v8Hf{O;C(*XiH#}Y{JK> zSligX$LqlIjfqGKk6E05nfBH5c3HG7lVkC{@cs#@D7GQ{fM>nwpJslBhkJ8y+V+wA YbBmN=y;al tappedMessage = action.message, + action: StreamMessageAction( + title: const Text('Reply'), + leading: const Icon(Icons.reply), + action: QuotedReply(message: message), + ), + ), + ), + ); + + await tester.tap(find.byType(InkWell)); + await tester.pump(); + + expect(tappedMessage, message); + }); + + testWidgets( + 'applies destructive styling when isDestructive is true', + (tester) async { + await tester.pumpWidget( + _wrapWithMaterialApp( + StreamMessageActionItem( + action: StreamMessageAction( + isDestructive: true, + title: const Text('Delete'), + leading: const Icon(Icons.delete), + action: DeleteMessage(message: message), + ), + ), + ), + ); + + expect(find.text('Delete'), findsOneWidget); + expect(find.byIcon(Icons.delete), findsOneWidget); + + // The icon and text should have the error color + final theme = StreamChatTheme.of(tester.element(find.text('Delete'))); + final iconTheme = IconTheme.of(tester.element(find.byIcon(Icons.delete))); + + expect(iconTheme.color, theme.colorTheme.accentError); + }, + ); + + group('StreamMessageActionItem Golden Tests', () { + for (final brightness in Brightness.values) { + final theme = brightness.name; + + // Test standard action + goldenTest( + 'StreamMessageActionItem (Reply) in $theme theme', + fileName: 'stream_message_action_item_reply_$theme', + constraints: const BoxConstraints(maxWidth: 300, maxHeight: 60), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + StreamMessageActionItem( + action: StreamMessageAction( + title: const Text('Reply'), + leading: const Icon(Icons.reply), + action: QuotedReply(message: message), + ), + ), + ), + ); + + // Test destructive action (like delete) + goldenTest( + 'StreamMessageActionItem (Delete) in $theme theme', + fileName: 'stream_message_action_item_delete_$theme', + constraints: const BoxConstraints(maxWidth: 300, maxHeight: 60), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + StreamMessageActionItem( + action: StreamMessageAction( + isDestructive: true, + title: const Text('Delete Message'), + leading: const Icon(Icons.delete), + action: DeleteMessage(message: message), + ), + ), + ), + ); + + // Test with custom styling + goldenTest( + 'StreamMessageActionItem with custom styling in $theme theme', + fileName: 'stream_message_action_item_custom_styling_$theme', + constraints: const BoxConstraints(maxWidth: 300, maxHeight: 60), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + StreamMessageActionItem( + action: StreamMessageAction( + title: const Text('Styled Action'), + titleTextStyle: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + color: Colors.purple[700], + ), + leading: const Icon(Icons.favorite), + iconColor: Colors.pink[400], + backgroundColor: Colors.amber[100], + action: CustomMessageAction(message: message), + ), + ), + ), + ); + } + }); +} + +Widget _wrapWithMaterialApp( + Widget child, { + Brightness? brightness, +}) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: Center( + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), + ), + ); + }), + ), + ); +} diff --git a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart new file mode 100644 index 0000000000..75d0a92c71 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart @@ -0,0 +1,561 @@ +// ignore_for_file: cascade_invocations, avoid_redundant_argument_values + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../mocks.dart'; + +/// Creates a test message with customizable properties. +Message createTestMessage({ + String id = 'test-message', + String text = 'Test message', + String userId = 'test-user', + bool pinned = false, + String? parentId, + Poll? poll, + MessageType type = MessageType.regular, + int? replyCount, +}) { + return Message( + id: id, + text: text, + user: User(id: userId), + pinned: pinned, + parentId: parentId, + poll: poll, + type: type, + deletedAt: type == MessageType.deleted ? DateTime.now() : null, + replyCount: replyCount, + moderation: switch (type) { + MessageType.error => const Moderation( + action: ModerationAction.bounce, + originalText: 'Original message text that violated policy', + ), + _ => null, + }, + ); +} + +const allChannelCapabilities = [ + ChannelCapability.sendMessage, + ChannelCapability.sendReply, + ChannelCapability.pinMessage, + ChannelCapability.readEvents, + ChannelCapability.deleteOwnMessage, + ChannelCapability.deleteAnyMessage, + ChannelCapability.updateOwnMessage, + ChannelCapability.updateAnyMessage, + ChannelCapability.quoteMessage, +]; + +void main() { + final message = createTestMessage(); + final currentUser = OwnUser(id: 'current-user'); + + setUpAll(() { + registerFallbackValue(Message()); + // registerFallbackValue(const StreamMessageActionType('any')); + }); + + MockChannel _getChannelWithCapabilities( + List capabilities, { + bool enableMutes = true, + }) { + final customChannel = MockChannel(ownCapabilities: capabilities); + final channelConfig = ChannelConfig(mutes: enableMutes); + when(() => customChannel.config).thenReturn(channelConfig); + return customChannel; + } + + Future _getContext(WidgetTester tester) async { + late BuildContext context; + await tester.pumpWidget( + StreamChatTheme( + data: StreamChatThemeData.light(), + child: Builder(builder: (ctx) { + context = ctx; + return const SizedBox.shrink(); + }), + ), + ); + return context; + } + + testWidgets('builds default message actions', (tester) async { + final context = await _getContext(tester); + + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final actions = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + ); + + // Verify default actions + actions.expects(); + actions.expects(); + actions.expects(); + actions.expects(); + actions.expects(); + actions.expects(); + actions.expects(); + actions.expects(); + actions.expects(); + }); + + testWidgets('returns empty set for deleted messages', (tester) async { + final context = await _getContext(tester); + final deletedMessage = createTestMessage(type: MessageType.deleted); + + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final actions = StreamMessageActionsBuilder.buildActions( + context: context, + message: deletedMessage, + channel: channel, + currentUser: currentUser, + ); + + expect(actions.isEmpty, isTrue); + }); + + testWidgets('includes custom actions', (tester) async { + final context = await _getContext(tester); + final customAction = StreamMessageAction( + title: const Text('Custom'), + leading: const Icon(Icons.star), + action: CustomMessageAction( + message: message, + extraData: {'customKey': 'customValue'}, + ), + ); + + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final actions = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + customActions: [customAction], + ); + + actions.expects( + reason: 'Custom action should be included', + ); + }); + + group('permission-based actions', () { + testWidgets( + 'includes/excludes edit action based on authorship', + (tester) async { + final context = await _getContext(tester); + + // Own message test + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final ownMessage = createTestMessage(userId: currentUser.id); + final ownActions = StreamMessageActionsBuilder.buildActions( + context: context, + message: ownMessage, + channel: channel, + currentUser: currentUser, + ); + + ownActions.expects( + reason: 'Edit action should be available for own messages', + ); + + // Other user's message test + final otherUserActions = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + ); + + otherUserActions.expects( + reason: 'Edit action should be available for others messages', + ); + }, + ); + + testWidgets('excludes edit action for messages with polls', (tester) async { + final context = await _getContext(tester); + + final pollMessage = createTestMessage( + userId: currentUser.id, + poll: Poll( + id: 'poll-id', + name: 'What is your favorite color?', + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + options: const [ + PollOption(text: 'Option 1'), + PollOption(text: 'Option 2'), + ], + ), + ); + + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final actions = StreamMessageActionsBuilder.buildActions( + context: context, + message: pollMessage, + channel: channel, + currentUser: currentUser, + ); + + actions.notExpects( + reason: 'Edit action should not be available for poll messages', + ); + }); + + testWidgets( + 'includes/excludes delete action based on permission', + (tester) async { + final context = await _getContext(tester); + + // With delete permission + final channel = _getChannelWithCapabilities([ + ChannelCapability.sendMessage, + ChannelCapability.updateOwnMessage, + ChannelCapability.deleteOwnMessage, + ]); + + final ownMessage = createTestMessage(userId: currentUser.id); + final actionsWithPerm = StreamMessageActionsBuilder.buildActions( + context: context, + message: ownMessage, + channel: channel, + currentUser: currentUser, + ); + + actionsWithPerm.expects( + reason: 'Delete action should be available with permission', + ); + + // Without delete permission + final channelWithoutDeletePerm = _getChannelWithCapabilities([ + ChannelCapability.sendMessage, + ChannelCapability.updateOwnMessage, + ]); + + final actionsWithoutPerm = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channelWithoutDeletePerm, + currentUser: currentUser, + ); + + actionsWithoutPerm.notExpects( + reason: 'Delete action should not be available without permission', + ); + }, + ); + + testWidgets( + 'includes/excludes pin action based on permission', + (tester) async { + final context = await _getContext(tester); + + // With pin permission + final channel = _getChannelWithCapabilities([ + ChannelCapability.sendMessage, + ChannelCapability.sendReply, + ChannelCapability.pinMessage, + ]); + + final actionsWithPerm = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + ); + + actionsWithPerm.expects( + reason: 'Pin action should be available with pin permission', + ); + + // Without pin permission + final channelWithoutPinPerm = _getChannelWithCapabilities([ + ChannelCapability.sendMessage, + ChannelCapability.sendReply, + ]); + + final actionsWithoutPerm = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channelWithoutPinPerm, + currentUser: currentUser, + ); + + actionsWithoutPerm.notExpects( + reason: 'Pin action should not be available without permission', + ); + }, + ); + + testWidgets('shows unpin action for pinned messages', (tester) async { + final context = await _getContext(tester); + + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final pinnedMessage = createTestMessage(pinned: true); + final actions = StreamMessageActionsBuilder.buildActions( + context: context, + message: pinnedMessage, + channel: channel, + currentUser: currentUser, + ); + + actions.expects( + reason: 'Unpin action should be available for pinned messages', + ); + }); + + testWidgets( + 'includes/excludes flag action based on authorship', + (tester) async { + final context = await _getContext(tester); + + // Other user's message + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final actionsOtherUser = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: currentUser, + ); + + actionsOtherUser.expects( + reason: "Flag action should be available for others' messages", + ); + + // Own message + final ownMessage = createTestMessage(userId: currentUser.id); + final actionsOwnMessage = StreamMessageActionsBuilder.buildActions( + context: context, + message: ownMessage, + channel: channel, + currentUser: currentUser, + ); + + actionsOwnMessage.notExpects( + reason: 'Flag action should not be available for own messages', + ); + }, + ); + + testWidgets( + 'handles mute action correctly based on user and config', + (tester) async { + final context = await _getContext(tester); + + // User with no mutes + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final userWithNoMutes = OwnUser(id: 'current-user', mutes: const []); + final actionsForNoMutes = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: userWithNoMutes, + ); + + actionsForNoMutes.expects( + reason: 'Mute action should be available for users with no mutes', + ); + + // User with mutes + final userWithMutes = OwnUser( + id: 'current-user', + mutes: [ + Mute( + user: User(id: 'test-user'), + target: User(id: 'test-user'), + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + ), + ], + ); + + final actionsForMutedUser = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channel, + currentUser: userWithMutes, + ); + + actionsForMutedUser.expects( + reason: 'Unmute action should be available for already muted users', + ); + + // Own message + final ownMessage = createTestMessage(userId: currentUser.id); + final actionsForOwnMessage = StreamMessageActionsBuilder.buildActions( + context: context, + message: ownMessage, + channel: channel, + currentUser: currentUser, + ); + + actionsForOwnMessage.notExpects( + reason: 'Mute action should not be available for own messages', + ); + + // Channel without mutes enabled + final channelWithoutMutes = _getChannelWithCapabilities( + allChannelCapabilities, + enableMutes: false, + ); + + final muteDisabledActions = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channelWithoutMutes, + currentUser: currentUser, + ); + + muteDisabledActions.notExpects( + reason: 'Mute action unavailable when channel mutes are disabled', + ); + }, + ); + + testWidgets( + 'handles thread and quote reply actions correctly', + (tester) async { + final context = await _getContext(tester); + + // Thread message + final channel = _getChannelWithCapabilities(allChannelCapabilities); + final threadMessage = createTestMessage(parentId: 'parent-message-id'); + final actionsForThreadMessage = + StreamMessageActionsBuilder.buildActions( + context: context, + message: threadMessage, + channel: channel, + currentUser: currentUser, + ); + + actionsForThreadMessage.notExpects( + reason: 'Thread reply unavailable for thread messages', + ); + + // Channel without quote permission + final channelWithoutQuote = _getChannelWithCapabilities([ + ChannelCapability.sendMessage, + ChannelCapability.sendReply, + ]); + + final actionsWithoutQuote = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channelWithoutQuote, + currentUser: currentUser, + ); + + actionsWithoutQuote.notExpects( + reason: 'Quote reply unavailable without quote permission', + ); + }, + ); + + testWidgets('handles mark unread action correctly', (tester) async { + final context = await _getContext(tester); + + // With read events capability + final parentMessage = createTestMessage( + id: 'parent-message', + text: 'Parent message', + replyCount: 5, + ); + + final channelWithReadEvents = _getChannelWithCapabilities([ + ChannelCapability.sendMessage, + ChannelCapability.sendReply, + ChannelCapability.readEvents, + ]); + + final actionsWithReadEvents = StreamMessageActionsBuilder.buildActions( + context: context, + message: parentMessage, + channel: channelWithReadEvents, + currentUser: currentUser, + ); + + actionsWithReadEvents.expects( + reason: 'Mark unread available with read events capability', + ); + + // Without read events capability + final channelWithoutReadEvents = _getChannelWithCapabilities([ + ChannelCapability.sendMessage, + ChannelCapability.sendReply, + ]); + + final actionsWithoutReadEvents = StreamMessageActionsBuilder.buildActions( + context: context, + message: message, + channel: channelWithoutReadEvents, + currentUser: currentUser, + ); + + actionsWithoutReadEvents.notExpects( + reason: 'Mark unread unavailable without read events capability', + ); + }); + }); + + group('buildBouncedErrorActions', () { + testWidgets('returns empty set for non-bounced messages', (tester) async { + final context = await _getContext(tester); + final regularMessage = createTestMessage(); + + final actions = StreamMessageActionsBuilder.buildBouncedErrorActions( + context: context, + message: regularMessage, + ); + + expect(actions.isEmpty, isTrue, reason: 'No actions for regular message'); + }); + + testWidgets( + 'builds actions for bounced messages with error', + (tester) async { + final context = await _getContext(tester); + final bouncedMessage = createTestMessage(type: MessageType.error); + + final actions = StreamMessageActionsBuilder.buildBouncedErrorActions( + context: context, + message: bouncedMessage, + ); + + // Verify the specific actions for bounced messages + actions.expects( + reason: 'Send Anyway action should be included', + ); + actions.expects( + reason: 'Edit Message action should be included', + ); + actions.expects( + reason: 'Delete Message action should be included', + ); + + // Verify the count is correct + expect(actions.length, 3, reason: 'Should have exactly 3 actions'); + }, + ); + }); +} + +/// Extension on Set to simplify action type checks. +extension StreamMessageActionSetExtension on List { + void expects({String? reason}) { + final containsActionType = this.any((it) => it.action is T); + return expect(containsActionType, isTrue, reason: reason); + } + + void notExpects({String? reason}) { + final containsActionType = this.any((it) => it.action is T); + return expect(containsActionType, isFalse, reason: reason); + } +} diff --git a/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart deleted file mode 100644 index 194652b336..0000000000 --- a/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart +++ /dev/null @@ -1,916 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:stream_chat_flutter/src/message_actions_modal/message_actions_modal.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -import '../mocks.dart'; - -void main() { - setUpAll(() { - registerFallbackValue( - MaterialPageRoute(builder: (context) => const SizedBox())); - registerFallbackValue(Message()); - }); - - testWidgets( - 'it should show the all actions', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - streamChatThemeData: streamTheme, - client: client, - child: SizedBox( - child: StreamChannel( - channel: channel, - child: MessageActionsModal( - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - state: MessageState.sent, - ), - messageWidget: const Text( - 'test', - key: Key('MessageWidget'), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - expect(find.byKey(const Key('MessageWidget')), findsOneWidget); - expect(find.text('Thread Reply'), findsOneWidget); - expect(find.text('Reply'), findsOneWidget); - expect(find.text('Edit Message'), findsOneWidget); - expect(find.text('Delete Message'), findsOneWidget); - expect(find.text('Copy Message'), findsOneWidget); - expect(find.text('Mark as Unread'), findsOneWidget); - }, - ); - - testWidgets( - 'it should show the reaction picker', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel( - ownCapabilities: [ - ChannelCapability.sendMessage, - ChannelCapability.sendReaction, - ], - ); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - streamChatThemeData: streamTheme, - client: client, - child: SizedBox( - child: StreamChannel( - channel: channel, - child: MessageActionsModal( - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - state: MessageState.sent, - ), - messageWidget: const Text( - 'test', - key: Key('MessageWidget'), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - expect(find.byType(StreamReactionPicker), findsOneWidget); - }, - ); - - testWidgets( - 'it should not show the reaction picker', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - streamChatThemeData: streamTheme, - client: client, - child: SizedBox( - child: StreamChannel( - channel: channel, - child: MessageActionsModal( - showReactionPicker: false, - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - state: MessageState.sent, - ), - messageWidget: const Text( - 'test', - key: Key('MessageWidget'), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - expect(find.byType(StreamReactionPicker), findsNothing); - }, - ); - - testWidgets( - 'it should show some actions', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - streamChatThemeData: streamTheme, - client: client, - child: SizedBox( - child: StreamChannel( - channel: channel, - child: MessageActionsModal( - showCopyMessage: false, - showReplyMessage: false, - showThreadReplyMessage: false, - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - messageWidget: const Text( - 'test', - key: Key('MessageWidget'), - ), - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - expect(find.byKey(const Key('MessageWidget')), findsOneWidget); - expect(find.text('Reply'), findsNothing); - expect(find.text('Thread reply'), findsNothing); - expect(find.text('Edit message'), findsNothing); - expect(find.text('Delete message'), findsNothing); - expect(find.text('Copy message'), findsNothing); - }, - ); - - testWidgets( - 'it should show custom actions', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - var tapped = false; - await tester.pumpWidget(MaterialApp( - theme: themeData, - home: StreamChat( - streamChatThemeData: streamTheme, - client: client, - child: SizedBox( - child: StreamChannel( - channel: channel, - child: StreamChannel( - channel: channel, - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - customActions: [ - StreamMessageAction( - leading: const Icon(Icons.check), - title: const Text('title'), - onTap: (m) { - tapped = true; - }, - ), - ], - ), - ), - ), - ), - ), - )); - - await tester.pumpAndSettle(); - - expect(find.byIcon(Icons.check), findsOneWidget); - expect(find.text('title'), findsOneWidget); - - await tester.tap(find.text('title')); - - expect(tapped, true); - }, - ); - - testWidgets( - 'tapping on reply should call the callback', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - var tapped = false; - - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - streamChatThemeData: streamTheme, - client: client, - child: SizedBox( - child: StreamChannel( - channel: channel, - child: MessageActionsModal( - messageWidget: const Text('test'), - onReplyTap: (m) { - tapped = true; - }, - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - state: MessageState.sent, - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Reply')); - - expect(tapped, true); - }, - ); - - testWidgets( - 'tapping on thread reply should call the callback', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - var tapped = false; - - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - streamChatThemeData: streamTheme, - client: client, - child: SizedBox( - child: StreamChannel( - channel: channel, - child: MessageActionsModal( - messageWidget: const Text('test'), - onThreadReplyTap: (m) { - tapped = true; - }, - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - state: MessageState.sent, - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Thread Reply')); - - expect(tapped, true); - }, - ); - - testWidgets( - 'tapping on edit should show the edit bottom sheet', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - final channelState = MockChannelState(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - when(() => channel.state).thenReturn(channelState); - when(channel.getRemainingCooldown).thenReturn(0); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: Builder( - builder: (context) => StreamChannel( - showLoading: false, - channel: channel, - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - onEditMessageTap: (message) => showEditMessageSheet( - context: context, - message: message, - channel: channel, - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Edit Message')); - - await tester.pumpAndSettle(); - - expect(find.byType(StreamMessageInput), findsOneWidget); - }, - ); - - testWidgets( - 'tapping on edit should show use the custom builder', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - editMessageInputBuilder: (context, m) => const Text('test'), - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Edit Message')); - - await tester.pumpAndSettle(); - - expect(find.text('test'), findsOneWidget); - }, - ); - - testWidgets( - 'tapping on copy should use the callback', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - var tapped = false; - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - onCopyTap: (m) => tapped = true, - message: Message( - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Copy Message')); - - expect(tapped, true); - }, - ); - - testWidgets( - 'tapping on resend should call retry message', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - final message = Message( - state: MessageState.sendingFailed, - text: 'test', - user: User( - id: 'user-id', - ), - ); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - when(() => channel.retryMessage(message)) - .thenAnswer((_) async => SendMessageResponse()); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - message: message, - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Resend')); - - verify(() => channel.retryMessage(message)).called(1); - }, - ); - - testWidgets( - 'tapping on flag message should show the dialog', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - id: 'testid', - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Flag Message')); - await tester.pumpAndSettle(); - - expect(find.text('Flag Message'), findsNWidgets(2)); - - await tester.tap(find.text('FLAG')); - await tester.pumpAndSettle(); - - verify(() => client.flagMessage('testid')).called(1); - }, - ); - - testWidgets( - 'if flagging a message throws an error the error dialog should appear', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - when(() => client.flagMessage(any())) - .thenThrow(StreamChatNetworkError(ChatErrorCode.internalSystemError)); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - id: 'testid', - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Flag Message')); - await tester.pumpAndSettle(); - - expect(find.text('Flag Message'), findsNWidgets(2)); - - await tester.tap(find.text('FLAG')); - await tester.pumpAndSettle(); - - expect(find.text('Something went wrong'), findsOneWidget); - }, - ); - - testWidgets( - 'if flagging an already flagged message no error should appear', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - when(() => client.flagMessage(any())) - .thenThrow(StreamChatNetworkError(ChatErrorCode.inputError)); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - id: 'testid', - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Flag Message')); - await tester.pumpAndSettle(); - - expect(find.text('Flag Message'), findsNWidgets(2)); - - await tester.tap(find.text('FLAG')); - await tester.pumpAndSettle(); - - expect(find.text('Message flagged'), findsOneWidget); - }, - ); - - testWidgets( - 'tapping on delete message should call client.delete', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - id: 'testid', - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Delete Message')); - await tester.pumpAndSettle(); - - expect(find.text('Delete Message'), findsOneWidget); - - await tester.tap(find.text('DELETE')); - await tester.pumpAndSettle(); - - verify(() => channel.deleteMessage(any())).called(1); - }, - ); - - testWidgets( - 'tapping on delete message should call client.delete', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - when(() => channel.deleteMessage(any())) - .thenThrow(StreamChatNetworkError(ChatErrorCode.internalSystemError)); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - id: 'testid', - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Delete Message')); - await tester.pumpAndSettle(); - - expect(find.text('Delete Message'), findsOneWidget); - - await tester.tap(find.text('DELETE')); - await tester.pumpAndSettle(); - - expect(find.text('Something went wrong'), findsOneWidget); - }, - ); - - testWidgets( - 'tapping on unread message should call client.unread', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final themeData = ThemeData(); - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - await tester.pumpWidget( - MaterialApp( - builder: (context, child) => StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: child, - ), - theme: themeData, - home: Scaffold( - body: StreamChannel( - showLoading: false, - channel: channel, - child: SizedBox( - child: MessageActionsModal( - messageWidget: const Text('test'), - message: Message( - id: 'testid', - text: 'test', - user: User( - id: 'user-id', - ), - ), - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - - await tester.tap(find.text('Mark as Unread')); - await tester.pumpAndSettle(); - - verify(() => channel.markUnread(any())).called(1); - }, - ); -} diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..cb199ba4b54cd488caa011481a134aa95be33827 GIT binary patch literal 2458 zcmc(hX;4#F6vtmeFzkV1rLu&GiaN@sLa-1(MV6_uHOL~XC@5GKSz;qJK@bs@KB3mBoNlH2q9n!s8wW52pEXq0>rQsBBT)Li=X_~;`ZCGbgBI+Fqk28=JN=q^MPu8! zJ(^im>eQr`2cVuadg8cJNR40DC`CYN+H4Iyc70riAFo|{x_~upDaIY_lRo8R;=`%5 zYCw1;yaEn{6u@A_Od_DEr3n~8p$?7?K&Fxspap@Tj8K5%zdV^s;VRgE{h$ zh>oi806II@TI+{@AJVvu=-3i}5}*M1Ni27IX@ysg(&oo$FI&zqQtCi6`d_NyJm z;ABqXnV|C+m8#cn?qtbayC=ChcLuuu&T~utb6&)A&%cc5$D2!uY8;OnEEc%b zwz}hVdf5$1Zv>zj!t1K>aw(bMj_DMU4~D(Qqh3OKm!@6NG=V6X!=)3P?xi4;vf zx2LbLSJpa_h?0jI=_YmUHkqB?1}w>&H%Nr>ZyM$Lw(;JvNO+4z4I>xB5lQ zjtQ0n%oUSRv4`Qot9UVMHL`+yO)_doc!AeH=j0%SX7Hm~bHfN4ZJK4jO6C5};ch>C z01DNKmF*p42=s8%?_|x1i(E5*lEMjPCEL6F@o+)%Ya4Ix#C3EG_7)us{}v3l$R@2@ z$YS!+N_V2>(!n%eulBoxNjoZKRgw7(NacbrG#iP+LS%CjwKk<_Pk1gsg9$h`8}*nP>v zx2-*Rm~jNvrgA;y0K$?nEe>vd(?99BCaWaWAzzjarB+?FS}r`F&tsaU#K)81+T*7C z>U-9+g(bL9ND>N2|42mH^U#CiUzq`?Tt8W7XG$diSs){TWx|Sbb?n!@L|UenHlHTn zSq16lRss;PcOee8YypeaOjJ zGDO;QI)?oo!Qfut4mzpk6D9b-E)p^+rL9y%#Cof9Jml1>ZU~m+89w>KIvXr=G>fE@ zV3@PsaQUp~jgEWa3zULq8M+y_sX+Ayd|NWQ{42Ue2~F?Dvwqyg^oBq};#cE<&v(O+ cE9nozw41*C?|5zV;Qb14J?7@fI1+N@FKwG&aR2}S literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_light.png new file mode 100644 index 0000000000000000000000000000000000000000..d101acfd46b9eefabb3ceac7b7553bd98d135a1f GIT binary patch literal 2550 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

MyqQi8 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 N)Jc2G^5Z_&{|mk;*`oje literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..12f8f7dc9c6b7ce772589734bdfc3141978c6a75 GIT binary patch literal 5081 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 C5k12I literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..77aea6972b11591bb5c1e88c11ab4cdc3b5be2b8 GIT binary patch literal 8393 zcmeI2XH-+$w#P$J@PI-n3IYM)96?cv(jkD-6chvzkg9;9ROuyPtpTGZHNxo)n zarl?xzkooX!RX=?jvVPxDl#=y|j5HwLk?@Ujfe_Pi(-PmsvM-t)>AL12}v#@O% ztF5!E{GK><_4U*uS@^}JH+8<7G?e{m%$V3^t?5y*M6|9yx1rjHcm8L_a)R#v+BbGS zZb|4*^Rk}faj#tBelXu~_YJbwi4ZJ#&45f_GcYp^;|8f*t0eP)Zs{E22c6>PHcp8L zWy#Bd{^I}l;lF3&|0x)<;X?6yr&8oCsUgp-s7l#Awqjh4VS0msm{LNZSrZ|} zx?+fa0)2ryzcy4X{xkiYxu zSI@9NyuTg#lyo|`2OS;b_e}bgCqKp+l~)24K{+7FCevs6Kk>hD@KeV`kGu1kpoZo; zSc`-AG#qxIV*MA4&3ik(+h4h2&4fvO(G*w;Z>s4C&=S(JEbm+~kkEa4y`a<; zeJe~Dc!^TBCGZlf)-1Vv>ki_XObuLsSxcz2Fs_uj|w4?9b|&m`ZZ{Hw{v- zd0X;Rp4-oE_)%;nr4}~ToZ1sQ!D{N7<7*IVh;CpDbynxWH)_<{w-31VGG|m*HL^NI zMqkB+JwDx@NWl=@Gaq$!;?fsf>w+eZ%I))BeI5HYl(UJ`6-*^$e`x6B4QERKNb!*#4-AU@P0L|xE+iQVxBnjM!6;}DQUBL z*Ns6#FmjKr$7G|?uO0l*@7_(8Be=CL8b5YLX%)wiX0H~^l*z`)RqHHWWi0E{llWv~ zbb#^5g2CF0I77pgRC=Z}D&jN69lo8t)m4v^v9fCMaNk~zY*C)s@}8&WdcbXYLUse_ zsrvK=c5`OaTnjzf0Vz)Ad{8)c$F-uMurN(3XjDc(K!C9rYLuyC7$gj~RoR@q#2g;B zXKe(r&99`Du<74k0iWb)$yOALnak12fIyFf!TPGLvCQ2X+>Y~nIFdr)J}1|kAc!ti z@~n!PhRG6qH4T{yB?bx*Fc{-}7EUdbO-5EXpQ~+m=@qYq-71T!1g0)g}+GA!L0*r!d4WIxBUcD{hk{DjWT6uVE>! z-rUr5ZVPgu=BVRjBz+3WaB_Fg;A>sG#v&uOEMwPPgv`r=7rzijN1Z0aX)<8^!`cn* z;+p0hfls4O1kI^~f5Z!-(Y|MyvS0hOTeP);NU{C&V`ktIRtKKqXt?vFezLzVz=Z;( z!-)r4_Z~Iu?L-!@ZnHjKwDAZ+0V9ox+4&uUz%SJ^!>&{``R{IQQ8Nu6ST>NtDd~y_ zhlhyp-3e0N4&xy?T4}?eR@*(AN{HIP(i}E_mzS?5VU*?N>jI(S&$oMD3KVd3PVAy}De zNPXI5v2wdp#R#}Z^ZM6>B+Bg?f-e##*YYkRXy(WLL~-K5fZ(}N?uRIsy5iNm=k3_| z4n`023xfMx$LH?uHIz$Z$h*HaOR3U{w(JQj{wTp!& z;I3(t-sp4{C=P!#5~F)QPHpRyAbPP=q@eF^44oRLm=PX1 z5l+M@017g!-IGlLviUUH3!kBso#Irj>ak+?MZmU(=;i6@DU)eXIiWp&Iz=ARz-b4A z)eYgR+H_}BT})CyM4;BVpQj_z!DcyO{ob9?heA;4Ac%nk(KU`ae{R+#2&)U9#=#Wi zXFfeqU}TcF9D1cW+f~p%!XG^BL8pGC;~p9tKX%#>?tD^aVRQ3vE!ZMMdg*h-$T*tv z?q?7)fC*SiA#+;DP|AX8OPCyP6;l%#Ck+M%HAkzF7#sB{$`eJ@l;8Yg%mwFNMn;cy zai(33YRS9Nm!jYz3i0w1;qy#(c6JmiS&_m}EKYMq9WB{jufbrpc3A(m&DDU7@9KHN{q;uV1w2m4`Q7-7=3@pK6cg72z~+iyjo}P z6+u7<1zZ@py<=CmbV+}p-b-G6+_7pyWXdc`{)|H52aBVPxuU_iLRmHL_8Dc z5_B^iUyozoVtspJG0;%^ZT707s#%DVZUX#b4K311mP^uZjIss>!-~h6Vs!2)l_%*% zlcUQGF4J-k`2CVFE~sJenbp-0gVi5Glw8BDgu^X+n~0T92U^h8__6-0x+PJ# zhlhan8cE3RQZtKJnLMhk(wvp-n$G^B+!~zj$O1EOF2s0bIlORTa~YU`3G)U9$YRkl;HJF!b~iEvL@~= z&OsS3hWdvT)PXm8ucD7ApJOCr={w_-~-(4*n8r+&n=tb9ym6eU8eTbHqg z3)lKw?rR)ptQY$<8s^kSe;-5u1+678{Lk3kjU{z;Lx>eK#>S&wsVJ`1Yj&j@T2v4e z6XZ{ZFS4HIy6e>)TbcK(>68k>Nvbxl%$y>Y%|B{S%kcoE3{_(sMZN|qwI>{YLMtHOnZ1pw zs_O8vF#r<9Xoukil_5GKIN3F(DCbmcDC^8D?br;`V>ia$kC0a|u{D4U1`qJfOkOD! zLYvp3r#16Y4$6BBDRP=(F{?XTcK1`6Q5xM~eX7_!IASS?KpO)1j3c1B;eW;_bcgj} zxU=Ee-nfZVk@Yjn@&?A^DF#xOGkOa7?dY-G84jDGtrA5THFpD$g;9f`d35<0vKNAZ z(yPDV6$m4v7!$2bsbF%;W?{(1+vY$L-mTT9$p+tEOc1QKRy>|=?ihHIx&INcSnSp} zJ~$(d4n)@0EKt;q5V$6*h=Exw4Gsawgt!CQU89weDD4&%1<#-BZqQj<>FFw;sT0I2 zr5>S7LNMiUlUK;GKNXANJD{%;BS;hQrQ=9^DZc~JtxTAY;=S`YfPHrxxyTkxf-SR5XuYQ8D zJ_MT?aS2Mct`M!+jNxW$_yyf%en!@Gy)-$`*jWg29ab+~UYS+^2+wQno|ToAkLhB^ z8>FbBNMKmDbJ_F?;f0d5%jgH;@ps`cV$I>OeKz>~Ib?bC zPX;3Q3zOP@tkkZu164mMt%?h~)t>v^DHFJlGfn19{H@HvcZNzj&%-u1SQug%fZ+QD zm4HT%uJw{?`!8R$w(fwDLl=ur?H9Vr?dqhYyJgcEfAE+Zo3}Y(ju%waS5uw{mI1@w z7n-h~8r<>SVsd1E^1RiD$w7q;cYU_(?Q<_QsjSMp;iTYs z8?L2iUF~TaKEC9XN8UP=6qXCz4q#fSo6ZG+gI9rI!H$*n8_F7UpSzgf_n7=uLRVm| zwtrXR+N`npHH>p=W#7>9^R{b%K~Xn?4ga+b63qhNP|5XLTOUyh-(HS-p#J`+WBAj3 zxu^34U^A3bBuetq7|EAm3WAS-g|JE$0E|JSj?Z@O3Bb}QS(fMJ<)tu^8TAciyz4f= zC!p@wojI$*j~51KSzWSyR_cs2!#Jd((aWxTyjrE`cOuHlOsAXfM>9_RDwq4ZRLSg4 zm57;bN~w|qhp#1MMyt2TT2XH)LZjgDphU>NbzL(CT>=Y(?09+O#kjcS%>MDP{41TS z?X|LH`RixOwx@F)23U!KdchHhUHOt}Rk<%bX11mQvGQ*)&i1F5Zwz!2?p2w3MeEKp z%ZqUtR?m$c#Q~RbXCBojtaV4k#hD|G=I0NmABAX;!uR25Y zx(%;hNUY=KZG7RXf`2uKvW?)obkH6-mWCZu7!0g$s=K;7`u2jEZO8EJea5X9*~-~@ z;~G+FG>}Bg!a`uS)mmk0ORJCx`u)@wJQjwGLpNi*&n?mRsGul6E+`B zp->nloFT;GPE^BtRyVCRD~7c7-Me=HGPSZ$V4C<>NV$khU7!s#a-t5!m?Qy8eNyFY zt{dEJ2WxTnNMO{(sS{@|9hX9G!1%L9(y6oD+?Qt!CGOtfO4zG>cJ;)$=Fi#b9JaXd zC8ZSkk7i&=vj74gQuE6<->Y-DIV8Ou$}yPcJa!9(~#?0?!uIaFjl(Jd#437i~v zFqW%4D<_D~h&SeF6r{t2xW4A2W*^s|kjonO=jU%n0_rjyz|a4yrbEsyl=sp?7uiEw zBOa*h;_2Dh5=i&0qC>ek^NelPShOPL_qCfht1T)7LZg0BI!l{v+=~Dr=MILE zoR?RaV%L4dkWC1z_q>1mL{9DkbPN}7EF@+I1}?uI@wKf?W5RS?J@eDM(Ayb1b~YXs z#xL+GcBf8LEdlul@BV}X$VN~f%rZ5oF(tjQJ@A14J-oZv$ zC+x+{Ol>>RwTDvpE5zH%D?=AK8SFvqJsP4=PR^v%{xqt1%vEI<&E?~(S%7YK&CI68 zyq{PqZY>r)#OG=&rf#S%NfCY8f9v2#`Outc+n^{*N^-Ecx9dI?b5rRCiu$^ zQAScy)XK|5uK|F68rjVJyu2hH)n$5*pU}IQ7KmeOU-1d{P+}%QP7uaVEKaHxRQ#DPs;8-L@7}n3WF#ep zU}1=}`F(d|_XIo^$2ZK)$_9UI3g2pXO^*cmlhL(g6Q^(hlgb9~b>Z06F9ga0XTM2F z#o(aA*1@yZa6vuQYr0J}bi--N_5K0Zd|vO4{Z%J28_LUnuX|e49ZFm_Z~X-<0ov)6IWE362yQkeL`8!rgYDc7L&;SzKR&&EjtH zkMaBuocM2a(fRy`!g7~X1b%&e{Q#8q<)sNa2+$KLQMKc|-hX6UmPdWt6Y^MD1JKor zyk|u3&Wj)1$0mEdh(F#<1>(IjjR2oX2JqfiC0F(1kNDe)a=GylO)~pFgcj#oZkMbd z*os2dK((}vmh6@pEzWDbbOFX3J7>eGBDYI8bD#4Z>5ncPOkXy-t%k=n7QoYSJWZuPk~uX5w5TB&zewBw&H=XNWuptTnF?_0VJ8ZB0b`{-?BLf!Fzhq;+V8_-zAh^DqHzUz%h@8ksWw`1VcY zIFEQ%I*^9zj-eJawFUKEu}v+@?Y4>#4)YPVI8#XCa1JBm#b-wH8V9#FPpFBDSR2{u z7+$|=WHdqH>c>Mq@$0DvyF>SA$=Obd4z5Lv?faR0PC|evzgDtlhc0gMVM=utXcb0~ zThRZVxy^uxstBDgNvFu3k>#wd57;0K+G2E`JP;1kbAukDtRK zETJ(q$^+07mzpl-RF~q(rp7)OKT!tNjo4Ke{&=o)){@nwyz7OapuBj}9`AhhJfqSZ zbWaKZiqqNXJW?ZSVWOqkHQ6R0KSPFEPZ~7%a<7A|+FRY93@W4lc=G(7W`WfB<9NX& z)I_9drMIp07Z}hR$bcBWpI(Z>9~TC;XaMqUFb!K^n*+4df)fi!%!-HjVVu#f^#0!^ zxg^Dkta}Gg^o?4OB;a#qX&L))dd@gM-TX{%lcMeyDZsBu73+9d86WHoiR+H#{}R4$ zx!yHT5(1nbX}&ml@}!ri@AZ9xihs0?t?q+W{U*m#<&5eao}E*gtdhR;_Ae#R;HU^gkxmp;I*5@D28KaH4GtnI0wV}W7wI*i z2|-a16_A!FNRbvp3nh^IY-hdaUF)p-p8MVp_sdz=53+W$%fCF&ukFNJo;Ty(C$f)? zjg9-))2FQ1*w|Cq*f{L>?1oRy%{{}xA9jqD*$KAtZn1B0uoH9QSDQWXFLKXi_)?1P z*Hg!BLLbeKM);1dM180C=(hfnlBT0Qr?c1V=e-%bUzZ(q3b=f7k5;jue20x~#86R| ztoiVgS-x4;9~#rL)rD!R=zMdRlG_(%9MipKZ)rHHN#8R4YbNe;(%GRADPb}@r<`mh z|1h~nGTBi7mtVFYQR$UGb`EqPn|mD@N(+%@4Uy9Vc!g@uLbnVAF%g`#s~+7gELF~ZUL z_h^l$wY9bN+Z(gU&{wkeIoHxt6`X1nf@u`-*w|PY7OlPO{qAZvQbIkwLzEP&TT)i0 z=-*85n4X?~%CHIL;dppu*yv(^l?Vf^z70pW}KBJWT;?~B> zO7;o!WLSSpkD;)rwtrHM&p^MQ#L1H2KfSD=RBuJ$nZS56uo#;PcOB^!vFA zW9B|pt`%Z83O&8O6O5TJjZ43|b8~Z(Vs>!mR#YgPnwq*zyiTw5`cS}?y|*6j^rC#H6Li3XQkCBGhiwdsI^$COM?40f8LOwoKEiIwjJd)YH(FU7yRh3bjt7j<-WaI5Xq;Xmp6n&W` zJ!)GUs(EcJvA4IEPkZ!+^(i88$f~9>cN2PnUQ-dJcs@%nsGY`u4spjD3SpUKtQahC z0_-HL#ycW|%GzcWN-z?RmGh=LxUDujyA5>+n>{Lj{P^)&hjuHyJe1h5YoV3VLPIum zY$5}lLYBlbf4AE~8*S2VU4I+UA32(vot>={I7TE+skeNlbZ6-+Z`LX|e?Q^U9~eH7 zZZ{UNJsB`&X1wuRBx{q3_sEIT8gsrTGv?y7+hqL<4_1c{4-K`pTxcwgW{wGuw{uD+ zK|A7bI+)2fr=mG`?=B!JL|8WG<-HudRrN>on@e38$`)Hcw|sxWMPD5bKre5mpE=yR zQWii8A#9E&EzEwPH4bOV|?NN8g z@^tUoLI^?h<;$1+=m^>YgyU&nS{-tScH`P=dg~|dImx!(ge7#S+7g0adY334_MDwj~$LbwvwA2CLdAU3X;6WV2P|h5=&?mfxME zZER=`IP>Rhj!f;#F?%#TGuRTrs9sPHD=FHOW+8T8tPn~!9xtrusBu^+-^xo`tY%*) zkkWXH{sK;apuV!UuuXo48ePyghOH=p$_7(ioN-szrOEwYI69%|Z04ml=xWwHF} zE3&3+fXThCiK7<%!b55XKr%l%#4uu2K#zdKv6wxqByCEljI^{w=;xUFsq6^K3Wvwy z;Eg_i%^{8l;yW*=6x+yuvvv%CDm{^M7y*!X2Te{fXQAj#Dvs6PcPzj25wIbL#hfav zNk#WIeN+loiM)Q<%+$1iX_S;>DmoSHu{BEFa$(L>xBcdZYD#3=#U(L72iDzfBH9`n z8dqBT{2R_2%_ePBitF44XwTm-TU%2@8V#X}vlf+ER(<2F)d1G&UAbcEBtk+~iX&Q( z5IjG$26r7@yNzADeH2Z7cIhOuU6OfR%qTK+Y_DH$u1OpLOZuvqniv(ivHb1mm#oNp z?>~S3Ow=?!dru*Lwt~?5Zk_Zb?WnAzea;-98NXy*b+yfwI)Ccman$59?`@nB^9v6- z+b{wFrSqe#ey4z}`mqKesKYBl1?quU`zPOKjsra4C0T1^Xl^LOTpRg5rlGy8IDb%%O>JfttRj-gCQmuk4&EKiU+qMsH zhv(7?(`JA05`fjVPrjMQ;5+J(QIy^)jcQ!B=@K#;6iAI?}LU9zzE4SVgm1U}`f^8*+yw>odx=Tt18Uy1A5_d0Sdq`1lZ}#9_F2%3YeY z$_d*W^^32M`Gl{m3fejI0UfkX=l&@!E?#;0)t}JpN4|=rd?>WAGu+(=08~mK5Q_V} zpgYHxa#)cD+iT+)Eib+SgN<3|Y}lA*C#iY#k3`T~)NAiX`S|$w4nDu~ddMCg8@SSE zH?SP2T)XRe%l5d8B@NhCwfmXqmxonI)FUJhpF4EcdI^wIysQDHRtg``2JOKooiCt8x<_Q z*6o!F^o^q#2#K_=)>M#quxl@im5pFY6qz<&*L`E&T!IQXpKajKd8`poN$#F9S^{X6 z*c2?I3B(!8V{}k^WwkJc8XvO0?1gyQa7 zw{MRlghy2elmvEC+OP1ff!{*1rxN zJcvU?T<^$;nB;n=*?YS`d4BpS)a-@BDU?VXX#1;7dp7k#pv92ZrL6jmnG*M<$+zmk z@7sKr7rT@#8Vdf{c+OSAj>!I3X>uMDo7b&dt~ZDgSepbi&Fkan8cnzAcGWWxgi3r? z`|~XWWMpJ2Luiz6i`b<-r(+L_h$MjYE}NvWv#XcEb9^dVCTEr$PNPIRK~H@-)_$U8 zez1xhBw2OWU5b11Q>DAAn%V)7#MNIlF+Ff2$U>)g=-p(7HUn)Unl#*E zmleVo`5CSU@DANVr(;FL#F7xD_fXR(x2b8ke-GwGXXj~zB*VkQi(LzD5Amn&*3#1x z;pCA>$}_`v4AuC!ugvsmx{&uh2ObqO4AL18 zE?+`TR-DOKqxUz#(x|GaNQqz`MZd9zgA1CwipLJi{VV@ppUUg)%PeNyyLS&PN9D7_ zaiZel$zQ&F(TP~~ZC>iuR}YROM5DOxc1<869r&3vMoOGD6rX$m^4b)QM#HSC3-B^h zmVZHIf$*;MA8qvX^DATAxLiEiI&A&x`mJXaf>#2p1MF$R5K1%7auh;413p=Lg=bxvSW=Bp2+LE9e_!e3!=c zxVVaKlrr33-r^o>FYTvLBt*4*kK8!N9wYBJQm^{ADQY{c2#&750*(F@%E4g^X2PV@ zx#2nGLv&XyaN7&l?>f8T<2rwrnVaDG=zSG8Yre0m5DXSOWr{Y-9I9l&4Z5t1M_AlA z?Hv$+=ehYkwrEqr_~ytxE?ZI2F5@WHoQHAAMs%Z#eQGrTakvHh`vjd)XOxr|DM4^0 zo8yTfee;-9YPDx?F7n;b@NkL5NtD!MXCo*LAP2|Z zzDHXeRWXXZY%``Pw$psPY*ssWMhmdBOPT!R@BkRHeORp5{a-=y+TwqfO4ZQQbEF+b zIr7nxmEcH4#S)H&zI`bC@w{)qy~t=*7z{hZThS;hK5Vq5asXi~xX(QlCWjRG_V)Hi zeSSm}yyP)3#t;O#p%RqJy9JNSiXK@)xds#}$EoI*|Pq zw?_TN2D7O287S9*E^H~}puHa$5N-;dmycZ8>2c}!aZ@uhcgDhKZ(pAvg0$c&!Y$&% z7U21T-#@p9F1^+EQEQDxwS&z>3N5L;yxbmm9??-0YqxCOu*J(T6;f}Wna_p}2ZyF* zkxg!4p&axs(n>zIx+^27>)_gH`lyecGE(dVX+~mYUjF zagfNLvD5!)w03?xEB5uoA`zQ!RYdu~KH~{34eEi2RsR(=iGwju&&?%)8R*D0Nt`hh zzbK>^G-HDd3tWU-XlVT;UQVjY+1lE=6eL4qQ&XOEEt#*r9)RByDi2(I$CsD4^9lrx7dx3RdnH?Yl{Q(hDp4}gdtO{S52?g^yb&xZ)A7TXP z5gdRlXoWbuvQ*VMh)0q|wL4y?ADcB4{EPkWnS2DP^IBRAK?+H_ySv9F`xR~|V896D zI4$dug@qn^?7pv4;XMe4zf%czji<;>{ycnkpQr`uYCQezIkG{t;~}bv>&K;}=r;!t zY`FI21(b*9H7;SLB)}3uwR`Xd&=FLnibbhwOJi!_&dWlcK0b**(vcna<&b?TD=V`F zgsDRHdYG~~zlM|mDd(#(q(tEX-#KA)q$&~#JWS?!V{Y;&dE&$i2gsmyX&z!A8N&Q< z9T^5SwlP~#@ygx#HTW8Xjp@9gu(`p~{QScb;nPsDv0<8gF3C^Y?63_BoFAZT6W$~mY&I%u@!VpUKq942IUFqQmt zB!POQ6DW%()ppwuHo2V0I`$O%q)iWW~CX z137C%xzbgxB}={lo}Z<-3qTcs9u*v}^-I(ViFyTU7$IRul9rd3i6F2gkS6w}wi@2t zUdkayF-CB%xaG3LXNr&% zjVuwNu+T(n{q+3GS#b~UH=5_i{VWm1NM*jICgBkKcKtO2IA^?Zwmi{zJ#r8pXC)o<=YL~#q@J%UcD4aQa_N)Q(`^&iGfg=i%CuMkfWvi>Ji92`< zETh_lHC{^gcliAy!t8AYeX;9zT*eDjsYiiOr`X0k0pq2w99=hCX#&w7* zp&w9<$8g!QrBKyl@97;#w^nz%wMFqFY9?+5)3O4 zR56Cdwx~+1G9fS!%F9kedm*b>SZ? z&uQX~tAZi+a;F0~H9?gdkPp_GzqOZXbD`Z(9|5(ZHcmykXbx{>hS4=&Vf55_c zYuSYM0n#0$NkM(_snP>}TzL$=e&*8n@jF99Lpz`B<9Lr!3V!1bbXFTcz1h22Q(M~s zklq>CEU|S$3VqjbGH{!~MkB@j0Sf_DLcM-uQA($c^iPYTlU&E{vT%Hv zKAem$GP)@qAN##+f|r*Plpo&U`%<7@gZ+z(T{(pF13^Y@BT`TkjdrOPAvKgF5SgKC zUvB%TY1x$I=jT(b?|*<|OOk9lc<4}APhSZ6Em0MZob>gMnYWgar7?`W1MlMOy)wE4 zey{J^1ytUF)ZOpFY#kU0Z2l6|dJ_Ft)9WJcwu za(0E|CCV5AYz1$ThN}feDeo)!QDZ}OSgb9hZr6X=)W>?KV&&>g#EhVnd*ZNtJ{)s#5&vCrR zQG61|BV}axsLWMXWUE_PB|D_!p>z7AWKN6&21A@OcA_~50G9XWum(x^Fz44bnF(24 zozovt?UA(?W1>~Mw)$NNL&<%u(~EVo9RVyl{$qGBDwa3ZR6}p0WYj*5CpAa%?yDU1 z^eS71lvJ|k+DOdOoi7+x$~kW0dQJ{DBD(AIi5I3CT3RbqI_jsKmhV$jREf`O|Frx6 zIMm3s@|qziPAM_Gy#CL*^{Ll{p4!O&rX>7naY_H(2(x6RQm78Sh8c|x^9Zfq;JUr* zvd}>ZiIiPjLIT2JB66Hy#3lk#@>18l#uzdezE|k%&ZtA$2B|+TQ!(~ zT&Q+N^=c36t-*y*)Wb}f@|##<>kd9Fy$`2ZLfu>?jBJ)*D~^R8rqCNA=@=58%Z3Dg z4KfuRNCaX1=^T~=k+p5iXJHf+R!4Icr%xyg>T_P~N5og3`<_mPcOW%KM@LEf!{-Zd zv~2=zzQ=T#L16gVg_!zo5m{pV>>{pUc7B|!qN2hJSwb?XIX6z%N`tW&3qgHZl_~E1 z`-PtG8q=USj7|5#yDpG4K+ghdDWGu-4GsS`l^}k=V+6u`j1wIPQXO(ZMJr?1yACd8 zi=mPQwhTb#AjWl$N+3`^u!($x$?wx$RXvZo`hY^AyjZp1NYaOF@n;WL^GStLhv~MM z9jXQfV(=0Nj8wF)KR^m1+J0y|MX9QfAQ#=QT~h(GWizMe(AKO9{%%1z92t)RxB>zKz}r4a)vQo5{V%oaK8M*ED@d~CGrIU$gYq%! ze*X}@uT)cYpGpvpuuWlZ2>p|T`FA-ywv#djzY}LXo9t4bt%hN V_AV_5e#61`tI7FOy<4=uWSh+B{}=;Fhrg3{g+_dANzJ7eehJVlueTNleL6>}rglPt=9?XZqYpq?LZ~A1_`d zJ1&kup|sv6`v;Np@p)B_m{9RtDs z+5G2j{6B%=wPzi#9@C@{_F69W!)v*F73TTovQH7laHnz$xi>vM=qcNz#V!9&HswCx zI7Ol4J0Hwt4KY7NFg6a~8J_n_c9n;9dU|?>J}4Q6d0bhgT>N$7risu@ar3R$JqxE# zi^sDge?^?x`CuWhDBrO+1;3Wn=L3ErD4cvpPkkJ2Qx4qk#eLa(n+$j29-fm;HF>!% zo?ucqyph-1a6LVJZha@y%HEzty}JzJT5$rb0{xh=wxS=N7-!cI*;PuR4>>0Z#Xg*~tZX_i1I7Np_u< zr_u?*hep{f%g#2hiZ~I6&?{!xT5Rsp;Gpqs=$%vQ{tdtCg%~(+^vp}?ZjZH|t;bH! z%_-|*NBhwu-nrYJ_89VPVS38fS{3(2j{3H~!PC$)?R84`%XMN4Cm%%&XL|c_c)(pl1vqKxSw>LP zd0jFY)!C}YF|0#ScFDU08Yyw2zFzfai|Xd{fksOLq0V>n#i98h4}I+8#XbT*S* zYtGQ7Ijt{VuECTC>}<-S+lvAioG+E=GzaBqW?YJ5pHDO!X$$4}@xd91TFG?H{U<1Z(2kK>1Xj z%C_!K9^P^m{mC4atG#pgZRVT!w#c^Kc^TbPzyaSYx0s8PY|>$GRkAf1OlCm~haw}5 zL**Jz`<7RpDujKVO~}f)wIlIFQDP1GIqN}_*RnhnTh^=9Rq(gxu|YJSV@`oY5Qd4;Kb=Vg8#N*%6c}Hkmd8zzg~Qx z<>w7;+8)2q5>4;s%@+mcB)FbzDfLisQIQhEwwxL=xY#ebC@$8#d#k6T!+?QhG8n@S zrnDo*;1A{jM#qhUDmJYtS-xIwPWXoJygmrz%QDS&xU>H+i)z8Q5_+A(vtw8D)+$lR z9Yl-RCI>^a+aZ@$Vl}0uC6Ke}N!R!OW+Aa{_7x z1_m_~FC`&6BeAAbJy%y(=kRk7)IE>64xxqtabxi1RR6QS*F=ZXGqmd87KXSjLMp=W z_}N+-XR?#_l>K@Ta6$x)6bCF70EHhTke#{y(Avr>c2cua=fg9{VFsyD_e`qE#Y2be zAs+cQu%)Ex zq>e6jORFk)#rjscRpukociVtwdsHrG7QIVXl1RW}Z9?g$4lj9l`?E)ByTZ^8eMp$P zXkyp5ji3sKZmk&04EL(v|8ObqBTj6R1fsS|S(~}O9qlbA?dP~|cg_W-huWsfa!*_6jxtWmt~0+}Lpq59zxak9n@I>jo1c0C=l z6Eke2H*ea-;ljY$r@`!H8IjKO($0?_J_#C>%Jm)LnE)=YkU z9^qdfI&`itghk=q#M&re_p%&b66qVn_@EZ1o!_5-cp>ATIAs-^2vjr9u8@ifP^m>`_YPZCw{Ov%Q#5=I_%`eXHO#G zDY9=Ov)}$CMC17-ERBVj%TWqt=kK4DG;mfNB`RsU<`-!7=c;jb&6=9uPzvdRFL;M$ z#Q8{nRZ>!t3LW#rr1I|4qoadK_0BX=m(jg0ex;`1iGj*+*dUN|Jwq7Pbq`A|z;@&T z#{SN@O}uQ6L3Q8-C2U8oG^Yowk9RIHL@ufz2fy;4Q3{^vOrI4&=}2rgQqodU0y()x zAsZO#rQeC)R`su!<_1<`9sL5~fscP1i*WSO?zo%BzVAdE4Hlv@=Plw#dj-Ox%yv!gSF}{3b1rQk*3a^Ki{sbGBS}MRvB1^be^Rc9`tRR zd2xFBxla->Yy0@vSYa8nu1uBtYouJiNMC<{=lVMQC>Y!_ z^XApdg@rCrAH&My$r5)RY&_Ra9u`Zyxi{gk_jrm@0zd- z1C~Yj)*uwGD_(7pc=LQXeLh8`JQ0HkZJOh%|AS7aX8=ApG&BTc;>rYdWboFEQTQn# zAryOkNlY~j!bxa}kBp3zQ>@m2KqLXkA54Y;q;uY~JAA0umvy zg~m(%c^-vb@a9lwjAjWfbSEPjB_;WWIt!5sEaCD%%M&uo&f{F0v>k(`nBL>JJV@~y z5Yd$!sC*NU;b0Zp!XVJp_MCf4sT&DI=5&js1AQyK;`8es1vR2Lk`@%MMcV5&avrln zh*a0wlz&juM2`Q_kLDdd54hdVAD2pX_PPs{uU|hKM5KIG6aU2nW8=384nJ+gr#rXm zpCqAkib<{TmS)v27ISz%Cr)ERMR(Hw5ew--qvmMXP(VX3d zl>Nl24~)HM?dm%r821WgyAMGNi44$S%6& z`%*OT@9Fm8bOm4h6^xBSMLlD6yvB|84R`6%r8xkUA?=2qVkJPtFRz;tS8CZSecF<5 zf3w~;39`#VR&TLO?ibIcLv>F=by$J8O@snK?5F&<5e1c%N;w*#^VQo@Q9L|;BX`tp z0vQUIyZe~2RM#{WTk>0Fjnf?9&LyJ^XWVj@(m?+rHF^N4Y9B@k)@Dv^i!nTtn-|x2 z&LE^7MgY|LtQIccHO{NH>Si;EGFW%m&54pRk?CQ%RQ(w9rY|FVB4Y%zqRq9U3@o?b z3~DVItFW@ZW4?;9UcSRU93`6A;N}6>s8JaidNPema~6CbGwKx?8n4I?$p$ayA}7V!!d?Ox-Z?8P0dF-UOg1^Vk5EY z3ZPP~GIA55=^ES5A7(_rr3+zKfUW|h<6YzBTfnfVL>67b!}}+G$45lKZvedjk1wc1 zN_mE15*%I~Zg_|Nbi&k>AN}cb;E?H7H3qO?30SZxH!QJD8m5n>*9P5?!Pt~P;9M)X z=Zn1Vp(+E&^v%~WalBNG^6E^)pOE$gd-r5?ulBO}yju0WoTpFJRAx>AVoIIY)j%+(Up={GpAb8C2_AM(m9{!MBdrnOqG&K9rmi}(1$U8Nntpzx8xVmC#NIs^g79Rdud5U z>9au-O?&Jc_IR$6(YLidiwiW7tw}-Sdibvns!C%~diD=dY=H1eN@e8`ow_~bq%71Q z%N;w`?YDR2f2yo_Xh{Kqx%1_LhIgZ$&l3ZUJ+-9na5)KYGx?u;^S-xtkaxW>c+fN) zd9HjTLjIEd5y6noFMFYNF`z69JeRfA4sZ7&=JVCDjdQI6|TgJQy8$i7_Kaf zb7PU$L=!VKRqpL?F>ucDyq`*{_>Z{tn{|F^n)|wg?d*)s$a%9)z3Mn3w_~ysHzHGD zUnx?5>+*O10-<7PHlS4_WvsX2Ri4CTo#R|)VR z20cs|znI`Zna!+5-3_0fnfIqS=52!l$FKAR<+V^*0olfEX_P0=LR(cHH zLqHus{oCUa`BujDtiFugti;Y}I#555TQ>fyH~7(o+fP6nZ?dw<&QEnd{u%Mw8Mp=f zF9Cm{YC}Omv7>jQCXKYF94+CnD!D8Ie)lAd#WMu?^WwRXJ5F3B7GBEQ)iodbxNIK< zKQc1+!uWur9`NyZcMFn1nmsAs39!HH^TOii?Icvk@GuOB-2rFoQJ7uE7Q` z>5!^)y&d9oRk2#%4sxy%gVq%Ma7OzH6TG*KBXm}!C(f++L5>t;FArSN1PBAUE?iLajH-%?ir;Sc(C)+lQiu}LJjmpA^q$oH{W{jo z!LPvjI!#E(Z?QL1J!E}id2KDhqV!}V4!6$-N{7~6L2`e zCrkZlHC}(58bVs&l0@vq#m4@%9pmFx^74vZ?I`VrEjqBrykL7_Nq{*32{veIn?BGP z1!4GU6FQ$CkJ$Ji&Wh4_Q#e`_~N>HKi4L)FA$A{y`x#D7j=?e~q1|4jcnbN`W!w)Y> z0m1^HvuNd*Dv;`zv?JZo3wI7N6t<66358Iv5hx$W)`mPW`8EnvcoZ^anGVIrd8D<-rZMYnyka*6YGUAi#h5*dF>${h`wY84xV!ve!JK~>)v?n zJNHJK{piNIz`l->lxc}CwPW`YQjpy&rZXJ=Y2QH36}UFY)*5;cV3#g{AAr0b9Y6b5 zCMhfybSkIFm*o$9;&x<($VvqvS5v$+`Adh~41uRSzC;-p{|G}leBG&w+6397UIMqf z#;^=uty*vQ^oYSbIwzB%L`q4I#BZyvdZ5ouz=P4jf!oO^L0%*Gx$5=wKq0yJ)BY}K zLbd=*`)ew-cH#ZGJXEvn&hocDLto^sW_)S?`c>s$n+x2qPrl)6V8C8PUzrTguxWs( zh1S7+L&iXigOz-$h{)ImEhhnnX;`H1`Xt5+SiiEy1ey$b^0+Y89a9qt04rWhpjGtF zTg{1$b8v*>g#-UboxX6R@b=%j0Lz%6S-KwFF?X~ zp`$?KdZ z!FgDs#ajNsM#V76h(sVK0^#^|PxkaHx`>QJQrE{vwhY~>=1(?kHsV)2m&f%ip@Y2d z37&@K=J7TqCny$j*s!n1FP0Kpp8PrkiwV!eYIu;%AK6T6&GFI8gyQIS8hZAuMfsGYD+&0W!DwM5|seP ztm7;6%2JfFJCeDQ0ap~!J@iiPPHyJQn+1doCpf~J_ky%DJQRwP8RnYZbJ|uBE^g2{ z8s8xJDBPzuwhz=)7)`JD0Y`509qFF^5(@CF`0*31Cl!Fi`{jn4S%wpfPm6R7@ochw zLJtQ>qm1m#q@U^|Dt!FLfOek9tTFT!{8M^ggMG+S-@F*zAF8CFsIGhDgby(7v{Ttd zL@z!K{xukjCkmi719Xj&KxyJ8|jA|xGwL(2m=nzY=s9*}CD02rW=Q3uQZuJivb zcK-S9@c)QO|9s8-@6;pU;?eKGw*lw&zXkYTV8e!_^pRCHsQRwJ!=PJ+W(E~E9Dn;4 DyWzgi#Drq**?V!1Dez;2Onfv3K%l&UIP4SfX4i0E*3IV=yVQHj1PXHogB9$Nvfm9@i zLy}IPguFR;5ORTuNh|i>!+%HPe<>OIhKNwp`k|pA;^Ja_VqzkZNQ|z!Xn%`TXd~T5 zB)Ys%^Ox4s*LMsFY3S8{{aZs{=Or{6UG6pY$>M{{HA%Y$<++~RN#ZHlsBCcO)2B}z z0s@quMn&y+V&h1%ygShlSnfUhg}AbUO6AcPab?TS&MptxS+!^k3A|A}s2sHJ(m>l? zK+yJf^w<+rIg>24l+&dQ^Uc<`w)8zcJq1;~&$5YVNS+;*fx3FH5qeO53qvZ#ttEYZ zea9tkl|<(orQyE9ngpGDay-_P-ZD3JUo6*+<7veuoM?S)S)7-5=Hi1Nd~rNd_t#C| zGDBU>82_}fFs$$9=9U-5r0DA5kpPBmtFvEEz_|{Ko-`rWEtJNc@NAF;s{nUIo=-6> z585CRmzN)`o1RY!SIDTUsIcRf*dZ*9Mcj8>GPm;Y+qR#Zv;7YY7fZ zqm>Bi#;}sRU|wDxdDIQlI`ug!&kC(qbR%|RVxng1=?Mq&bnDR*!zoAD*l?QkHO;n> z5sQ#Lya;B&Cm}Hr*BDBf-X`O(NvAo^_vItLN>%GPI}@yh>ydQYNQLv&66@**qxL<6 z#pZ2D>M)X9*<0W@t<0A9PG9fuq8D3YIAvvIj_D@~#ssd-wa#^AO}-Z$+TIQbp;IPN zK7?*vBoZlU->9A{X=&C>#B^^ijp0vBZtFca%->Gd+({-bEoGMzq|?5ZJGLbT?98U& ze|~&?4SfqnsWHjA*gAx^&bq%jCf}pZN!eVA1DiLrq;e%&m7BilN#{}XUye7-_wH@u zk+$Izp%V3Bs_W}JJxGns#qXRP96g%!kiDH;`p$t+ zDk~%`oQMgTl_&@A8aF}jl<#Q)6XG|=JW2Y74;WhZ9|2v z=UJ59{_RH~A^Vzm%4-{GeVgdp@c8)nmdU-Y$(D{}F&KrMEOr&g+xRPTd%I0jI5aer zg9AbQ_NoKr+~c~wxp}xd=+2JAgl!b}4i0k9 zdaE?<&BE+AtCvG5o2>+mt=et8CJhfN)qt+qko@uE$2eTzyl3skCSHWT{Z52}T?vH= z2mFlSZwg;4)TFwG?0mIPEH5vQW(`i+nncoPhS7F$TpHB%{$w(v-dRLKWP*Z&@$2*b ze?+L(hv4AuE}0XyJHL&cq+peUHy3ryQ=Qqd(pDeNTUlF6H7duc#7yktk+OPTH;1Q8 z(rHe3*;iI*93G`9O#j7B_iEL?h?r`nM)KOFZ?0W!L(&LHyY)@uMY6G?va&L|4M`cB zEFH6uCXAFjlJjAqu5!X09I(c1hn7f;Bb>TksF}S-0lVk8HrG{tuPbw;2I2T4bZb0W zWUStQWyYe=s@B_y6lj#+7cYD%KY*!k-}|;ISm?FJ7v8lYH={HjF8|07_&j(%?Q3!r zM)a<|@4YV|S7EBg*F9kkzb?h2P;I*#3;3$B2XQrJEOP4V>ikJTwic=z6nvj$`1QvZ z5sAxvpRZ7<)OkWFAy9~PRV!1=+}xbB7ONh%H<#tfQ-wAP1uv2K>eZ``YRc}e!^cPa z{em06cD&%i=-=>P8s*NVtrz0eCU?4ZS8}(PXgR^lF`x)c8j-hezg!MJxe_#7FD)?n zB+V}9LfEgzB04rT2Y-EJ5s9yvp*#RpKEEo+%ewM@NuWsLfWS7bC0nq-CCPQ zqTnY07J~2~h3QY8Ga$#Z_C^52k29}Mu_KjtDHO+^9C&hndJ|=Q1($qPgMaY8Vo*@f zw0{`EUvx{L@W7iP_+|f|7vmutnOd7sZwm{>K<(aa=L4m9tNmetDnRo+MrvA5Ab&PT zY|n^k?xb#E?69gdkP>CT5IQ;~R+ZvcUMS0=dsISqeW&m>KjPmN1@os-5<;fG-Ndrp z@$>a<0o%;GHSTW@_y`By^ZQ7(r@fBOkKh$7xtW<=CpefggD<414GB>1WlDFgt2`Op z_g+(n^SWslOFmj_E6$`qniV#E0nIST*wAE zL;m%dy$zINST9A4En7&{*JV|`V{d1TwF%iefK8O3Qadx`d9hkov$++^I}L0OPPe$D zPn*1$1hhtV($v^Udz6}*n(2J4c6@0OP~yu}k=OOhbrN=gvnj=yeZeXxlpZv=3|+k@ zM_?xfp29x?q})oG*lOHH(YH|@TPE>-gYRzog)SGpN)OU-B<+s_K%IM}{r7W54pW~Z zdEr&X#S+U6YuzL7os4X0SkWs#?dM;N41D%5N|h|y5!8c=ip%)ydvoZ8icdkoj4IPp=@fla^}zAO;mOb7r0ps@4ye?46hh`>rjzQRehDb)?qE`3O6^zD-TLS3p3` zadCM{u|CiGr7C{=6UEil zNo96Z^c;xP^tOs;a&Q;^?Bs=s=Rhhupxqj1DBqGi)u3 zQA9TDaLb|_(+l?WAcj5++4fT3nMp2xFkZL5c9fkxD?;(>A%kQ-0ReG$+m~v~HD`8r zcc){-a?(RM?6E<9dpOTMJzLCX4k-<}lO|^Fh3$(i77`L7OEj%YASOe%y4uqV#8V8( zIa>{4IiZ{1fx1KB6O_7%YwSmk7}Kb@6Q1!mi*G6J-NFFuCx4N^09bxW?t{Ms6+xVz z&-k(S)-N^lvw4NRYg?kwhOJmcaTNn~JU3LxkGz21;;I{;=Mxf2zy@!Dhc(CsvNY3Z zw1DCIiH+2_fqQ)bg54(@;SU;j=J;#1r-8WIYqj5Nof(rbFOBcYQfh-y`(T6AT8tim z^OdlzdIXR^HI(IgSg`QjyLZpp1x!V{0M!cMP>H&s<}+s;GXd?n03 zFX}g;P;#7oJVWI@J$hnp-E0olwD%sKozgDyO8Z-_I*l(P4XL5WSR+^rIeDd`6a`G)z&nVFfvl~Wam2oPw7E_e$; zWv`QLLaJOwY0?QfIXM;$0p$1+{62Ft^esmhm-7c$Snxpjev*wk*en+F9KWmUOmG8db<5+lq3I8ImzZRcU>evf-gJ8G26Td18O3_)q$eZ zO01E5{QNPYlr3vG^sw2QWQozu;z2$>zG!*pZk?XKe6R$&_3OZcom>?EM zWaHj+Q-FHPB4JrJwoE`MzQ$l+4{D|k z#9d(OXLKHh?UA9NL(%r}F$QrqX6ARu0Q4(LEGuv-Y$wrwGyj}mb>yePH46D4 z+@K7Bz3&|!HlMi{q4MsAcq_w$vhqkq!-F?RI9=r;bJBr*=4OBC^)*#$ZM5&nVO9fw zfBzEO`l`2GP@B75nTnv`$BB1jbWbs=AF1{God(k7z>o%ziV9x? z?3ti0`w!2ml;Rvw@S!rogL^bvmp4J!Wf}M%)$Hp^826vF-R51ZCFI0mkkkbZ4)OvJ zz=$6B7FQj0UdHLystt$nnFK%;TRHpvv33Pi(2c;&Oriu;j)N{n;8#Z;n4O^iM4)p6ow|Yo z_{F`u2eHZKZ#pxj7WgxQWxA*^C$^@nY6vup9DRKiK-1^Qks~cYvN!;0U?_wDax1Un z!VsDvq%H=HKzy$B@1Fq{+Y|IW0#-Z3@W8<$#{Gs{!3KzGY5@KKb~)w`Jp9*U0p=(Rb{0j@VLClb$uik!*7@saoJNwho@V4?cKk* zK<5ey#+WmH0b#9F3iLOiyfkWnk&zMb2r4|17RT&&`_iWE=^OU=f~*JL5gg4&T))7R z4*8G!nY)jEnD-Fz8S|)aEilPq*m>HlJHz=|($b2?zX@d*jsb>sRXp&!02L2V>TGr}4D zqNPdN(kJttN_Um!SzCE%Omq!(6Ohina20%}3JX(n=kb5aqkp2+=b6KwROMt$I}IS| zHy0xyNoH%p2K3e0*7$w51vVQut@5H|2;Z6i3l;zA5&uBc&og}GzJ-U7uIGxoTbn9CUp>nd zKPj@)u0IV@13UnO!IY69UQQ<5Nn@T(*j{bOPjQtPwmXk=B(i;m7 zw-0uI5)UfihV&2LfYy#$THLdOD%f4$-y$g){{8c1-#?Va^8(c;8xK3bF}X-rh@Pac zU!`*a#lEtwEdK#=4_9)i9aw{bBz`ND#;(h&G3J_E&mS(1TthoCgW9=@$OGlg=%q0N z^PkK3@AcOeF}UEnw_m0|gUA$*fRN_T!INmSU*q@>H7hKJE>-HW-|4Pk`Bw)PhF#{b zhx`8?-~Qbfps+{E?r4wW_BHo_)NEW$!RS<4We*WPR8<{5*nGr=6mHytr%_g#-nAhY ztS4iE_)rMEw_2llYsUGTxBZ|Ax$$r(#;cB29zVvoxH^alQxs46Vm(2>63nx4% zK@~Z4&-}^?W-I_w^ByDy5b{5I1aGIx5V-$JTK*}YpJ!rpH2>!%kv}KVyRe+qqqjJQ z+(DtS7p7@jJ?qhsbZ%(iI$iI^yEM8*a8@`(!C-CwOdmW^qV>#ahY~?@Eo^VvBls*t zzF>!G6{*Q7s~WU{q9alC>6JACuSil+#G~3}q(&c+}2j9cFI~Q1h-n?36 zQ<>pI2d^vGYtbl3%FdmV)V{$L6JrfpV-SihoE6-Um}&`hTYxcnyP8UeQu^AMP5rz0 zlMEGKo6%aw(hf}bRl`EnA%4RzptS?}5yy^%KlM4M`d3@{WicH$HY#vU+;+zUa?b`x zxDzMhHa9mN^nA{tXe+t;ctcNSpD)0m-OGWJrm|*#5rmTutDoOb3JwrY8J+T8!$?(0U5b0Cl}2LK$t$rTbISt*A34 z8i%{yN@LWFt--WFd9}vz^2%o(%H6Z)$lb1pE^G?*L)j0lt@S|Xo?I`yq8N0LizA6s z>`KeKo5ivGT~8|APB(6Uk9Kb4L^u$aM8<|skR!HqB^RY19?|MoMNI4bZOMM58!t4G z8laDF-We?_X(vd2hHibpnZAL;;T9tlVlI_32ZHm4xRE2xYC*sT3&8hDpFew2A0?c? z=t7iV2$xU|-Yf}Mcy@^ixFvjwxm^rk$d)z_zrE7deQ^8_2lh8nnsz=!ww0NMtz`lm3=TJVu&%e+R6$b$ z_%z@We#(*F)7qY$(Vqskhhh9(D(`V8$^4yHl_o!f*jh6Rl1WlWAj{=A#LAZgH#{#^~~4vDm+>!i^Ba+o=K|_Mm~T z{BSYdtMfQRsdN%MVu97~&^))b9VUDPgwPT9~@sb0vY@^pn&mPfPd!O|DP;)md=dpSA6-A_gFnxG32uD6`j&cw;%ln D7Q03* literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..365dd24050e20187a89ab2ee20a016498ac969ee GIT binary patch literal 12082 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png new file mode 100644 index 0000000000000000000000000000000000000000..b329b800bf6ec714b33fc8df0dc48c5d0d588222 GIT binary patch literal 13269 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[ + StreamMessageAction( + title: const Text('Reply'), + leading: const StreamSvgIcon(icon: StreamSvgIcons.reply), + action: QuotedReply(message: message), + ), + StreamMessageAction( + title: const Text('Thread Reply'), + leading: const StreamSvgIcon(icon: StreamSvgIcons.threadReply), + action: ThreadReply(message: message), + ), + StreamMessageAction( + title: const Text('Copy Message'), + leading: const StreamSvgIcon(icon: StreamSvgIcons.copy), + action: CopyMessage(message: message), + ), + StreamMessageAction( + isDestructive: true, + title: const Text('Delete Message'), + leading: const StreamSvgIcon(icon: StreamSvgIcons.delete), + action: DeleteMessage(message: message), + ), + ]; + + group('StreamMessageActionsModal', () { + testWidgets('renders message widget and actions correctly', (tester) async { + await tester.pumpWidget( + _wrapWithMaterialApp( + StreamMessageActionsModal( + message: message, + messageActions: messageActions, + messageWidget: const Text('Message Widget'), + ), + ), + ); + + // Use a longer timeout to ensure everything is rendered + await tester.pumpAndSettle(const Duration(seconds: 1)); + expect(find.text('Message Widget'), findsOneWidget); + expect(find.text('Reply'), findsOneWidget); + expect(find.text('Thread Reply'), findsOneWidget); + expect(find.text('Copy Message'), findsOneWidget); + expect(find.text('Delete Message'), findsOneWidget); + }); + + testWidgets('renders with reaction picker when enabled', (tester) async { + await tester.pumpWidget( + _wrapWithMaterialApp( + StreamMessageActionsModal( + message: message, + messageActions: messageActions, + messageWidget: const Text('Message Widget'), + showReactionPicker: true, + ), + ), + ); + + // Use a longer timeout to ensure everything is rendered + await tester.pumpAndSettle(const Duration(seconds: 1)); + expect(find.byType(StreamReactionPicker), findsOneWidget); + }); + + testWidgets( + 'calls onActionTap with SelectReaction when reaction is selected', + (tester) async { + MessageAction? messageAction; + + // Define custom reaction icons for testing + final testReactionIcons = [ + StreamReactionIcon( + type: 'like', + builder: (context, isActive, size) => const Icon(Icons.thumb_up), + ), + StreamReactionIcon( + type: 'love', + builder: (context, isActive, size) => const Icon(Icons.favorite), + ), + ]; + + await tester.pumpWidget( + _wrapWithMaterialApp( + StreamMessageActionsModal( + message: message, + messageActions: messageActions, + messageWidget: const Text('Message Widget'), + showReactionPicker: true, + onActionTap: (action) => messageAction = action, + ), + reactionIcons: testReactionIcons, + ), + ); + + // Use a longer timeout to ensure everything is rendered + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Verify reaction picker is shown + expect(find.byType(StreamReactionPicker), findsOneWidget); + + // Find and tap the first reaction (like) + final reactionIconFinder = find.byIcon(Icons.thumb_up); + expect(reactionIconFinder, findsOneWidget); + await tester.tap(reactionIconFinder); + await tester.pumpAndSettle(); + + expect(messageAction, isA()); + // Verify callback was called with correct reaction type + expect((messageAction! as SelectReaction).reaction.type, 'like'); + + // Find and tap the second reaction (love) + final loveIconFinder = find.byIcon(Icons.favorite); + expect(loveIconFinder, findsOneWidget); + await tester.tap(loveIconFinder); + await tester.pumpAndSettle(); + + expect(messageAction, isA()); + // Verify callback was called with correct reaction type + expect((messageAction! as SelectReaction).reaction.type, 'love'); + }, + ); + }); + + group('StreamMessageActionsModal Golden Tests', () { + Widget buildMessageWidget({bool reverse = false}) { + return Builder( + builder: (context) { + final theme = StreamChatTheme.of(context); + final messageTheme = theme.getMessageTheme(reverse: reverse); + + return Align( + alignment: reverse ? Alignment.centerRight : Alignment.centerLeft, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 16, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14), + color: messageTheme.messageBackgroundColor, + ), + child: Text( + message.text ?? '', + style: messageTheme.messageTextStyle, + ), + ), + ); + }, + ); + } + + for (final brightness in Brightness.values) { + final theme = brightness.name; + + goldenTest( + 'StreamMessageActionsModal in $theme theme', + fileName: 'stream_message_actions_modal_$theme', + constraints: const BoxConstraints(maxWidth: 400, maxHeight: 600), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + StreamMessageActionsModal( + message: message, + messageActions: messageActions, + messageWidget: buildMessageWidget(), + ), + ), + ); + + goldenTest( + 'StreamMessageActionsModal with reaction picker in $theme theme', + fileName: 'stream_message_actions_modal_with_reactions_$theme', + constraints: const BoxConstraints(maxWidth: 400, maxHeight: 600), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + StreamMessageActionsModal( + message: message, + messageActions: messageActions, + messageWidget: buildMessageWidget(), + showReactionPicker: true, + ), + ), + ); + + goldenTest( + 'StreamMessageActionsModal reversed in $theme theme', + fileName: 'stream_message_actions_modal_reversed_$theme', + constraints: const BoxConstraints(maxWidth: 400, maxHeight: 600), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + StreamMessageActionsModal( + message: message, + messageActions: messageActions, + messageWidget: buildMessageWidget(reverse: true), + reverse: true, + ), + ), + ); + + goldenTest( + 'StreamMessageActionsModal reversed with reaction picker in $theme theme', + fileName: 'stream_message_actions_modal_reversed_with_reactions_$theme', + constraints: const BoxConstraints(maxWidth: 400, maxHeight: 600), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + StreamMessageActionsModal( + message: message, + messageActions: messageActions, + messageWidget: buildMessageWidget(reverse: true), + showReactionPicker: true, + reverse: true, + ), + ), + ); + } + }); +} + +Widget _wrapWithMaterialApp( + Widget child, { + Brightness? brightness, + List? reactionIcons, +}) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChatConfiguration( + data: StreamChatConfigurationData(reactionIcons: reactionIcons), + child: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: ColoredBox( + color: theme.colorTheme.overlay, + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), + ), + ); + }), + ), + ), + ); +} diff --git a/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart new file mode 100644 index 0000000000..c153889075 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart @@ -0,0 +1,277 @@ +import 'package:alchemist/alchemist.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_card.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import '../mocks.dart'; + +void main() { + final message = Message( + id: 'test-message', + text: 'This is a test message', + createdAt: DateTime.now(), + user: User(id: 'test-user', name: 'Test User'), + latestReactions: [ + Reaction( + type: 'love', + messageId: 'test-message', + user: User(id: 'user-1', name: 'User 1'), + createdAt: DateTime.now(), + ), + Reaction( + type: 'like', + messageId: 'test-message', + user: User(id: 'user-2', name: 'User 2'), + createdAt: DateTime.now(), + ), + ], + reactionGroups: { + 'love': ReactionGroup(count: 1, sumScores: 1), + 'like': ReactionGroup(count: 1, sumScores: 1), + }, + ); + + late MockClient mockClient; + + setUp(() { + mockClient = MockClient(); + + final mockClientState = MockClientState(); + when(() => mockClient.state).thenReturn(mockClientState); + + // Mock the current user for the message reactions test + final currentUser = OwnUser(id: 'current-user', name: 'Current User'); + when(() => mockClientState.currentUser).thenReturn(currentUser); + }); + + tearDown(() => reset(mockClient)); + + group('StreamMessageReactionsModal', () { + testWidgets( + 'renders message widget and reactions correctly', + (tester) async { + await tester.pumpWidget( + _wrapWithMaterialApp( + client: mockClient, + StreamMessageReactionsModal( + message: message, + messageWidget: const Text('Message Widget'), + ), + ), + ); + + // Use a longer timeout to ensure everything is rendered + await tester.pumpAndSettle(const Duration(seconds: 2)); + expect(find.text('Message Widget'), findsOneWidget); + // Check for reaction picker + expect(find.byType(StreamReactionPicker), findsOneWidget); + // Check for reaction details + expect(find.byType(ReactionsCard), findsOneWidget); + }, + ); + + testWidgets( + 'calls onUserAvatarTap when user avatar is tapped', + (tester) async { + User? tappedUser; + + // Create just the StreamUserAvatar directly + await tester.pumpWidget( + _wrapWithMaterialApp( + client: mockClient, + StreamMessageReactionsModal( + message: message, + messageWidget: const Text('Message Widget'), + onUserAvatarTap: (user) { + tappedUser = user; + }, + ), + ), + ); + + await tester.pumpAndSettle(); + + final avatar = find.descendant( + of: find.byType(ReactionsCard), + matching: find.byType(StreamUserAvatar), + ); + + // Verify the avatar is rendered + expect(avatar, findsNWidgets(2)); + + // Tap on the first avatar directly + await tester.tap(avatar.first); + await tester.pumpAndSettle(); + + // Verify the callback was called + expect(tappedUser, isNotNull); + }, + ); + + testWidgets( + 'calls onReactionPicked with SelectReaction when reaction is selected', + (tester) async { + MessageAction? messageAction; + + // Define custom reaction icons for testing + final testReactionIcons = [ + StreamReactionIcon( + type: 'like', + builder: (context, isActive, size) => const Icon(Icons.thumb_up), + ), + StreamReactionIcon( + type: 'love', + builder: (context, isActive, size) => const Icon(Icons.favorite), + ), + StreamReactionIcon( + type: 'camera', + builder: (context, isActive, size) => const Icon(Icons.camera), + ), + StreamReactionIcon( + type: 'call', + builder: (context, isActive, size) => const Icon(Icons.call), + ), + ]; + + await tester.pumpWidget( + _wrapWithMaterialApp( + client: mockClient, + reactionIcons: testReactionIcons, + StreamMessageReactionsModal( + message: message, + messageWidget: const Text('Message Widget'), + onReactionPicked: (action) => messageAction = action, + ), + ), + ); + + // Use a longer timeout to ensure everything is rendered + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Verify reaction picker is shown + expect(find.byType(StreamReactionPicker), findsOneWidget); + + // Find and tap the camera reaction (camera) + final reactionIconFinder = find.byIcon(Icons.camera); + expect(reactionIconFinder, findsOneWidget); + await tester.tap(reactionIconFinder); + await tester.pumpAndSettle(); + + expect(messageAction, isA()); + // Verify callback was called with correct reaction type + expect((messageAction! as SelectReaction).reaction.type, 'camera'); + + // Find and tap the call reaction (call) + final loveIconFinder = find.byIcon(Icons.call); + expect(loveIconFinder, findsOneWidget); + await tester.tap(loveIconFinder); + await tester.pumpAndSettle(); + + expect(messageAction, isA()); + // Verify callback was called with correct reaction type + expect((messageAction! as SelectReaction).reaction.type, 'call'); + }, + ); + }); + + group('StreamMessageReactionsModal Golden Tests', () { + Widget buildMessageWidget({bool reverse = false}) { + return Builder( + builder: (context) { + final theme = StreamChatTheme.of(context); + final messageTheme = theme.getMessageTheme(reverse: reverse); + + return Align( + alignment: reverse ? Alignment.centerRight : Alignment.centerLeft, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 16, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14), + color: messageTheme.messageBackgroundColor, + ), + child: Text( + message.text ?? '', + style: messageTheme.messageTextStyle, + ), + ), + ); + }, + ); + } + + for (final brightness in Brightness.values) { + final theme = brightness.name; + + goldenTest( + 'StreamMessageReactionsModal in $theme theme', + fileName: 'stream_message_reactions_modal_$theme', + constraints: const BoxConstraints(maxWidth: 400, maxHeight: 600), + builder: () => _wrapWithMaterialApp( + client: mockClient, + brightness: brightness, + StreamMessageReactionsModal( + message: message, + messageWidget: buildMessageWidget(), + onReactionPicked: (_) {}, + ), + ), + ); + + goldenTest( + 'StreamMessageReactionsModal reversed in $theme theme', + fileName: 'stream_message_reactions_modal_reversed_$theme', + constraints: const BoxConstraints(maxWidth: 400, maxHeight: 600), + builder: () => _wrapWithMaterialApp( + client: mockClient, + brightness: brightness, + StreamMessageReactionsModal( + message: message, + messageWidget: buildMessageWidget(reverse: true), + reverse: true, + onReactionPicked: (_) {}, + ), + ), + ); + } + }); +} + +Widget _wrapWithMaterialApp( + Widget child, { + required StreamChatClient client, + Brightness? brightness, + List? reactionIcons, +}) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChat( + client: client, + // Mock the connectivity stream to always return wifi. + connectivityStream: Stream.value([ConnectivityResult.wifi]), + child: StreamChatConfiguration( + data: StreamChatConfigurationData(reactionIcons: reactionIcons), + child: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: ColoredBox( + color: theme.colorTheme.overlay, + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), + ), + ); + }), + ), + ), + ), + ); +} diff --git a/packages/stream_chat_flutter/test/src/message_modal/moderated_message_actions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_modal/moderated_message_actions_modal_test.dart new file mode 100644 index 0000000000..59e76cf347 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_modal/moderated_message_actions_modal_test.dart @@ -0,0 +1,139 @@ +// ignore_for_file: lines_longer_than_80_chars + +import 'package:alchemist/alchemist.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() { + final message = Message( + id: 'test-message', + type: MessageType.error, + text: 'This is a test message', + createdAt: DateTime.now(), + user: User(id: 'test-user', name: 'Test User'), + moderation: const Moderation( + action: ModerationAction.bounce, + originalText: 'This is a test message with flagged content', + ), + ); + + final messageActions = [ + StreamMessageAction( + title: const Text('Send Anyway'), + leading: const StreamSvgIcon(icon: StreamSvgIcons.send), + action: ResendMessage(message: message), + ), + StreamMessageAction( + title: const Text('Edit Message'), + leading: const StreamSvgIcon(icon: StreamSvgIcons.edit), + action: EditMessage(message: message), + ), + StreamMessageAction( + isDestructive: true, + title: const Text('Delete Message'), + leading: const StreamSvgIcon(icon: StreamSvgIcons.delete), + action: HardDeleteMessage(message: message), + ), + ]; + + group('ModeratedMessageActionsModal', () { + testWidgets('renders title, content and actions correctly', (tester) async { + await tester.pumpWidget( + _wrapWithMaterialApp( + ModeratedMessageActionsModal( + message: message, + messageActions: messageActions, + ), + ), + ); + + // Use a longer timeout to ensure everything is rendered + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Check for icon, title and content + expect(find.byType(StreamSvgIcon), findsWidgets); + expect(find.byType(Text), findsWidgets); + + // Check for actions + expect(find.text('Send Anyway'), findsOneWidget); + expect(find.text('Edit Message'), findsOneWidget); + expect(find.text('Delete Message'), findsOneWidget); + }); + + testWidgets('action buttons call the correct callbacks', (tester) async { + MessageAction? messageAction; + + await tester.pumpWidget( + _wrapWithMaterialApp( + ModeratedMessageActionsModal( + message: message, + messageActions: messageActions, + onActionTap: (action) => messageAction = action, + ), + ), + ); + + await tester.pumpAndSettle(); + + // Tap on Send Anyway button + await tester.tap(find.text('Send Anyway')); + await tester.pumpAndSettle(); + expect(messageAction, isA()); + + // Tap on Edit Message button + await tester.tap(find.text('Edit Message')); + await tester.pumpAndSettle(); + expect(messageAction, isA()); + + // Tap on Delete Message button + await tester.tap(find.text('Delete Message')); + await tester.pumpAndSettle(); + expect(messageAction, isA()); + }); + }); + + group('ModeratedMessageActionsModal Golden Tests', () { + for (final brightness in Brightness.values) { + final theme = brightness.name; + + goldenTest( + 'ModeratedMessageActionsModal in $theme theme', + fileName: 'moderated_message_actions_modal_$theme', + constraints: const BoxConstraints(maxWidth: 400, maxHeight: 350), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + ModeratedMessageActionsModal( + message: message, + messageActions: messageActions, + ), + ), + ); + } + }); +} + +Widget _wrapWithMaterialApp( + Widget child, { + Brightness? brightness, +}) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: ColoredBox( + color: theme.colorTheme.overlay, + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), + ), + ); + }), + ), + ); +} diff --git a/packages/stream_chat_flutter/test/src/message_reactions_modal/message_reactions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_reactions_modal/message_reactions_modal_test.dart deleted file mode 100644 index 8cf78680b3..0000000000 --- a/packages/stream_chat_flutter/test/src/message_reactions_modal/message_reactions_modal_test.dart +++ /dev/null @@ -1,121 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -import '../mocks.dart'; - -void main() { - testWidgets( - 'control test', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - final themeData = ThemeData(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - final message = Message( - id: 'test', - text: 'test message', - user: User( - id: 'test-user', - ), - ); - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: StreamChannel( - channel: channel, - child: StreamMessageReactionsModal( - messageWidget: const Text( - 'test', - key: Key('MessageWidget'), - ), - message: message, - messageTheme: streamTheme.ownMessageTheme, - ), - ), - ), - ), - ); - - await tester.pump(const Duration(milliseconds: 1000)); - - expect(find.byType(StreamReactionBubble), findsNothing); - - expect(find.byType(StreamUserAvatar), findsNothing); - }, - ); - - testWidgets( - 'it should apply passed parameters', - (WidgetTester tester) async { - final client = MockClient(); - final clientState = MockClientState(); - final channel = MockChannel(); - final themeData = ThemeData(); - - when(() => client.state).thenReturn(clientState); - when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); - - final streamTheme = StreamChatThemeData.fromTheme(themeData); - - final message = Message( - id: 'test', - text: 'test message', - user: User( - id: 'test-user', - ), - latestReactions: [ - Reaction( - messageId: 'test', - user: User(id: 'testid'), - type: 'test', - ), - ], - ); - - // ignore: prefer_function_declarations_over_variables - final onUserAvatarTap = (u) => print('ok'); - - await tester.pumpWidget( - MaterialApp( - theme: themeData, - home: StreamChat( - client: client, - streamChatThemeData: streamTheme, - child: StreamChannel( - channel: channel, - child: StreamMessageReactionsModal( - messageWidget: const Text( - 'test', - key: Key('MessageWidget'), - ), - message: message, - messageTheme: streamTheme.ownMessageTheme, - reverse: true, - showReactionPicker: false, - onUserAvatarTap: onUserAvatarTap, - ), - ), - ), - ), - ); - - await tester.pump(const Duration(milliseconds: 1000)); - - expect(find.byKey(const Key('MessageWidget')), findsOneWidget); - - expect(find.byType(StreamReactionBubble), findsOneWidget); - expect(find.byType(StreamUserAvatar), findsOneWidget); - }, - ); -} diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ec2744779b8a227e57483b6ae583e2cf284c7656 GIT binary patch literal 670 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq}`x)5S3)qw(#Gz5c?5636#HUFUME=!(|?wFPQC6RtUaROR6_`f0SH@Un%q zgqq=-f6RSqDtyO|9QE`pxpZWqp&^S4uhT`BiPIOcM)hYmE>E33=bByt@wSN^^aT2PUS;)1QXwN7?iuruvR)FEBLIBqu3oRd@+>u z`!SxFUUOwhK1IRIhNl)gKC3n#yqT|IF`J=bLRkCj+_gI@4fvd|8|1A`x}){TQLQ^9 z&((8%L)Y;wf7>7JxO*|~vg5@x!ms=n-hxbNHF+vj3(I&-zT8O-^%2yOkvyR*PQ zSUK_5s6xJ}H@XD^P9tKYJrW#7s38t)!ly05!#{_&Z$f##(~FZWr@EAW4t x`{nCq#vS`=5C7*j{oVnIA#4#BTztr$k;D5+u5Q_GF<=^F@O1TaS?83{1OQd&Il=${ literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.png new file mode 100644 index 0000000000000000000000000000000000000000..d50722b8f219e97b3987569cfa6b86d21035c25c GIT binary patch literal 628 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq_ZR)5S3)qw(#Gv))qzMUKrcc6VK>b8%*wsR@s7Z-$VVQp$pemK_&EXO}Hv zSvuPxR+ObqWrmQ}S+$ffV+F6-W=`A(TOAea8Wg_jpZKx0Adh=4&n3x=#qJixb*~S9 zwzIFef7(|6?VC4IPXwMV;!cqkoz}SA6prJS2Js9wPjYbW#zGQar3u*D@)w(qb%9abURw%zwZM#hAUr0LJF^Y>KA>S zeeKvHkGgp_{~8YpoH-z|VSj&0zWAG8w>B0p`>VQQY42{S{TpHDsiLn}R;fzchPx zO=L9ZzBSH2TKC#*)A$sZeA?@vp3g(AeH#i?-n&ar?Pko|-eBom6KCgh-+IBB z*NbNEe%iR|-N8MQR=dpSw=GJV@h@;f^I@&l%ekGavJ>w0GlzQ{^G~mQC^?Uz^^l(S z&UpTl@(t-vgbVK0fAUe_IN$DZOHyysX8!5FA4p2E-~Ipp%QE*~gJyaE?_vfIQfz(N zV`CcTb}_KBE_nX-+_!s^Pwe{OI=Og%1ycBV^ zzN1NkjSdXI|H=W;<(DF_zs~YpZ!UIx%hDjusa{Xt*UmZPuNYGi{pO$rPdY@85s;{Xgeqo!$I}nNmE5 z6GA)J8Zc;dHC65HE3o)eaBf>}iIuDjAN#b@8{EteDngEH!X#qE5+U%Idj7PZ17 z^0d>bbLQ60+L1O(jgS9+vW?v1Cr>2amQ_EB(VBYb*Dvo^SzivFO%rx^mtS`7$m2qu zb{=!{-j&5aYvj7S{WV`-tUo-}>*>LnQER^~c(Z*C_o6U+1@V1*b0?*4jndtuBVF|H zV1mQ6qc!os6f5^&Bn>H`8-u`#({Xf`o2+zyY-O!m*0O^7Vlc8JiVHG z|NZlu`RWrHUVN>xu+?2~`>kILKU?#OwBip{d-triQ08IiF%;=`jfs!{`^9FWM?(2` z(~!{8MQz20%)VC1E)C-R{F!Upwzxv;@Bg@tx603+x%&~mI5I9i6wi3iY^uegV7-;V P#Khp~>gTe~DWM4fS-~X$ literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..78280c1832e95af234fb2ab678ca9d45abaee96e GIT binary patch literal 2741 zcmdUxiC0s{9>;G$fdbN&TCuFQvKd(v6Ila@%B~$FEv zT@iwyJuc3tydVg64}6Cx$bokqGb|Z&ummqB2Z%DP$pb&T5*%E76u^_F5ON!W6oXw( zo$$ez3E%(Y;VseWU-3(=dkt&#vJZSd6Ef)d7^#kV##2?p^%P7k5^gXhb{tmB``P!u zw<|n7!wCH;*YhaO+n(f~34g2D((;c6AwKYfQd&3av|ufcrITG@UR1{3_`2>4SAa62 zSC+|AEFT+DPS;Pd(G!`90Sbjft# z$h>4J733+ zGB+1?6^ZwxDcn;>cUj}!wMG`_f#He@?XC4U9;*cUCg_Ap_t8PJRi4gtI=wTF`)kZp z=WIkd4u=C}Kdm%JAleDt@lJV~oFg`6X||QaWtP>;Jv-fSoF$9J;=OIUY=!^)2eu1e zm6-_}8XDrL;i&BL>4hz+M6fVgEnZ8sB4=goMj{Y~`;}b_#KOti?d|J~OGi`aSR@k3 z={HdQ#*g32%!KOC35CMQ-oE&^_;t~-PgGQ*coBVG@2cDcgdK+84DV3U|9@o}7 z&0NF3;ZCPZrWAc!yJh87ifnFduGf?154T0KDbZRxqfR;lPmS38L&={%oB(DCZ4RJK zHqmH7SSq{qgQ4Os88NqKXFDj%;Y5Lt;oc&5eW65MLxZhp>XMLjCI*c#6{&tjx}$11=cTjve!&n zylk}dZMVO0kr-{@FsFQNVrW1_bTn}6=-61n$CdWTW6fi{^=GsuPz^(HRw^TOL=_+`E$cxDNM!PvW5Gi-45Gp)efx<({dIgnrxU z4Lc`^ukfIK#Q6GpB17h{yXY6vkJjR)T8gT2q4Ko54ZXfnBomm&4s2b#w%{xw!>mu@vX%jWjGs6*@e;cDUTy zfc(tFB)GdV(Fzl91Y0FkDUlo*+!e5oHEMNQR*A2cR5%T;7-jYk`TaPlSQx$KUelX` z8b0zRSYTa-i3N_h?|dqJq=Ll`z9Ag^E4yu)z_eYiaVwspRx>v7X z?}pFJtl+`nu@lbhU6wGHC6Q54?w2oLrm%07J1Koa-gm88@B7wn;eAJfSRX$d79Nh{ zjn&}foe%S7`m)7$DuzPLN*WS_Es4wai*sk&1WiV60HOTlWxoU8y%q`Btf?t-)N#`2 z=xBp{gKoJ+TyMqKYoA_yk7>X5Vj5kuur^``W&$`=>g($xEG+y*R_8FgUPbDbpB41$ z+!*J*sbx35Xit?;C|G*u+@BwQ1>B@iC}-p)#l^)U5H!DZd_;GD%$=K`XH8C$ z03K+^4TT{A=z-z3K&{)_nwn{cl3FnS{+=El`9{pKg@rnO0|U2d)4hs-cl^c0@xj60 zC>YvHTYoAnU-vi(mh>PrU~}$aY|&5{5(F(L=NmoMoQ5o`3pXJcRuv!&P&>;0wx8U; z*P~tp7RvZuW*2nf76gO#|7;IIjtbxXj}Lw7(U+WPO%^G<0#{GS<@DK86o(5p{|i{) BAJYH; literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f0c98372ce521fcc2183b6fa5f0c0c98bf22a5 GIT binary patch literal 3049 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..45484fa7732df3cd19ac506aa4392c5d77a02953 GIT binary patch literal 2843 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..0fcbd270b57c17c55e7d2a1741fb27f925bcb62a GIT binary patch literal 3460 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png new file mode 100644 index 0000000000000000000000000000000000000000..f6f59b90000d2bff1b2ced41cc9a1f8bc8d504a9 GIT binary patch literal 3413 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 jNYXq2_!(u3guCf0DartKI literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..757ebb5a0ce36b762089a757501ee8c736ef2913 GIT binary patch literal 3536 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png new file mode 100644 index 0000000000000000000000000000000000000000..cac18319fa88f8dd8484b6ef8c6c7e9a28c207eb GIT binary patch literal 3451 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_icon_list_test.dart b/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_icon_list_test.dart new file mode 100644 index 0000000000..511fc1b858 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_icon_list_test.dart @@ -0,0 +1,387 @@ +import 'package:alchemist/alchemist.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/src/message_widget/reactions/reaction_picker_icon_list.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() { + final reactionIcons = [ + StreamReactionIcon( + type: 'love', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.loveReaction, + size: iconSize, + color: isSelected ? Colors.red : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'thumbsUp', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.thumbsUpReaction, + size: iconSize, + color: isSelected ? Colors.blue : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'thumbsDown', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.thumbsDownReaction, + size: iconSize, + color: isSelected ? Colors.orange : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'lol', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.lolReaction, + size: iconSize, + color: isSelected ? Colors.amber : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'wut', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.wutReaction, + size: iconSize, + color: isSelected ? Colors.purple : Colors.grey.shade700, + ), + ), + ]; + + group('ReactionIconButton', () { + testWidgets( + 'renders correctly with selected state', + (WidgetTester tester) async { + await tester.pumpWidget( + _wrapWithMaterialApp( + ReactionIconButton( + icon: reactionIcons.first, + isSelected: true, + onPressed: () {}, + ), + ), + ); + + expect(find.byType(ReactionIconButton), findsOneWidget); + expect(find.byType(IconButton), findsOneWidget); + }, + ); + + testWidgets( + 'triggers callback when pressed', + (WidgetTester tester) async { + var callbackTriggered = false; + + await tester.pumpWidget( + _wrapWithMaterialApp( + ReactionIconButton( + icon: reactionIcons.first, + isSelected: false, + onPressed: () { + callbackTriggered = true; + }, + ), + ), + ); + + await tester.tap(find.byType(IconButton)); + await tester.pump(); + + expect(callbackTriggered, isTrue); + }, + ); + + group('Golden tests', () { + for (final brightness in [Brightness.light, Brightness.dark]) { + final theme = brightness.name; + + goldenTest( + 'ReactionIconButton unselected in $theme theme', + fileName: 'reaction_icon_button_unselected_$theme', + constraints: const BoxConstraints.tightFor(width: 60, height: 60), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + ReactionIconButton( + icon: reactionIcons.first, + isSelected: false, + onPressed: () {}, + ), + ), + ); + + goldenTest( + 'ReactionIconButton selected in $theme theme', + fileName: 'reaction_icon_button_selected_$theme', + constraints: const BoxConstraints.tightFor(width: 60, height: 60), + builder: () => _wrapWithMaterialApp( + brightness: brightness, + ReactionIconButton( + icon: reactionIcons.first, + isSelected: true, + onPressed: () {}, + ), + ), + ); + } + }); + }); + + group('ReactionPickerIconList', () { + testWidgets( + 'renders all reaction icons', + (WidgetTester tester) async { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + await tester.pumpWidget( + _wrapWithMaterialApp( + ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ), + ); + + // Wait for animations to complete + await tester.pumpAndSettle(); + + // Should find same number of IconButtons as reactionIcons + expect(find.byType(IconButton), findsNWidgets(reactionIcons.length)); + }, + ); + + testWidgets( + 'triggers onReactionPicked when a reaction icon is tapped', + (WidgetTester tester) async { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + Reaction? pickedReaction; + + await tester.pumpWidget( + _wrapWithMaterialApp( + ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (reaction) { + pickedReaction = reaction; + }, + ), + ), + ); + + // Wait for animations to complete + await tester.pumpAndSettle(); + + // Tap the first reaction icon + await tester.tap(find.byType(IconButton).first); + await tester.pump(); + + // Verify callback was triggered with correct reaction type + expect(pickedReaction, isNotNull); + expect(pickedReaction!.type, 'love'); + }, + ); + + testWidgets( + 'shows reaction icons with animation', + (WidgetTester tester) async { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + await tester.pumpWidget( + _wrapWithMaterialApp( + ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ), + ); + + // Initially the animations should be starting + await tester.pump(); + + // After animation completes + await tester.pumpAndSettle(); + + // Should have all reactions visible + expect( + find.byType(ReactionIconButton), + findsNWidgets(reactionIcons.length), + ); + }, + ); + + testWidgets( + 'properly handles message with existing reactions', + (WidgetTester tester) async { + // Create a message with an existing reaction + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ownReactions: [ + Reaction( + type: 'love', + messageId: 'test-message', + userId: 'test-user', + ), + ], + ); + + await tester.pumpWidget( + _wrapWithMaterialApp( + Material( + child: ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ), + ), + ); + + // Wait for animations + await tester.pumpAndSettle(); + + // All reaction buttons should be rendered + expect( + find.byType(ReactionIconButton), + findsNWidgets(reactionIcons.length), + ); + }, + ); + + testWidgets( + 'updates when reactionIcons change', + (WidgetTester tester) async { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + // Build with initial set of reaction icons + await tester.pumpWidget( + _wrapWithMaterialApp( + ReactionPickerIconList( + message: message, + // Only first two reactions + reactionIcons: reactionIcons.sublist(0, 2), + onReactionPicked: (_) {}, + ), + ), + ); + + await tester.pumpAndSettle(); + expect(find.byType(IconButton), findsNWidgets(2)); + + // Rebuild with all reaction icons + await tester.pumpWidget( + _wrapWithMaterialApp( + ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, // All three reactions + onReactionPicked: (_) {}, + ), + ), + ); + + await tester.pumpAndSettle(); + expect(find.byType(IconButton), findsNWidgets(5)); + }, + ); + + group('Golden tests', () { + for (final brightness in [Brightness.light, Brightness.dark]) { + final theme = brightness.name; + + goldenTest( + 'ReactionPickerIconList in $theme theme', + fileName: 'reaction_picker_icon_list_$theme', + constraints: const BoxConstraints.tightFor(width: 400, height: 100), + builder: () { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + return _wrapWithMaterialApp( + brightness: brightness, + ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ); + }, + ); + + goldenTest( + 'ReactionPickerIconList with selected reaction in $theme theme', + fileName: 'reaction_picker_icon_list_selected_$theme', + constraints: const BoxConstraints.tightFor(width: 400, height: 100), + builder: () { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ownReactions: [ + Reaction( + type: 'love', + messageId: 'test-message', + userId: 'test-user', + ), + ], + ); + + return _wrapWithMaterialApp( + brightness: brightness, + ReactionPickerIconList( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ); + }, + ); + } + }); + }); +} + +Widget _wrapWithMaterialApp( + Widget child, { + Brightness? brightness, +}) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: Center( + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), + ), + ); + }), + ), + ); +} diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_test.dart b/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_test.dart new file mode 100644 index 0000000000..8447b10396 --- /dev/null +++ b/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_test.dart @@ -0,0 +1,198 @@ +import 'package:alchemist/alchemist.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat_flutter/src/message_widget/reactions/reaction_picker_icon_list.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() { + final reactionIcons = [ + StreamReactionIcon( + type: 'love', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.loveReaction, + size: iconSize, + color: isSelected ? Colors.red : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'thumbsUp', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.thumbsUpReaction, + size: iconSize, + color: isSelected ? Colors.blue : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'thumbsDown', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.thumbsDownReaction, + size: iconSize, + color: isSelected ? Colors.orange : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'lol', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.lolReaction, + size: iconSize, + color: isSelected ? Colors.amber : Colors.grey.shade700, + ), + ), + StreamReactionIcon( + type: 'wut', + builder: (context, isSelected, iconSize) => StreamSvgIcon( + icon: StreamSvgIcons.wutReaction, + size: iconSize, + color: isSelected ? Colors.purple : Colors.grey.shade700, + ), + ), + ]; + + testWidgets( + 'renders with correct message and reaction icons', + (WidgetTester tester) async { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + await tester.pumpWidget( + _wrapWithMaterialApp( + StreamReactionPicker( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ), + ); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Verify the widget renders with correct structure + expect(find.byType(StreamReactionPicker), findsOneWidget); + expect(find.byType(ReactionPickerIconList), findsOneWidget); + + // Verify the correct number of reaction icons + expect(find.byType(IconButton), findsNWidgets(reactionIcons.length)); + }, + ); + + testWidgets( + 'calls onReactionPicked when a reaction is selected', + (WidgetTester tester) async { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + Reaction? pickedReaction; + + await tester.pumpWidget( + _wrapWithMaterialApp( + StreamReactionPicker( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (reaction) { + pickedReaction = reaction; + }, + ), + ), + ); + + // Wait for animations to complete + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Tap the first reaction icon + await tester.tap(find.byType(IconButton).first); + await tester.pump(); + + // Verify the callback was called with the correct reaction + expect(pickedReaction, isNotNull); + // Updated to match first reaction type in the list + expect(pickedReaction!.type, 'love'); + }, + ); + + group('Golden tests', () { + for (final brightness in [Brightness.light, Brightness.dark]) { + final theme = brightness.name; + + goldenTest( + 'StreamReactionPicker in $theme theme', + fileName: 'stream_reaction_picker_$theme', + constraints: const BoxConstraints.tightFor(width: 400, height: 100), + builder: () { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ); + + return _wrapWithMaterialApp( + brightness: brightness, + StreamReactionPicker( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ); + }, + ); + + goldenTest( + 'StreamReactionPicker with selected reaction in $theme theme', + fileName: 'stream_reaction_picker_selected_$theme', + constraints: const BoxConstraints.tightFor(width: 400, height: 100), + builder: () { + final message = Message( + id: 'test-message', + text: 'Hello world', + user: User(id: 'test-user'), + ownReactions: [ + Reaction( + type: 'love', + messageId: 'test-message', + userId: 'test-user', + ), + ], + ); + + return _wrapWithMaterialApp( + brightness: brightness, + StreamReactionPicker( + message: message, + reactionIcons: reactionIcons, + onReactionPicked: (_) {}, + ), + ); + }, + ); + } + }); +} + +Widget _wrapWithMaterialApp( + Widget child, { + Brightness? brightness, +}) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: Center( + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), + ), + ); + }), + ), + ); +} diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart index ced86d92f1..1986b0f0fc 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for Catalan (`ca`). @@ -172,8 +174,7 @@ class StreamChatLocalizationsCa extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - "Si us plau, permet l'accés a les teves fotos" - '\ni vídeos per a que puguis compartir-los'; + "Si us plau, permet l'accés a les teves fotos i vídeos per a que puguis compartir-los"; @override String get allowGalleryAccessMessage => "Permet l'accés a la galeria"; @@ -183,8 +184,7 @@ class StreamChatLocalizationsCa extends GlobalStreamChatLocalizations { @override String get flagMessageQuestion => - "Vols enviar una còpia d'aquest missatge a un" - '\nmoderador per una major investigació?'; + "Vols enviar una còpia d'aquest missatge a un moderador per una major investigació?"; @override String get flagLabel => 'REPORTA'; @@ -207,7 +207,7 @@ class StreamChatLocalizationsCa extends GlobalStreamChatLocalizations { @override String get deleteMessageQuestion => - 'Estàs segur que vols esborrar aquest\nmissatge de forma permanent?'; + 'Estàs segur que vols esborrar aquest missatge de forma permanent?'; @override String get operationCouldNotBeCompletedText => @@ -449,8 +449,8 @@ class StreamChatLocalizationsCa extends GlobalStreamChatLocalizations { String unreadMessagesSeparatorText() => 'Missatges nous'; @override - String get enableFileAccessMessage => "Habilita l'accés als fitxers" - '\nper poder compartir-los amb amics'; + String get enableFileAccessMessage => + "Habilita l'accés als fitxers per poder compartir-los amb amics"; @override String get allowFileAccessMessage => "Permet l'accés als fitxers"; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart index 92d7643b5a..93b1e2c28b 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for German (`de`). @@ -162,8 +164,7 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - 'Bitte aktivieren Sie den Zugriff auf Ihre Fotos' - '\nund Videos, damit Sie sie mit Freunden teilen können.'; + 'Bitte aktivieren Sie den Zugriff auf Ihre Fotos und Videos, damit Sie sie mit Freunden teilen können.'; @override String get allowGalleryAccessMessage => 'Zugang zu Ihrer Galerie gewähren'; @@ -173,8 +174,7 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations { @override String get flagMessageQuestion => - 'Möchten Sie eine Kopie dieser Nachricht an einen' - '\nModerator für weitere Untersuchungen senden?'; + 'Möchten Sie eine Kopie dieser Nachricht an einen Moderator für weitere Untersuchungen senden?'; @override String get flagLabel => 'MELDEN'; @@ -443,8 +443,7 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations { @override String get enableFileAccessMessage => - 'Bitte aktivieren Sie den Zugriff auf Dateien,' - '\ndamit Sie sie mit Freunden teilen können.'; + 'Bitte aktivieren Sie den Zugriff auf Dateien, damit Sie sie mit Freunden teilen können.'; @override String get allowFileAccessMessage => 'Zugriff auf Dateien zulassen'; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart index a8e28a10e5..fdc85f41cc 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for English (`en`). @@ -169,8 +171,7 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - 'Please enable access to your photos' - '\nand videos so you can share them with friends.'; + 'Please enable access to your photos and videos so you can share them with friends.'; @override String get allowGalleryAccessMessage => 'Allow access to your gallery'; @@ -180,8 +181,7 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { @override String get flagMessageQuestion => - 'Do you want to send a copy of this message to a' - '\nmoderator for further investigation?'; + 'Do you want to send a copy of this message to a moderator for further investigation?'; @override String get flagLabel => 'FLAG'; @@ -204,7 +204,7 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { @override String get deleteMessageQuestion => - 'Are you sure you want to permanently delete this\nmessage?'; + 'Are you sure you want to permanently delete this message?'; @override String get operationCouldNotBeCompletedText => @@ -446,8 +446,8 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { String unreadMessagesSeparatorText() => 'New messages'; @override - String get enableFileAccessMessage => 'Please enable access to files' - '\nso you can share them with friends.'; + String get enableFileAccessMessage => + 'Please enable access to files so you can share them with friends.'; @override String get allowFileAccessMessage => 'Allow access to files'; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart index 887ebb58e9..887854d929 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for Spanish (`es`). @@ -173,8 +175,7 @@ class StreamChatLocalizationsEs extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - 'Por favor, permita el acceso a sus fotos' - '\ny vídeos para que pueda compartirlos con sus amigos.'; + 'Por favor, permita el acceso a sus fotos y vídeos para que pueda compartirlos con sus amigos.'; @override String get allowGalleryAccessMessage => 'Permitir el acceso a su galería'; @@ -184,8 +185,7 @@ class StreamChatLocalizationsEs extends GlobalStreamChatLocalizations { @override String get flagMessageQuestion => - '¿Quiere enviar una copia de este mensaje a un' - '\nmoderador para una mayor investigación?'; + '¿Quiere enviar una copia de este mensaje a un moderador para una mayor investigación?'; @override String get flagLabel => 'REPORTAR'; @@ -208,7 +208,7 @@ class StreamChatLocalizationsEs extends GlobalStreamChatLocalizations { @override String get deleteMessageQuestion => - '¿Estás seguro de que quieres borrar este\nmensaje de forma permanente?'; + '¿Estás seguro de que quieres borrar este mensaje de forma permanente?'; @override String get operationCouldNotBeCompletedText => @@ -451,8 +451,8 @@ No es posible añadir más de $limit archivos adjuntos String unreadMessagesSeparatorText() => 'Nuevos mensajes'; @override - String get enableFileAccessMessage => 'Habilite el acceso a los archivos' - '\npara poder compartirlos con amigos.'; + String get enableFileAccessMessage => + 'Habilite el acceso a los archivos para poder compartirlos con amigos.'; @override String get allowFileAccessMessage => 'Permitir el acceso a los archivos'; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart index 09f4c0ecb3..7c1fcbc994 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for French (`fr`). @@ -172,8 +174,7 @@ class StreamChatLocalizationsFr extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - "Veuillez autoriser l'accès à vos photos" - '\net vidéos afin de pouvoir les partager avec vos amis.'; + "Veuillez autoriser l'accès à vos photos et vidéos afin de pouvoir les partager avec vos amis."; @override String get allowGalleryAccessMessage => "Autoriser l'accès à votre galerie"; @@ -183,8 +184,7 @@ class StreamChatLocalizationsFr extends GlobalStreamChatLocalizations { @override String get flagMessageQuestion => - 'Voulez-vous envoyer une copie de ce message à un' - '\nmodérateur pour une enquête plus approfondie ?'; + 'Voulez-vous envoyer une copie de ce message à un modérateur pour une enquête plus approfondie ?'; @override String get flagLabel => 'SIGNALER'; @@ -207,7 +207,7 @@ class StreamChatLocalizationsFr extends GlobalStreamChatLocalizations { @override String get deleteMessageQuestion => - 'Êtes-vous sûr de vouloir supprimer définitivement ce\nmessage ?'; + 'Êtes-vous sûr de vouloir supprimer définitivement ce message ?'; @override String get operationCouldNotBeCompletedText => @@ -451,8 +451,7 @@ Limite de pièces jointes dépassée : il n'est pas possible d'ajouter plus de $ @override String get enableFileAccessMessage => - "Veuillez autoriser l'accès aux fichiers" - '\nafin de pouvoir les partager avec des amis.'; + "Veuillez autoriser l'accès aux fichiers afin de pouvoir les partager avec des amis."; @override String get allowFileAccessMessage => "Autoriser l'accès aux fichiers"; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart index 5ba1eb4b26..34694c6466 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for Hindi (`hi`). @@ -167,8 +169,7 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - 'कृपया अपने फ़ोटो और वीडियो तक पहुंच सक्षम करें' - '\nताकि आप उन्हें मित्रों के साथ साझा कर सकें।'; + 'कृपया अपने फ़ोटो और वीडियो तक पहुंच सक्षम करे ताकि आप उन्हें मित्रों के साथ साझा कर सकें।'; @override String get allowGalleryAccessMessage => 'अपनी गैलरी तक पहुंच की अनुमति दें'; @@ -177,8 +178,8 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { String get flagMessageLabel => 'फ्लैग संदेश'; @override - String get flagMessageQuestion => 'क्या आप आगे की जांच के लिए इस संदेश की' - '\nएक प्रति मॉडरेटर को भेजना चाहते हैं?'; + String get flagMessageQuestion => + 'क्या आप आगे की जांच के लिए इस संदेश की एक प्रति मॉडरेटर को भेजना चाहते हैं?'; @override String get flagLabel => 'फ्लैग'; @@ -201,7 +202,7 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { @override String get deleteMessageQuestion => - 'क्या आप वाकई इस संदेश को स्थायी रूप से\nहटाना चाहते हैं?'; + 'क्या आप वाकई इस संदेश को स्थायी रूप से हटाना चाहते हैं?'; @override String get operationCouldNotBeCompletedText => @@ -444,8 +445,8 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { String unreadMessagesSeparatorText() => 'नए संदेश।'; @override - String get enableFileAccessMessage => 'कृपया फ़ाइलों तक पहुंच सक्षम करें ताकि' - '\nआप उन्हें मित्रों के साथ साझा कर सकें।'; + String get enableFileAccessMessage => + 'कृपया फ़ाइलों तक पहुंच सक्षम करें ताकि आप उन्हें मित्रों के साथ साझा कर सकें।'; @override String get allowFileAccessMessage => 'फाइलों तक पहुंच की अनुमति दें'; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart index 04c3a500db..0f4ab0b2a4 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for Italian (`it`). @@ -176,8 +178,7 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.'''; @override String get enablePhotoAndVideoAccessMessage => - "Per favore attiva l'accesso alle foto" - '\ne ai video cosí potrai condividerli con i tuoi amici.'; + "Per favore attiva l'accesso alle foto e ai video cosí potrai condividerli con i tuoi amici."; @override String get allowGalleryAccessMessage => "Permetti l'accesso alla galleria"; @@ -186,8 +187,8 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.'''; String get flagMessageLabel => 'Segnala messaggio'; @override - String get flagMessageQuestion => 'Vuoi mandare una copia di questo messaggio' - '\nad un moderatore?'; + String get flagMessageQuestion => + 'Vuoi mandare una copia di questo messaggio ad un moderatore?'; @override String get flagLabel => 'SEGNALA'; @@ -210,7 +211,7 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.'''; @override String get deleteMessageQuestion => - 'Sei sicuro di voler definitivamente cancellare questo\nmessaggio?'; + 'Sei sicuro di voler definitivamente cancellare questo messaggio?'; @override String get operationCouldNotBeCompletedText => @@ -453,8 +454,8 @@ Attenzione: il limite massimo di $limit file è stato superato. String unreadMessagesSeparatorText() => 'Nouveaux messages'; @override - String get enableFileAccessMessage => "Per favore attiva l'accesso ai file" - '\ncosí potrai condividerli con i tuoi amici.'; + String get enableFileAccessMessage => + "Per favore attiva l'accesso ai file cosí potrai condividerli con i tuoi amici."; @override String get allowFileAccessMessage => "Consenti l'accesso ai file"; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart index d2a55c4c83..c5a714075e 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart @@ -163,8 +163,8 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { String get addMoreFilesLabel => 'ファイルの追加'; @override - String get enablePhotoAndVideoAccessMessage => 'お友達と共有できるように、写真' - '\nやビデオへのアクセスを有効にしてください。'; + String get enablePhotoAndVideoAccessMessage => + 'お友達と共有できるように、写真やビデオへのアクセスを有効にしてください。'; @override String get allowGalleryAccessMessage => 'ギャラリーへのアクセスを許可する'; @@ -172,8 +172,7 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { String get flagMessageLabel => 'メッセージをフラグする'; @override - String get flagMessageQuestion => 'このメッセージのコピーを' - '\nモデレーターに送って、さらに調査してもらいますか?'; + String get flagMessageQuestion => 'このメッセージのコピーをモデレーターに送って、さらに調査してもらいますか?'; @override String get flagLabel => 'フラグする'; @@ -194,8 +193,7 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { String get deleteMessageLabel => 'メッセージを削除する'; @override - String get deleteMessageQuestion => 'このメッセージ' - '\nを完全に削除してもよろしいですか?'; + String get deleteMessageQuestion => 'このメッセージを完全に削除してもよろしいですか?'; @override String get operationCouldNotBeCompletedText => '操作を完了できませんでした。'; @@ -429,8 +427,7 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { String unreadMessagesSeparatorText() => '新しいメッセージ。'; @override - String get enableFileAccessMessage => - '友達と共有できるように、' '\nファイルへのアクセスを有効にしてください。'; + String get enableFileAccessMessage => '友達と共有できるように、ファイルへのアクセスを有効にしてください。'; @override String get allowFileAccessMessage => 'ファイルへのアクセスを許可する'; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart index 816f6d129b..62b14d818b 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart @@ -163,8 +163,8 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations { String get addMoreFilesLabel => '파일을 추가함'; @override - String get enablePhotoAndVideoAccessMessage => '친구와 공유할 수 있도록 사진과' - '\n동영상에 액세스할 수 있도록 설정하십시오.'; + String get enablePhotoAndVideoAccessMessage => + '친구와 공유할 수 있도록 사진과 동영상에 액세스할 수 있도록 설정하십시오.'; @override String get allowGalleryAccessMessage => '갤러리에 대한 액세스를 허용합니다'; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart index cb8b2c80ab..d1a841e01e 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for Norwegian (`no`). @@ -165,8 +167,7 @@ class StreamChatLocalizationsNo extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - 'Vennligst gi tillatelse til dine bilder' - '\nog videoer så du kan dele de med dine venner.'; + 'Vennligst gi tillatelse til dine bilder og videoer så du kan dele de med dine venner.'; @override String get allowGalleryAccessMessage => 'Tillat tilgang til galleri'; @@ -176,8 +177,7 @@ class StreamChatLocalizationsNo extends GlobalStreamChatLocalizations { @override String get flagMessageQuestion => - 'Ønsker du å sende en kopi av denne meldingen til en' - '\nmoderator for videre undersøkelser'; + 'Ønsker du å sende en kopi av denne meldingen til en moderator for videre undersøkelser'; @override String get flagLabel => 'RAPPORTER'; @@ -423,7 +423,6 @@ class StreamChatLocalizationsNo extends GlobalStreamChatLocalizations { @override String toggleMuteUnmuteUserQuestion({required bool isMuted}) { if (isMuted) { - // ignore: lines_longer_than_80_chars return 'Er du sikker på at du vil oppheve ignoreringen av denne brukeren?'; } return 'Er du sikker på at du vil ignorere denne brukeren?'; @@ -437,7 +436,7 @@ class StreamChatLocalizationsNo extends GlobalStreamChatLocalizations { @override String get enableFileAccessMessage => - 'Aktiver tilgang til filer slik' '\nat du kan dele dem med venner.'; + 'Aktiver tilgang til filer slik at du kan dele dem med venner.'; @override String get allowFileAccessMessage => 'Gi tilgang til filer'; diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart index 2fd941c773..415ddd0ecd 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart @@ -1,3 +1,5 @@ +// ignore_for_file: lines_longer_than_80_chars + part of 'stream_chat_localizations.dart'; /// The translations for Portuguese (`pt`). @@ -168,8 +170,7 @@ class StreamChatLocalizationsPt extends GlobalStreamChatLocalizations { @override String get enablePhotoAndVideoAccessMessage => - 'Por favor, permita o acesso às suas fotos' - '\ne vídeos para que possa compartilhar com sua rede.'; + 'Por favor, permita o acesso às suas fotos e vídeos para que possa compartilhar com sua rede.'; @override String get allowGalleryAccessMessage => 'Permitir acesso à sua galeria'; @@ -178,8 +179,8 @@ class StreamChatLocalizationsPt extends GlobalStreamChatLocalizations { String get flagMessageLabel => 'Denunciar mensagem'; @override - String get flagMessageQuestion => 'Gostaria de enviar esta mensagem ao' - '\nmoderador para maior investigação?'; + String get flagMessageQuestion => + 'Gostaria de enviar esta mensagem ao moderador para maior investigação?'; @override String get flagLabel => 'DENUNCIAR'; @@ -202,7 +203,7 @@ class StreamChatLocalizationsPt extends GlobalStreamChatLocalizations { @override String get deleteMessageQuestion => - 'Você tem certeza que deseja apagar essa\nmensagem permanentemente?'; + 'Você tem certeza que deseja apagar essa mensagem permanentemente?'; @override String get operationCouldNotBeCompletedText => @@ -450,7 +451,7 @@ Não é possível adicionar mais de $limit arquivos de uma vez @override String get enableFileAccessMessage => - 'Ative o acesso aos arquivos' '\npara poder compartilhá-los com amigos.'; + 'Ative o acesso aos arquivos para poder compartilhá-los com amigos.'; @override String get allowFileAccessMessage => 'Permitir acesso aos arquivos'; From 08600ee399ba8acb48ee5cb9356af0b1f6f4db3c Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Mon, 26 May 2025 15:18:01 +0200 Subject: [PATCH 02/34] refactor(ui): sync theme with figma (#2263) Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com> --- .../lib/src/theme/color_theme.dart | 210 ++++++++++-------- .../lib/src/theme/stream_chat_theme.dart | 19 +- .../lib/src/theme/text_theme.dart | 17 +- ...m_voice_recording_attachment_idle_dark.png | Bin 5994 -> 6008 bytes ..._voice_recording_attachment_idle_light.png | Bin 6435 -> 6761 bytes ...oice_recording_attachment_playing_dark.png | Bin 5485 -> 5510 bytes ...ice_recording_attachment_playing_light.png | Bin 6206 -> 6413 bytes ...ice_recording_attachment_playlist_dark.png | Bin 14008 -> 14115 bytes ...ce_recording_attachment_playlist_light.png | Bin 13889 -> 14609 bytes .../goldens/ci/edit_message_sheet_0.png | Bin 5357 -> 5694 bytes .../goldens/ci/error_alert_sheet_0.png | Bin 1760 -> 1757 bytes .../goldens/ci/confirmation_dialog_0.png | Bin 4309 -> 4282 bytes .../goldens/ci/delete_message_dialog_0.png | Bin 4314 -> 4283 bytes .../dialogs/goldens/ci/message_dialog_0.png | Bin 4241 -> 4210 bytes .../dialogs/goldens/ci/message_dialog_1.png | Bin 4220 -> 4229 bytes .../dialogs/goldens/ci/message_dialog_2.png | Bin 4241 -> 4210 bytes .../goldens/ci/stream_svg_icon_light.png | Bin 118994 -> 118840 bytes .../goldens/ci/sending_indicator_1.png | Bin 290 -> 309 bytes .../goldens/ci/sending_indicator_2.png | Bin 478 -> 508 bytes ...ssage_action_item_custom_styling_light.png | Bin 399 -> 391 bytes ...tream_message_action_item_delete_light.png | Bin 391 -> 355 bytes .../stream_message_action_item_reply_dark.png | Bin 396 -> 398 bytes ...stream_message_action_item_reply_light.png | Bin 391 -> 358 bytes ...stream_audio_recorder_button_idle_dark.png | Bin 1641 -> 1651 bytes ...tream_audio_recorder_button_idle_light.png | Bin 1592 -> 1679 bytes ...io_recorder_button_recording_hold_dark.png | Bin 4743 -> 4953 bytes ...o_recorder_button_recording_hold_light.png | Bin 4813 -> 4915 bytes ..._recorder_button_recording_locked_dark.png | Bin 6746 -> 6743 bytes ...recorder_button_recording_locked_light.png | Bin 6344 -> 6636 bytes ...recorder_button_recording_stopped_dark.png | Bin 5872 -> 5916 bytes ...ecorder_button_recording_stopped_light.png | Bin 5536 -> 5853 bytes .../goldens/ci/attachment_button_0.png | Bin 1268 -> 1354 bytes .../goldens/ci/countdown_button_0.png | Bin 625 -> 815 bytes .../moderated_message_actions_modal_dark.png | Bin 2458 -> 2500 bytes .../moderated_message_actions_modal_light.png | Bin 2550 -> 2534 bytes .../ci/stream_message_actions_modal_dark.png | Bin 5034 -> 5029 bytes .../ci/stream_message_actions_modal_light.png | Bin 5140 -> 5199 bytes ...am_message_actions_modal_reversed_dark.png | Bin 5081 -> 5109 bytes ...m_message_actions_modal_reversed_light.png | Bin 5317 -> 5363 bytes ...ons_modal_reversed_with_reactions_dark.png | Bin 8393 -> 8389 bytes ...ns_modal_reversed_with_reactions_light.png | Bin 8702 -> 8934 bytes ...sage_actions_modal_with_reactions_dark.png | Bin 8323 -> 8276 bytes ...age_actions_modal_with_reactions_light.png | Bin 8456 -> 8771 bytes .../stream_message_reactions_modal_dark.png | Bin 12082 -> 12166 bytes .../stream_message_reactions_modal_light.png | Bin 13269 -> 13555 bytes ..._message_reactions_modal_reversed_dark.png | Bin 11837 -> 11876 bytes ...message_reactions_modal_reversed_light.png | Bin 13104 -> 13404 bytes .../goldens/ci/deleted_message_custom.png | Bin 935 -> 956 bytes .../goldens/ci/deleted_message_dark.png | Bin 706 -> 761 bytes .../goldens/ci/deleted_message_light.png | Bin 692 -> 753 bytes .../reaction_icon_button_selected_light.png | Bin 628 -> 646 bytes .../reaction_icon_button_unselected_light.png | Bin 647 -> 620 bytes .../ci/reaction_picker_icon_list_light.png | Bin 3049 -> 2918 bytes ...action_picker_icon_list_selected_light.png | Bin 3054 -> 2971 bytes .../ci/stream_reaction_picker_light.png | Bin 3413 -> 2918 bytes .../stream_reaction_picker_selected_light.png | Bin 3451 -> 2971 bytes .../src/misc/goldens/ci/reaction_bubble_2.png | Bin 2676 -> 2678 bytes .../goldens/ci/reaction_bubble_3_dark.png | Bin 2150 -> 2178 bytes .../goldens/ci/reaction_bubble_3_light.png | Bin 1842 -> 1982 bytes .../goldens/ci/reaction_bubble_like_dark.png | Bin 1626 -> 1696 bytes .../goldens/ci/reaction_bubble_like_light.png | Bin 1331 -> 1474 bytes ...ream_audio_waveform_slider_custom_dark.png | Bin 3487 -> 3489 bytes ...eam_audio_waveform_slider_custom_light.png | Bin 3375 -> 3439 bytes .../ci/stream_audio_waveform_slider_dark.png | Bin 2999 -> 3168 bytes ...tream_audio_waveform_slider_empty_dark.png | Bin 935 -> 988 bytes ...ream_audio_waveform_slider_empty_light.png | Bin 943 -> 976 bytes ...am_audio_waveform_slider_inverted_dark.png | Bin 3087 -> 3237 bytes ...m_audio_waveform_slider_inverted_light.png | Bin 3129 -> 3272 bytes ...m_audio_waveform_slider_less_data_dark.png | Bin 2826 -> 2999 bytes ..._audio_waveform_slider_less_data_light.png | Bin 2926 -> 3055 bytes .../ci/stream_audio_waveform_slider_light.png | Bin 3086 -> 3187 bytes ...am_audio_waveform_slider_progress_dark.png | Bin 3446 -> 3476 bytes ...m_audio_waveform_slider_progress_light.png | Bin 3348 -> 3236 bytes .../goldens/ci/stream_timestamp_light.png | Bin 1019 -> 1027 bytes .../misc/goldens/ci/system_message_dark.png | Bin 661 -> 660 bytes .../misc/goldens/ci/system_message_light.png | Bin 659 -> 659 bytes ...poll_option_reorderable_list_view_dark.png | Bin 5513 -> 5583 bytes ...ption_reorderable_list_view_error_dark.png | Bin 5688 -> 5777 bytes ...tion_reorderable_list_view_error_light.png | Bin 5614 -> 5907 bytes ...oll_option_reorderable_list_view_light.png | Bin 5440 -> 5711 bytes .../ci/poll_question_text_field_dark.png | Bin 1778 -> 1787 bytes .../poll_question_text_field_error_dark.png | Bin 1874 -> 1903 bytes .../poll_question_text_field_error_light.png | Bin 1950 -> 2006 bytes .../ci/poll_question_text_field_light.png | Bin 1811 -> 1874 bytes .../ci/stream_poll_creator_dialog_dark.png | Bin 18790 -> 18847 bytes .../ci/stream_poll_creator_dialog_light.png | Bin 17821 -> 18325 bytes ...m_poll_creator_full_screen_dialog_dark.png | Bin 13767 -> 13935 bytes ..._poll_creator_full_screen_dialog_light.png | Bin 13634 -> 13814 bytes ...poll_option_reorderable_list_view_dark.png | Bin 5513 -> 5583 bytes ...oll_option_reorderable_list_view_error.png | Bin 5614 -> 5907 bytes ...oll_option_reorderable_list_view_light.png | Bin 5440 -> 5711 bytes .../ci/poll_question_text_field_dark.png | Bin 1778 -> 1787 bytes .../ci/poll_question_text_field_error.png | Bin 1950 -> 2006 bytes .../ci/poll_question_text_field_light.png | Bin 1811 -> 1874 bytes .../ci/stream_poll_creator_dialog_dark.png | Bin 18790 -> 18847 bytes .../ci/stream_poll_creator_dialog_light.png | Bin 17821 -> 18325 bytes ...m_poll_creator_full_screen_dialog_dark.png | Bin 13767 -> 13935 bytes ..._poll_creator_full_screen_dialog_light.png | Bin 13634 -> 13814 bytes .../ci/stream_poll_options_dialog_dark.png | Bin 10397 -> 10901 bytes .../ci/stream_poll_options_dialog_light.png | Bin 10767 -> 11017 bytes .../ci/stream_poll_results_dialog_dark.png | Bin 14055 -> 14145 bytes .../ci/stream_poll_results_dialog_light.png | Bin 14328 -> 14471 bytes ...poll_results_dialog_with_show_all_dark.png | Bin 11524 -> 11632 bytes ...oll_results_dialog_with_show_all_light.png | Bin 11620 -> 11782 bytes .../ci/poll_add_comment_dialog_dark.png | Bin 3498 -> 3516 bytes .../ci/poll_add_comment_dialog_light.png | Bin 3457 -> 3526 bytes ...comment_dialog_with_initial_value_dark.png | Bin 4020 -> 4036 bytes ...omment_dialog_with_initial_value_light.png | Bin 3991 -> 4064 bytes .../goldens/ci/poll_end_vote_dialog_light.png | Bin 2323 -> 2324 bytes .../goldens/ci/poll_header_dark.png | Bin 946 -> 952 bytes .../goldens/ci/poll_header_light.png | Bin 979 -> 989 bytes .../ci/poll_header_long_question_dark.png | Bin 1146 -> 1154 bytes .../ci/poll_header_long_question_light.png | Bin 1111 -> 1115 bytes ...l_header_subtitle_voting_mode_all_dark.png | Bin 948 -> 953 bytes ..._header_subtitle_voting_mode_all_light.png | Bin 978 -> 987 bytes ...der_subtitle_voting_mode_disabled_dark.png | Bin 946 -> 951 bytes ...er_subtitle_voting_mode_disabled_light.png | Bin 979 -> 986 bytes ...ader_subtitle_voting_mode_limited_dark.png | Bin 945 -> 951 bytes ...der_subtitle_voting_mode_limited_light.png | Bin 979 -> 988 bytes ...eader_subtitle_voting_mode_unique_dark.png | Bin 946 -> 952 bytes ...ader_subtitle_voting_mode_unique_light.png | Bin 979 -> 989 bytes .../ci/poll_suggest_option_dialog_dark.png | Bin 3341 -> 3522 bytes .../ci/poll_suggest_option_dialog_light.png | Bin 3271 -> 3430 bytes ...option_dialog_with_initial_option_dark.png | Bin 3907 -> 4067 bytes ...ption_dialog_with_initial_option_light.png | Bin 3887 -> 4019 bytes .../ci/stream_poll_interactor_closed_dark.png | Bin 6693 -> 6724 bytes .../stream_poll_interactor_closed_light.png | Bin 6792 -> 6369 bytes .../ci/stream_poll_interactor_dark.png | Bin 8491 -> 8656 bytes .../ci/stream_poll_interactor_light.png | Bin 8513 -> 8400 bytes .../ci/stream_draft_list_tile_dark.png | Bin 1366 -> 1364 bytes .../ci/stream_draft_list_tile_light.png | Bin 1455 -> 1339 bytes .../ci/stream_thread_list_tile_dark.png | Bin 3858 -> 3856 bytes .../ci/stream_thread_list_tile_light.png | Bin 4073 -> 3983 bytes .../ci/stream_unread_threads_banner_light.png | Bin 2278 -> 2273 bytes .../src/theme/channel_header_theme_test.dart | 12 +- .../theme/channel_list_header_theme_test.dart | 8 +- .../src/theme/channel_preview_theme_test.dart | 22 +- .../src/theme/gallery_footer_theme_test.dart | 32 +-- .../src/theme/message_input_theme_test.dart | 44 ++-- .../theme/message_list_view_theme_test.dart | 4 +- .../test/src/theme/message_theme_test.dart | 56 ++--- 141 files changed, 225 insertions(+), 199 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/theme/color_theme.dart b/packages/stream_chat_flutter/lib/src/theme/color_theme.dart index 167c68ee61..785af3c404 100644 --- a/packages/stream_chat_flutter/lib/src/theme/color_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/color_theme.dart @@ -1,84 +1,110 @@ import 'package:flutter/material.dart'; -/// {@template color_theme} -/// Theme that holds colors -/// {@endtemplate} +/// Defines a color theme for the Stream Chat UI, +/// including core surfaces, text colors, accents, and visual effects. +/// +/// This theme provides two variants: +/// - `StreamColorTheme.light`: for light mode +/// - `StreamColorTheme.dark`: for dark mode class StreamColorTheme { - /// Initialise with light theme - StreamColorTheme.light({ + /// Creates a [StreamColorTheme] instance based on the provided [brightness]. + /// + /// Returns a light theme when [brightness] is [Brightness.light] and + /// a dark theme when [brightness] is [Brightness.dark]. + factory StreamColorTheme({ + Brightness brightness = Brightness.light, + }) { + return switch (brightness) { + Brightness.light => const StreamColorTheme.light(), + Brightness.dark => const StreamColorTheme.dark(), + }; + } + + /// Creates a light mode [StreamColorTheme] using design system values. + const StreamColorTheme.light({ this.textHighEmphasis = const Color(0xff000000), - this.textLowEmphasis = const Color(0xff7a7a7a), - this.disabled = const Color(0xffdbdbdb), - this.borders = const Color(0xffecebeb), + this.textLowEmphasis = const Color(0xff72767e), + this.disabled = const Color(0xffb4b7bb), + this.borders = const Color(0xffdbdde1), this.inputBg = const Color(0xffe9eaed), - this.appBg = const Color(0xfff7f7f8), + this.appBg = const Color(0xffffffff), this.barsBg = const Color(0xffffffff), this.linkBg = const Color(0xffe9f2ff), - this.accentPrimary = const Color(0xff005FFF), - this.accentError = const Color(0xffFF3842), - this.accentInfo = const Color(0xff20E070), + this.accentPrimary = const Color(0xff005fff), + this.accentError = const Color(0xffff3742), + this.accentInfo = const Color(0xff20e070), this.highlight = const Color(0xfffbf4dd), this.overlay = const Color.fromRGBO(0, 0, 0, 0.2), this.overlayDark = const Color.fromRGBO(0, 0, 0, 0.6), this.bgGradient = const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, - colors: [Color(0xfff7f7f7), Color(0xfffcfcfc)], + colors: [Color(0xfff7f7f8), Color(0xffe9eaed)], stops: [0, 1], ), this.borderTop = const Effect( sigmaX: 0, sigmaY: -1, - color: Color(0xff000000), + color: Color(0xffdbdde1), blur: 0, - alpha: 0.08, + alpha: 1, ), this.borderBottom = const Effect( sigmaX: 0, sigmaY: 1, - color: Color(0xff000000), + color: Color(0xffdbdde1), blur: 0, - alpha: 0.08, + alpha: 1, ), this.shadowIconButton = const Effect( sigmaX: 0, sigmaY: 2, color: Color(0xff000000), - alpha: 0.5, blur: 4, + alpha: 0.25, ), this.modalShadow = const Effect( sigmaX: 0, sigmaY: 0, color: Color(0xff000000), - alpha: 1, - blur: 8, + blur: 4, + alpha: 0.6, ), }) : brightness = Brightness.light; - /// Initialise with dark theme - StreamColorTheme.dark({ + /// Creates a dark mode [StreamColorTheme] using design system values. + const StreamColorTheme.dark({ this.textHighEmphasis = const Color(0xffffffff), - this.textLowEmphasis = const Color(0xff7a7a7a), - this.disabled = const Color(0xff2d2f2f), - this.borders = const Color(0xff1c1e22), - this.inputBg = const Color(0xff13151b), + this.textLowEmphasis = const Color(0xff72767e), + this.disabled = const Color(0xff4c525c), + this.borders = const Color(0xff272a30), + this.inputBg = const Color(0xff1c1e22), this.appBg = const Color(0xff000000), this.barsBg = const Color(0xff121416), - this.linkBg = const Color(0xff00193D), + this.linkBg = const Color(0xff00193d), this.accentPrimary = const Color(0xff337eff), - this.accentError = const Color(0xffFF3742), - this.accentInfo = const Color(0xff20E070), + this.accentError = const Color(0xffff3742), + this.accentInfo = const Color(0xff20e070), + this.highlight = const Color(0xff302d22), + this.overlay = const Color.fromRGBO(0, 0, 0, 0.4), + this.overlayDark = const Color.fromRGBO(255, 255, 255, 0.6), + this.bgGradient = const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Color(0xff101214), Color(0xff070a0d)], + stops: [0, 1], + ), this.borderTop = const Effect( sigmaX: 0, sigmaY: -1, - color: Color(0xff141924), + color: Color(0xff272a30), blur: 0, + alpha: 1, ), this.borderBottom = const Effect( sigmaX: 0, sigmaY: 1, - color: Color(0xff141924), + color: Color(0xff272a30), blur: 0, alpha: 1, ), @@ -86,93 +112,81 @@ class StreamColorTheme { sigmaX: 0, sigmaY: 2, color: Color(0xff000000), - alpha: 0.5, blur: 4, + alpha: 0.5, ), this.modalShadow = const Effect( sigmaX: 0, sigmaY: 0, color: Color(0xff000000), - alpha: 1, blur: 8, - ), - this.highlight = const Color(0xff302d22), - this.overlay = const Color.fromRGBO(0, 0, 0, 0.4), - this.overlayDark = const Color.fromRGBO(255, 255, 255, 0.6), - this.bgGradient = const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color(0xff101214), - Color(0xff070a0d), - ], - stops: [0, 1], + alpha: 1, ), }) : brightness = Brightness.dark; - /// + /// Main body text or primary icons. final Color textHighEmphasis; - /// + /// Secondary or less prominent text/icons. final Color textLowEmphasis; - /// + /// Disabled UI elements (icons, inputs). final Color disabled; - /// + /// Standard UI borders and dividers. final Color borders; - /// + /// Background for input fields. final Color inputBg; - /// + /// Main app background. final Color appBg; - /// + /// Bars: headers, footers, and toolbars. final Color barsBg; - /// + /// Background for links and link cards. final Color linkBg; - /// + /// Primary action color (buttons, active states). final Color accentPrimary; - /// + /// Error color (alerts, badges). final Color accentError; - /// + /// Informational highlights (e.g., status). final Color accentInfo; - /// - final Effect borderTop; - - /// - final Effect borderBottom; - - /// - final Effect shadowIconButton; - - /// - final Effect modalShadow; - - /// + /// Highlighted rows, pinned messages. final Color highlight; - /// + /// General translucent overlay for modals, sheets. final Color overlay; - /// + /// Overlay for dark mode interactions or highlight effects. final Color overlayDark; - /// + /// Background gradient for section headers. final Gradient bgGradient; - /// + /// Theme brightness indicator. final Brightness brightness; - /// Copy with theme + /// Top border effect (for elevation). + final Effect borderTop; + + /// Bottom border effect. + final Effect borderBottom; + + /// Icon button drop shadow effect. + final Effect shadowIconButton; + + /// Modal shadow effect. + final Effect modalShadow; + + /// Returns a new [StreamColorTheme] by overriding selected fields. StreamColorTheme copyWith({ - Brightness brightness = Brightness.light, + Brightness? brightness, Color? textHighEmphasis, Color? textLowEmphasis, Color? disabled, @@ -184,16 +198,16 @@ class StreamColorTheme { Color? accentPrimary, Color? accentError, Color? accentInfo, - Effect? borderTop, - Effect? borderBottom, - Effect? shadowIconButton, - Effect? modalShadow, Color? highlight, Color? overlay, Color? overlayDark, Gradient? bgGradient, + Effect? borderTop, + Effect? borderBottom, + Effect? shadowIconButton, + Effect? modalShadow, }) { - return brightness == Brightness.light + return (brightness ?? this.brightness) == Brightness.light ? StreamColorTheme.light( textHighEmphasis: textHighEmphasis ?? this.textHighEmphasis, textLowEmphasis: textLowEmphasis ?? this.textLowEmphasis, @@ -206,14 +220,14 @@ class StreamColorTheme { accentPrimary: accentPrimary ?? this.accentPrimary, accentError: accentError ?? this.accentError, accentInfo: accentInfo ?? this.accentInfo, - borderTop: borderTop ?? this.borderTop, - borderBottom: borderBottom ?? this.borderBottom, - shadowIconButton: shadowIconButton ?? this.shadowIconButton, - modalShadow: modalShadow ?? this.modalShadow, highlight: highlight ?? this.highlight, overlay: overlay ?? this.overlay, overlayDark: overlayDark ?? this.overlayDark, bgGradient: bgGradient ?? this.bgGradient, + borderTop: borderTop ?? this.borderTop, + borderBottom: borderBottom ?? this.borderBottom, + shadowIconButton: shadowIconButton ?? this.shadowIconButton, + modalShadow: modalShadow ?? this.modalShadow, ) : StreamColorTheme.dark( textHighEmphasis: textHighEmphasis ?? this.textHighEmphasis, @@ -227,18 +241,18 @@ class StreamColorTheme { accentPrimary: accentPrimary ?? this.accentPrimary, accentError: accentError ?? this.accentError, accentInfo: accentInfo ?? this.accentInfo, - borderTop: borderTop ?? this.borderTop, - borderBottom: borderBottom ?? this.borderBottom, - shadowIconButton: shadowIconButton ?? this.shadowIconButton, - modalShadow: modalShadow ?? this.modalShadow, highlight: highlight ?? this.highlight, overlay: overlay ?? this.overlay, overlayDark: overlayDark ?? this.overlayDark, bgGradient: bgGradient ?? this.bgGradient, + borderTop: borderTop ?? this.borderTop, + borderBottom: borderBottom ?? this.borderBottom, + shadowIconButton: shadowIconButton ?? this.shadowIconButton, + modalShadow: modalShadow ?? this.modalShadow, ); } - /// Merge color theme + /// Merges this theme with [other], replacing any fields that [other] defines. StreamColorTheme merge(StreamColorTheme? other) { if (other == null) return this; return copyWith( @@ -265,9 +279,9 @@ class StreamColorTheme { } } -/// Effect store +/// Visual effect such as blur or shadow used by the theme. class Effect { - /// Constructor for creating [Effect] + /// Creates an [Effect] instance. const Effect({ this.sigmaX, this.sigmaY, @@ -276,22 +290,22 @@ class Effect { this.blur, }); - /// + /// Horizontal shadow offset. final double? sigmaX; - /// + /// Vertical shadow offset. final double? sigmaY; - /// + /// Color of the shadow or border. final Color? color; - /// + /// Opacity (0–1) of the effect. final double? alpha; - /// + /// Blur radius. final double? blur; - /// Copy with new effect + /// Returns a copy with updated fields. Effect copyWith({ double? sigmaX, double? sigmaY, @@ -303,7 +317,7 @@ class Effect { sigmaX: sigmaX ?? this.sigmaX, sigmaY: sigmaY ?? this.sigmaY, color: color ?? this.color, - alpha: color as double? ?? this.alpha, + alpha: alpha ?? this.alpha, blur: blur ?? this.blur, ); } diff --git a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart index d3200ff478..f1cb07953b 100644 --- a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart @@ -74,9 +74,8 @@ class StreamChatThemeData { StreamVoiceRecordingAttachmentThemeData? voiceRecordingAttachmentTheme, }) { brightness ??= colorTheme?.brightness ?? Brightness.light; - final isDark = brightness == Brightness.dark; - textTheme ??= isDark ? StreamTextTheme.dark() : StreamTextTheme.light(); - colorTheme ??= isDark ? StreamColorTheme.dark() : StreamColorTheme.light(); + textTheme ??= StreamTextTheme(brightness: brightness); + colorTheme ??= StreamColorTheme(brightness: brightness); final defaultData = StreamChatThemeData.fromColorAndTextTheme( colorTheme, @@ -180,7 +179,7 @@ class StreamChatThemeData { color: colorTheme.barsBg, titleStyle: textTheme.headlineBold, subtitleStyle: textTheme.footnote.copyWith( - color: const Color(0xff7A7A7A), + color: colorTheme.textLowEmphasis, ), ); final channelPreviewTheme = StreamChannelPreviewThemeData( @@ -245,7 +244,7 @@ class StreamChatThemeData { createdAtStyle: textTheme.footnote.copyWith(color: colorTheme.textLowEmphasis), repliesStyle: textTheme.footnoteBold.copyWith(color: accentColor), - messageBackgroundColor: colorTheme.borders, + messageBackgroundColor: colorTheme.inputBg, messageBorderColor: colorTheme.borders, reactionsBackgroundColor: colorTheme.barsBg, reactionsBorderColor: colorTheme.borders, @@ -309,14 +308,14 @@ class StreamChatThemeData { linkHighlightColor: colorTheme.accentPrimary, idleBorderGradient: LinearGradient( colors: [ - colorTheme.disabled, - colorTheme.disabled, + colorTheme.borders, + colorTheme.borders, ], ), activeBorderGradient: LinearGradient( colors: [ - colorTheme.disabled, - colorTheme.disabled, + colorTheme.borders, + colorTheme.borders, ], ), useSystemAttachmentPicker: false, @@ -340,7 +339,7 @@ class StreamChatThemeData { bottomSheetCloseIconColor: colorTheme.textHighEmphasis, ), messageListViewTheme: StreamMessageListViewThemeData( - backgroundColor: colorTheme.barsBg, + backgroundColor: colorTheme.appBg, ), pollCreatorTheme: StreamPollCreatorThemeData( backgroundColor: colorTheme.appBg, diff --git a/packages/stream_chat_flutter/lib/src/theme/text_theme.dart b/packages/stream_chat_flutter/lib/src/theme/text_theme.dart index 9662b4bcd9..62a30d1245 100644 --- a/packages/stream_chat_flutter/lib/src/theme/text_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/text_theme.dart @@ -4,8 +4,21 @@ import 'package:flutter/material.dart'; /// Class for holding text theme /// {@endtemplate} class StreamTextTheme { + /// Creates a [StreamTextTheme] instance based on the provided [brightness]. + /// + /// Returns a light theme when [brightness] is [Brightness.light] and + /// a dark theme when [brightness] is [Brightness.dark]. + factory StreamTextTheme({ + Brightness brightness = Brightness.light, + }) { + return switch (brightness) { + Brightness.light => const StreamTextTheme.light(), + Brightness.dark => const StreamTextTheme.dark(), + }; + } + /// Initialise light text theme - StreamTextTheme.light({ + const StreamTextTheme.light({ this.title = const TextStyle( fontSize: 22, fontWeight: FontWeight.w500, @@ -49,7 +62,7 @@ class StreamTextTheme { }); /// Initialise with dark theme - StreamTextTheme.dark({ + const StreamTextTheme.dark({ this.title = const TextStyle( fontSize: 22, fontWeight: FontWeight.w500, diff --git a/packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_dark.png b/packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_dark.png index cf951c9a8d4655eb4772c93cce2a623a33a57289..50e70cf4909541d366a748046f05c5e62d2c61ec 100644 GIT binary patch literal 6008 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 YtPJ@Vi@lKquzL<5^^9+n>fC$$Kawgbl>h($ literal 5994 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 diff --git a/packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_light.png b/packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_light.png index 247512100d7a72f63bd2c310454e7c8125bdda28..378d8e621f4a7e46b393d220462c17895531701a 100644 GIT binary patch literal 6761 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 literal 6435 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 U7qw4={{aBz##To4h8_?8AE{vtSpWb4 diff --git a/packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playlist_dark.png b/packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playlist_dark.png index c00c4952f6fd639fb92dcaa76ff4d4ba251beeb5..b39b7214a71ee19556099061f9a39349ac7eaf83 100644 GIT binary patch literal 14115 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 TMjXI@14F1QYoLl1O@jUx;?3ty diff --git a/packages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/edit_message_sheet_0.png b/packages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/edit_message_sheet_0.png index 386f6c481f56b241ce888428315cd386a4c6b910..154cdd7a3976128c1ed97a524dd35c663fe98425 100644 GIT binary patch literal 5694 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 literal 5357 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 delta 919 zcmV;I18Dr+4d4xsL4S%#L_t(|obBDstDI*Uz~SeebNmOiezoGp8oE#^wQ8+4WFf(w ziw4AvZi*>yq%Ni77P}3&Gm57v@g(zB$x+qwfEF2v}@-0f2)NEFeR$fU^bxLIINy0Z4y#H@yHy zz_n{*@w16vH8^!$}E{rQD4#x&-)zIn`dzGKYy-8=S=e`t(dPd9GPv|KLdO)o*$ z^z`Mi^T?zBiPX!R@3?*JefbMxe(&9{+HM>@g2kcjJpSZZJpSatAF!Cl-e(^g`yYSs zR<6Yn<~=M9W#_RcR*TgbW9)y=W9PfyAB(d;x>aj�eHFn=W1&iy!>((2w7F^m}9a z^>5a?6Wc+sSj|f>jooj2>xP$HyYSSwcHya)zhHkJJ70ffjO*9ezaK}MV6l?LkAFJG z-~VybbEe<_VJt3QTFXvs55Zz3i(fvowpr8Dm)ACn?I2jJ=J_jY8#RCZ_PMpqVmk;H zE16z=aecG?bmM!s;Qt90tJ&FE->i9meY4mKzAM2><~O{4O#l4j4X=6K@sA#C)@`?~ zX)Csc6Ba9(kKMVxS$Dm2ZL`=8g2hVa``-VG*Sz9=SpS`M{|DBz7286vSjqm02gdxS zH{SG|`R#8T`yc+`T6TY8d-(D*E1RDE)!6;g*A72mF^%ird3en4dDlAEVhcE7v9kHz zd&b^FpE~s8_dfp_vEopCO30z?fASM!%=6fJ?1?ev10K>Bi?R2)PmlcvKX$9v(4j`{9)ziPX2^avI=Z@DfUiwnOP)5XhU`rVZ= zz3`WR|3vcbZyEDl$Hx4=d&d3)_pkS+Q?`;|0U6$O2a|CDRUl(`(+j+ooIihloIH7Q z(`&&0oI7`JoH%h}(`&qDIAN3T1TT|q1`0Y%%jI(3^b!CE;e-Wb2o{hbSU`qg0U3e? zWC#|J;h&#ZboT7oar*S>O|QWbaOTXJaq85mO|OySgp>aSACqkc5e2{b0y3PF5dm=) z*u8r7>ZW%9IFM<%T+W+b0^lILBm|Rj0WKV4chd{da^bmYeB|NvJZ*mRmFwg9F+az~ t!8u`*?*uXjOFu{iBsgJ{?*uOv@h<_?&M#8FHFW?0002ovPDHLkV1nO$=End4 diff --git a/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/confirmation_dialog_0.png b/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/confirmation_dialog_0.png index 28fd090881670dc1c94b2de6f4b1970c74ecec56..5d0d97458b799ef4e6d6e9d4776e884a85251208 100644 GIT binary patch literal 4282 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 KZSbcq|LZ^X!nUsf diff --git a/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/delete_message_dialog_0.png b/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/delete_message_dialog_0.png index 7d9d740d7789b6db478fa7bd711c08488ca04341..b4b97e104b03b700619dd491fc4e0de7e9a0f2cd 100644 GIT binary patch literal 4283 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 DP1oR~ diff --git a/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_0.png b/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_0.png index e6bf309bc32627086db301fb3e2c47e45208eb8d..ff5aae491bb172b82eba8c3c76dff09a54ba812a 100644 GIT binary patch literal 4210 zcmds*c~H~Ymd6u75NJeXQ;5L0fFeQzB3pn62&k+gvL}kN*b0b%5CVd)MOl>4(#Q_7 z3lWe-5KTxcYqQEOBoHAgkc1^HAp}U?P0zen^`>h6nVPDpdZ|h!H+T7+bMCp{^SMcM zw6~TJQxJndAQBgBEH6VK&{Xi&*eeWvS#0|L34B09FI$^Ks{3IJpdl1$e&Nbq@QU7h zGXVnG54&J_?n-3t;#AC?^o@x>n7D>3G;u|EI6mNSPB3=eoku0ky1j1{XdPv$o?jGO z)dov6lXq&5YmzL_WZPvNv^$fU*`CoGn9^J;x^Sl55_ax@QI@5y?Ae?puSp8kBPk9W#%@8XBrh1HCs`hpQJw>Sw9h3!jQr4`fv}jLPlCsB_<}OHfn|AKJQ&Mq@< zePg5DPJc?q0nW6Xz(FJ`akx`K?-$BMrJp~Rv_YXzEK&B<)i#F*t7&zvhMM8qKi#BuJPR3haZM)(BRrg)o#CAMVt%OWTrX7g z#4*Utx~6Mc18plScR>hY8I6sNU-0PA=+(3W4NST=?n4~N5G}r8l$IC}g`YM3`m$w7 zO~F`a2a~r9myVL^{D(hDN_Nhf@z6|&LiaQQLrpqWozVJ3GK0{aIpTt7VZE(s@6R*t zK?+_Y2U1#0s#`d;y77Z)??t;>CCy-p`av2PiMUUE%a}OSZY4u6#oZe&Xc*1D8@)qS z#u6}_F9>3YLcf9h!&=0hd$#%TW`>LD74KZc5`N8|2~mAyf?>5yMNqt13Y{gZYN_K$ z%;|p9ZH7VEyd!XHq-~_anOd5GOj;N&2Udwx?ug#pppDK#ZBJNOScLSPZu*_j@uYHH z^ycQ$R0wx#ZoBfpwNJN#f>P%4F`E39>Ri#N^nG3OM0Pv7RhjEZ+ZQ_5|7@+_SZk6* zDkcz2CMPE^PKli8FSK~#bM2anu(0rKygV|&`@{Y8_X9(vm#F&0ExQWi=+tiE5+ae< zu-cz%sLPK8$RGD;nsb4=ugJ^j0n_a}@YSxPA-vtqPVVmZrHMi!(F}y#rJEt?JmIfG zAFrv|>UFj^JRU^Y7-Q2>JOwk(Ahu0V_1zwExi)O<4)x31+pf{PZHm@+*#rug)udN| zeyy&U>hU1pO=;=z>JLlr`6G6|ikPkF$gc2m?{%LHAq6(I_h=Der>?$!wXl4a^5(il zpWic=nBa!S#<819jzlXfE1&P(>9zM4C$oERgJ21Y z>}yL@%Xdpd-*Ea<+Qz}b!ESbNa#CS)Dgs50pv25VVQFJyV{Y|+cCX#*%Tzb{i91BG zU4Ni{D78}w^IA2ug}YJH2_EE}=8m|ru(XtNs`_1#YW*+a4lrCd;gOz^k%F#YZvr@X z=5t<=Gx5w3XNS@D%|6KJ88{rqKfre;>PkNwDsOdJ`|!BCgCiqX=5uQ+$)evD$_q5% zN_~BO%=&^|TX-CGXlzVQ625|HXlRfznnUq8t~0-Nzw$!dXMAyDKmFd5(V69+@6Lw3 zWcKA5>$fnU1sI2-%*-cBy@V~CF9F~X8{GS5b6pqgkl2U&R^RPa&KuqPmJkVv2V+m3QF1v` zC?N0$TWUY#vXD@m3>2zz9s#l8H}U1+xl=KlQ@%A2JU0E5>kERpMV6!Tv8M?JQ4L>+ zOYZ)8F2ET4)Q1T9sNEvst5FeAXu#h8!|Hh2SL<^?HId7ybA`N0{I43qw6ChFibwM1 z2QTi1KNKF~@9Ks%@Q%QBLyL<4iwpnFqyOh-X(^xyj-(}-x6byW$I74Y-6~)<%PHF; z;)V#T9<}&N+|dIdPk+$p4KW?c>dYrN-2egq&&^@wStq-O-~*t$UEOc^;mg;sows zaXN=CAW>3LQSq6Mefm@;YPWXvfZYFtGnbp=K6~J7$|D z8x?cSN1Zc$M5XiPyz=un$oc)LVkbC4bvHUw%xffVZO>CYg}xn>*|qQ>K8PtC7f~%k zaaS|qktjsUxk0tR$}T7q;(1V84XqY-k+h907;6-@9zed=b2`2sqWS`e6mI2^u7AHq zbcdVE5}h2eL_Q=guc;Ac6&e}}-z0~IEH%%`8Hof$$8PnYW_Q*Gus}=9=XSORVpBr< z4a+|ty5Z6+-KA#AOf*<*7#7O|)m5Pv-$ao|KKRUlT{M&1ZCVfKmaW#H)rr;I0*PE;dn+ ze5GpM`jK;E>V3Fg*68S{OPV2gw!ey$l!&C#Qx=Q$2^$~G*D}mfvs!je&TSpZS16zg z%*EhXpYE?1T-(ZPlz_~ z`LiPctx*jnDXC<+)0H>jMU~J*1rrf;`SkR3rdjL*GI}mg8xHpxo`1ZU=ZxnQFIc$8t?I;$0fG>`> zD8)^n)Me@iBTv?w+4>3|kgAPj&VH%$y;Nb`3v{vHWRn~a9E=5ib}Jo!NYw{AEGQ_b z4FGe%j2F$Ae2W{2G2NaR=#X}RJJI$jmkdD{==5Z9E&LmX9^@jEQ9sZDEOuonEaU11 z5J!&4X?h(*afULwk%BLOyg2Q7bs^Gn)B%LE2ETeS7i_K`=8_g-Le(K3riEWI@6FOJ z2RPtZ${*sN8)6j}5s?9Cr!SiBNvVv67b)5E=MuS5x#45(AuC@$0#-UP@~=qn1Rw#} ze$M(rNUMbY?_l~&%O+uY^gO%>$)C>SZW4>@>vi+dKeG7K+uG$(FcT9KZS?9lKw7Hd z(y0jvA3uJapPx_Qa=Bp0L03K@_~)Zl%k1+!Sn8dxHIbj9dKzvG7nPT*mD%N71yD#W z1Ly##n5M4e6bwz|UExF!x4oxeOo(Zhs9NrRtO?7_8&9WA(KLY(@?Lk(?W~uZod&o> zWqr1gl;z&WCtuEhCMK}EU0V*|u2!jot_IIwf?oA|T4mk14G#BYe);=H5oJ)Tf(ovP z(5x<9x&(@^>ebh7PQa+rCH{t@*M6{9Gl;NXfBh9O-pWH@og5&I-~_Ftz=SwU%k|Ao zYgboS#x&sr!v!)uj7P8ev_6&y-}+;RFtVtd8j%B-_717>w2?8uyggruVfXKMj8%Cm zswxfI0Jox_^maT`q;lvrS{T{5rYf&yowGsYgK7oQ_W%jw9-~F+Q)h#xVfy5|7J%y0 z31UB=3l9rxI~+lllJ^dCn!w2v722yThcVmbJHfjAqn5rK^9gYy8|3>AXPlT~#${q9 z6tMx{q`QotrKEINNSes#Q=&r|6ZPec@HpXc&O&)-r3-F0hqB{mn?3S|XBta-w71K1 z8e9_I0j!~>7%#27KwTr_H%_VXDJfIO_u>S7r1z0nm*+lZQxSU49B`v}k&E{{<-^~{#&pwj2KY^*r&Pj!$n__`dFu$cabbzoH zH8tr2CL^X34mfIq!=>(7CqTqV^jCU3a5&MsSyUXf7uHQV7urS3vcHSS4 Sf&UF47tY&TR-0e@+us2`=9LTp literal 4241 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 jgOsRq67F_0b+6EwrSn1pz}e$%E3db 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 XD%W(+27|v6Am^>GSQVeW^ZQ=`1wG|u literal 4220 zcmd6rX;hQhmWBg}*eD`{AOez>c`A@8Pza)Kp-ME)|M_12wx_6YaKZZzFBXg{tiC)!d4Z0~+o~qM&aHX|-d=B|ClSevrWd`m@sGL*z z#d2axFW*m%mE^o3C_aar@{bqecgPH!>y#qaTTB0Yo1oW}-0`}IaJbX>?N`|?DG>!V zJKSGk!|#9CyM|qiJmX#66@L(Gf#1rQdA?y{R$`cN;U_i7_4}j+A_PLUfkUj%LLo|G zCm>lzjzDY<9g0`t=ZA~)@j)NNLozM@)j#_&ykBH*ZEbb!tWWwKaQADl2i&FQWj6MJ zGdaV3!h8n5c>46|!dI`9RU8ZCRP!TT?4KE^U%h(O_v3Fi=P;WKtUr>>CAGD+G1VS= zKMN=P?nJR$Kn4b?HHJ(|b#SOU^DmRmq{y4z>H5QIglilh>E!Avp}_efRMgO5D5c{q zR~JA|fA;JdVXXhsh~UBq!Y6HTa4>4=Wl~{XoxXSU@+$&@zu(Qy&dw{WPnlkm5vTQC z>r$aHy-R}OT~=DI0>$pH`pl1dhNhucN4wv?g;Q1`Cu#R39Fh%#M!OIlyCZ>tfxR*L zg{7=`0(W;6MK)u0eSpo#5s5@hwSZgmlP6DDBv`u`!Y2;>X>^oEbST#N9%^yGCeN?> z97Lbr-x|hL^Sj}ehf8|2o2JA=LP9XrS-6yAy}XoduZ+}y2NMu{cje7dTwVjv^v*kzbZLi?)wNeb9SF2sZ-PVov4`@(z|Mr z@4E!lf*dXOBfRdisppK1bD0`8{d&-`YmwI?&}b_0@Y{2f1Wb4=Rnw<0CQS*+6d&DZ z&M0VJuI!BwiFZbWf!&Md%of7fsYkWK)(8Z`E0*4kTIhWQ9(&5Yp`n4^tC-ORQpxZ} zj`yoT$>$mNyqWFp?J>Lsp%U{w85uJi8VvRMW(i2+o9quUP&{|5q+6ggQ0TZ^GWqUK z9j5wRFj6dYXJ>~sy>a&`^E3n(GxtEXpXO<3%T=y?_wJqXVqSQxvZ<5dp!wcf)MlS5 z!+Tynha<9ZPw31E(HG@wQ!V;;w~7>~M3Sk-vTW~cXOiE_r!xB7Lme7X818%tr>6`O zErCX(G1Z$-Y{h(Ea^=)b4W0;_h<<5KT?+gsLxXK)W zWE|IwIVFL(hISuXJZ{z3e&2n~$FHKgIztDGL9cxtkstGJyLdi6IXUp>pHqUWuSvAs zLHCrq`=syg?iLQ}P<@uQ`(%3`DOwe_w3v9utTz-61O*4DDjcv>>5npEe^X<`Z*G72 zRg|R5LQno9sSgpx5 zkBfGu$)AtXZ491p$@Wlm&*EENThr>#qtR&NZ+`N#e{NI-!uRXO?QXG_9kEgpst#KH z1Ya`=t8yg)m((%N%F2pwXJQ(PBop9oezf$wYl%Y|p0iN$BRlV6S-Yr97$2K~KaiWA zp2m?qh`XPSnN#8VcmcQ97zV9-Wn}Dz`C?f~K?5Uhtib89X~RG;Vcf{@O+~f)*a%KQ=yo3MjHk4?jFS z{Ft5ksJu1az|gQez?^}z4}gqN`!%amL1yd&BHXQ7eOTFoz(6b|ugOrm<^ zrH@K^WiB6sW&YILTKiB+yMHV8#rMelV3dGNVx^`j=qL7Mp>o$zvebVL0qqu7AnI09 ziPydb?R*nD({4|eJ^?-IVc|IiPn`WW+lec{PN8~`(dJJ1wRamA*iDZpwta$!;y0mx z+k5)P3DTto`T+$vrtn+OrLUA6rtrybk$;9cm8nY#|A5g!)dP*$lNC-GXD_qi+oxe) zS@vWdNnu=ph0CqKJ;{H-AW1YL{1wiGF+e~-C>J7`uL+1!wf~*)pCpA7UJ{-fUj@Zm zyeN81j<;*kX|j>A#f#Fy31DgJu>U6}|33o^J);dl$eBrf6{&s1bZK70a%(4wTmR14 zS)4+;>CMijG1_u7o+?fL| z^Uq>o04_ZdelORkFORARfew0_PRQn&7n<2yV zn+fDoQhVH<9$wI`AOIg{^hCQ&ixFk{sNjLRtsb8jZt*Yf@K1vyF!RU4bh03{hBqmXA@8#3=gDqh+8g0G=6GP zQxmM6)tyu0Z{s;MCni=CvHUSB)hhdE_}L`QNkBzYku!0qor!?%kfy3MKxPf4jC&s= zzI}Puyx!P=8uifk+uz*=_;KYE`_=BId-jUm6*@`PG+-cCEQa~@LrBu-=qRg8^}7sx za-P_S4-!SdzZ{Hb?@#UU)f(#Rp7_&nBO*6a(qv(lF)=Z>_U!-L(_7ZR-LW--iit6& zBYk4I3_KaYi&v#jhxzN~xfH@!l%2ACCcubX!=THYSy5~+psK=Wz~wkxW=F<3Kii%B z#E)^JN@slsa?hdW(_l2>VffH=*n4ed`3$vf* zX&_Y16`?3d%1sW7PG5NJNXk}s-SkFY>7P3+E=F%>5_OD%$4>yl0ywJ+%yVT9THe!&>xLD-L%wzx3=_x0`oMP{BSc$^=rOqUr#+%?%Fu-Qe zcs_N!F~k!T^8(x|#!mYy^&!yYnCzlo6&n zY@mO~EE5)fu+Qu<9P^T>?%+mKDj=N4HGVy$$d0|~=9Tgakf={?ZXgoC5%H(q(KqFc zZ$kl3pQW(cXtJ{#6nk2?VdSUmshbAU)ObvLB2Pg*Kb{0G2gG}Mdmf|@-0Qikvw)07uZi`$b3Omi- z0O|$X8lZLM4S2L30;Tg45hr+5sw-XIbnbQA*A$z_DpcZer+d7k7$}g)wegxFjXANA zFaeX#JVFH$;H`RneVxu>kQa&KPQ{cx3iG0;rzdZh1f{)B{1sT;+(0kGHiRz@28M=a zq^GBkx1xiNiMVfP2t>(({67F&W*HO|RNv6h?Gccl!?bNF-;I~6a#HJJkS!E+2;VNO zO}D|kqh=GZyG&vX^CCDtP=fenZUQ)TbudwOFrj7}vlkxE0~vBV4h}L7M#jb#i8uOA r07rD|e!c`rHUGal@%|k%s@S(P^n7 diff --git a/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_2.png b/packages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_2.png index e6bf309bc32627086db301fb3e2c47e45208eb8d..ff5aae491bb172b82eba8c3c76dff09a54ba812a 100644 GIT binary patch literal 4210 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 Sf&UF47tY&TR-0e@+us2`=9LTp literal 4241 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%0AnigB&CeoHnfutW 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

>2vYk&TO4D_gA}= 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 literal 118994 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 diff --git a/packages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_1.png b/packages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_1.png index be1ab4d6f5f25eb3c3860f0041954bd20f2a490f..06e22f1b1a4ce12415f6f55a8e73d0633f836230 100644 GIT binary patch delta 252 zcmZ3)w3TUsWBq+k7srr{#uiZRYP z%(1RW?e}blPmlUcPQU)D>bHTjRN3daGt1w3M?IuFibc&5TfFBysIW@jZl7Q$ohWca zf#JaBUzvNJvWC4Dc=vWgjL(_8N3$ha80MW9XE^YEcbM`kA4T6~NSG5?3v_7m)<22Lr-B3_2cG31Gi;C6`2FKdFYaYZt zH<+{EyEuQJ)`aVYGUoOde%}`Vv7RUJw7^zugk0;Cpc~tCQ@$lnsGKL+*7$mt)3bJm zYo$x4e6oB#$5Zp732$kv`H0)2D*0wY}c!xybsoNZrRW!wxOj(=b@=w$> zb>TCAhm+Y|LY1ohJ{*-j$2hcwXGiWZTXgbUOx?@xYyG}o`TOqr&gb`Tm#R+ooL%p5 zD?YwK)5JweN{N?uVq2Ssv-6ULikB`3WM*`j0EP3G`^i{ZCfBEz&tLsInxSj0(;wcg zAyaB}-m|fnqdqJ4 z`=5^pb3C>2_m9KZZ-gfacGn;E%|4r7w%z(~w#*!!LizdwkAKF=hR^CQ|9yAMwHgmU zKeOr6uZM((8kre=N&ffeQP-b6F+h{Hhb_2y{?I3`_4)bs&*FqQryW|&67^@eWF++MtYeeCtw;mGO o*Iy}edLDBk|8xGnt+)eBp5b-PgWq*Ui3~vC>FVdQ&MBb@0EZ*rp#T5? delta 423 zcmeyve2;m8V||CGi(^PeW6%XRmk^&s$qgG%nss;I@GH|lZF|)~{Ml^g&&Q9Ae z6d;(nqQfM_MM_JFS9D@qmxr_K62bng2Y>6%SM7aPV#PS&^wSmfSF@&^e(LclDX_+_ zV&3tx-Aix3O}cHyaQ*evj}<<9`+q$wP?&sjMxW{a zEi%UsezuY8Kkg2+_1S03Ubn*~IVQ*7=a?mLzIoyG*A2O|4S06O==rD#%N$>LGiO#` zk6X)o?!v86g?959HKuxntPbrunj}(qvGb4F|7UBLqJ@hBG+=Ro%mQiZ57b7nabIJeSP$yG5pZ`O(nvR0=h6bL4Oh$axhdnfOtR^F~_Q mxqB=JxP&J=GKzs5S;M?FNrb<;u10_X2s~Z=T-G@yGywqD;c74Rf22(@FW_Y{k-WO1Irz`y^IZkO{^&#ViOc29NH2XCE=W7nI#YJUjMz#n(^P- zr~fiD=5lhM5YSO@-q65vkjaPznbT%3v-jHb)2WxA+wYlYUTariBMdih_uRz4rI#On zz8KxG=Ii6!>ECByF#yFhbWVZ%wf?>DJ~P&xZ-F`VSYCR>KWUDb({K?Kr-L|`ZS-GX koXsGScnHn0aN~ROPiu=j%(I;K4H&2lp00i_>zopr00e7|^Z)<= diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_light.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_delete_light.png index 57f4026a0239b18d79ba54479ffff3159c4be535..8911ab5aa2fdebdd29ddd4792e34ccb75576c1e4 100644 GIT binary patch delta 223 zcmZo?e#|t%(TLa6#WAE}&f7Z&c@G%~FdSqF6sdppZ2r1Fp%dyB+Gj-)?q-*6Qhjf1 zEbVY0`6~lMI_Jb^Y7_tS*4u>hZ`gb9`n>v@b++<9q@~3sC`LH6B```hv8JrqU$TGq zYI)WLDIb-m@p7LK&{1&S(7i{e2N_w>Kn$P2m6=dCbmua}`H}aSq&c lu=vF9qCi(n{LdzKO#IDr-e2Y)EMypfz|+;wWt~$(699hkRL1}S delta 236 zcmaFN)XqG?G0xD_#WAE}&f7bNeTNK092_0ACu--O-MRglhoNXS%LE?|{K%JS!{vL@3>DK77$uunQ#iyXC`LH6!8sp|cOTd^Cw{Z=gV()0cG+@EKDAYA&f+1I_C6E8?|EsM{dv6qAGgO2cIMMg=n ZKg=1M#dcih-xtpS1fH&bF6*2UngA?LV}bwx diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_reply_dark.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_reply_dark.png index efa8574b75057c6e566b4bb9c60fc256e951c4e8..eb2407025e718d7b848b434f04fa3a5b86da1c9f 100644 GIT binary patch delta 250 zcmeBS?qi0EsbMfEWgamQ0Kj&f#)ET5exST0UZTrIA_OvxqxkV-!4}dD6x`Trk*nK zwUp7}_QlQf;^Wr;`qTe?`)WJ+f3vueb?qs6zUck>^DjBgUq1YpS#@at(?b(Ks2Kna z|FgES`_I&d=*NeUEb2KM_1eaEQP%F;{{9LtN^E@mPZT9GN;XZ7V-#cMcW>kopPa}j eCfUTA@`vH%a{gUsvYyOf00K`}KbLh*2~7Z{UTVq! delta 237 zcmeBU?qQzbXl3T<;uumf=k1+~p3H$Ft{25OHc2EmD@{{LYCbkYEQyt|{?XZETe&38 zU4Lf8vpF(*uDHX2yI&X@?h8$3WE2y8x14=SZu#$*oGf$u+Fx=;>VZTpSh!Doc=%$$ z_36)7+x>t0_wlOp?fah{Vlo1X3+N~~Z)o7rzq|9r@7KjuhkUClYG%#*kiQcscyQu7 zHQoB`2TJv-53cP13Ba@@Z@y;b-@oG4yKk3;Ijm&)FAHyqiEwC3nC!?X%K7kcpu*u+ h))bD(@r+`k_Ggy!?`l{aeUAYMJYD@<);T3K0RV^iXo~;< diff --git a/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_reply_light.png b/packages/stream_chat_flutter/test/src/message_action/goldens/ci/stream_message_action_item_reply_light.png index e86d33395e539e2657263cb6e9b6f9581d3ab94d..ec6c889e52c84a17fd2816099112e11418b09d3d 100644 GIT binary patch delta 181 zcmZo?e#SJx(L})0#WAE}&fB{id6^6a7#w?E%xDl06bjh9@`384`u|-snbvfNsk48Z zQGAZu;XvtE28R7Y6Bmk2T*V7S1}xkscC3|qF#oRn`PlRS_r&j>$M3#5kx{aVHHAZL zf?|Y2n|HZcuVGk!fmhwJ=;Lh@KgvvE6p-|dQ+<$=1C&jGDK%U+J5=EiM4opNBd=Hu YW2~WI5$nTW-x+|w)78&qol`;+06FePv;Y7A delta 216 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 delta 1175 zcmeC@-N7@#p`P`Tr;B4q#hkZy&Ug3L%OC%Ey~i<4#Me#grcY8MD>tWWSHumEC-NIN z&f4@LKH^4zkm~+fS2d<6MS4t}@JHhEks~t4`-}D8J$!cT?%&$!GZ%lZ$T?TC?!4t* z@#XVki({`Z&(2zPk&EGv^WDw13=H+^jEoCh92hhN1sJ?oSQ>;T$1tf*c3@(k9L=Og zBF!&0X`Ra2n{rGI`}>Wd#(_+q9LOZbTNS0tzliz6c}r%9h)(^I^lj`7WuG4$Z0_ml zNy*94@!VAM^3t0-JB^*4oj2P`ZJD}m+TS}5XW!nQ|NP6#%lmE0UR+qXCU$q(vGk_0 zr#vjnOr?6~*w@>6Zb~~l>&?Br)}BQV54GOeU9SK9{QUE;uC6vNe|INxp2)4{Yz2e2 zA0HpjG?9Aw`t|8XX7)?>@6WIQ_wS#KO@+bd=jYEqd6F{Ew%Y7=veRt=ff;6YcJovs zH>G%1RsAb2vICl;6T8dA^V6rNrz2F4~9@B4Rq)y0f6KVmMd z0|g&EG_9_koUCqaV>9RE$&)Ic;o;Z$*WdsB{`m6IPnd^pFdv_7kCS?f1tg_1Su z{_~dH%$b&Vw)Wqj%2{XAsek$Q?c9$$7slS;?(Vw^3=m+b)mQJTIoc%}xh*F$ zZcoL;$H)8AZ*R-}`R8Y`o4fnvtgS{C7Bilnp00lRy2Gc~k_Ez+%nOs(Ms3ydEc*WL zZq2VRns@Ksy}3OFcX4+e%85b_z8nt$gMWIst_xJbxC-Ly|re0qcD=8!MXWPn0$NS|! zzqz?NW><-(|9m^&No(Tw+x`Cje*V>)iQ9mI|NiuJ{hbvblk)EDn5ZAW@6Y+Iwzjr6 zx8+8cy}4nS{Mm805G3(LZ_j%Q^iJi^PfxeMz5D#^?CA#&9$XW%(@5GZ=fon{?zHNV z4DNa+ru_z{rc)QY_p5pK$yh$BFVdQ&MBb@0K#2bM*si- diff --git a/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_dark.png b/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_dark.png index 5c7a7afaa20160a6c738e6cc91bf94b444a33e12..f93c0444b60245e0495f3ba149222fd6aa2a0f62 100644 GIT binary patch literal 4953 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 V!EOyqgC78kp0<$|M&seD{{wa|<;eg5 diff --git a/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_light.png b/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_light.png index 5dcce8808023654b4882a5346658589e327029dc..428591aea67c82badabccad3d2334f23ea6d8533 100644 GIT binary patch literal 4915 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 Q1Av#=RV!n%;hl&70henQj{pDw diff --git a/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_locked_dark.png b/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_locked_dark.png index ff99d92898e80bb0aa51d4c7361618a90cf30234..b60dc5659fbbcedb128dede97d37f166f4b664de 100644 GIT binary patch delta 6424 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 literal 6746 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 Qj}6G^rYX=8b$#)F02e+2YybcN literal 6344 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 diff --git a/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_dark.png b/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_dark.png index 6710cf41f4e4d4f3bdf814c3d80684ed7842e39f..e3c2592aaa8ebf0c1f123bdbd7976c92edfcb884 100644 GIT binary patch literal 5916 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 literal 5872 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 b&n{SP)qGN%brAxq)_{hpHlj?$D&#)^ca#-p diff --git a/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_light.png b/packages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_light.png index 40a2c8be8f07b21e0861487f0c92a935b825d18f..1050773f6e49d932e365e8bf159ee6c8d98f84bf 100644 GIT binary patch literal 5853 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 delta 571 zcmV-B0>u5V2Jr-tL4O-bL_t(&f$f>wj)E`{hX1yrs9-S$d@P^U*Mh{z!Gwdfdqv`f zo1K=fi!R@-r88fv9XhhMZ8bgs{?`e(ViuViv&ht#MW)8bh%8)ArnN?0*SOto=(-L{ zDfE3001!fea}Lk*u-$Iq`#uP_eO@pE+jDMaX*O9*O$&;T>CzNIR^s_JwaXz1aoTDfT1VI2H1SuwYN5&knHVn0i z3Q0sMg{rE?=46=~acY(CadW0OQ|3Y06TvHzFI zJ3tbl7Ny_7X+iuLk>zqZHXm!Ku}LDn?~l#Ln)P~38h=L?aoH%K!WbhjB1vRu6ug=s z2*?XaK7OT?FWnW!7^IZ+@g{fn%jNRzJ;OD--46Txo;=>DAVyL2k`rvTS{dyIOhq{7 zNRs4N>&jxWK$0ZJZ6V`V6d{CFAW|}%<9Iw;%{{6?m!_$+W`ytih~xOR4Z26Fs>1bp zwSGeuLNp+XqS43u+{Avy+yAXF1^(B?>K&Lxrp7EXHD-~i@db$H7-LgkSn~h?002ov JPDHLkV1mO~6nFpt diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_dark.png index cb199ba4b54cd488caa011481a134aa95be33827..0c67a41ec5b08d1c66334138f55559658ac281c8 100644 GIT binary patch delta 1542 zcmaKsc~H`67{`BrXIA1dB046Mn{GQDrdeo#*sA2ZUhRS_d32fOoktj=V0KtU>f%hB z2X;8C^E1TFKt)ANTcxHbP4Gxj(Nakfjbt%(v7OyN_x5MLx9T z0AHV#SsrRLVTVoEy)ZP2e5oJUbQU(#?=Iu8V z*rZVSVRAEEpZE1lL)|KZl~)79HUO>86WYu&C3`Wsreg z8}S`z;lTEPzPq4_iMVIcsD{=Te^mhhw}1nzL#D0>KFK_56r)`>=C}aN z)=#`U$3wE}Jo8u%!V+82GD^56j%}ppCv|Y_R!~k}0(s0LaPh zeH5sqz>0O!)QJ^pV1}3h!4%BI;kxLSQ3@0{Ilh|BaVckf&Fd!=t1J=494YJF(B3ln<)a4>VWO?Q?O#xAE%AFp=|&a#CBRDM+`c;x-&$qDHfsUd=~) zf#7(%TCW=r+**0KZgi)CEnTQmE{JIgsk`))H6(&VX?;H>FSKpL4*xs2+izwWRwd*e&##6CGa z8g)mm#wk00m^neDOQr<@QLP!xe17Bc5XgadV)2C>YHH}JiBK?^(%_FQ3ekI(hrA_} zC9c^@5&@5hwO-W4thWcXx4cjU!hg2bpBbg}6!mCwVi*rQncA$5Y1raApM2J%>}9;$ z2q>b&fartk$d=O6n delta 1490 zcmYjRc~p{F9Q{BP%>_*-DhXcih*eIftxtuANMsmqDOG_JTZ{J&7GE>DF(Ubef@tS&H8*Fy8n@RRd45o{rb5~ z=BFtGUqCm1?Bof}h`OMjF@}WEV&nin{>y}lJW;>&V!_|4t(0`6U-?3eOO9r;Y60oh z=qe--QG`HHZcqSy1AV|84tJp?sH5&^_<{_fn$!0IoP*QP&-yJWy>;vF=R}?s*fe0Y z3ze7?m5w5M6GmtRFZpt1Z5JpVciqmi}8#BvX~e<_?ddwWWu#c~O==d9vj` z!S)^wT~w@gXmD)pXSr#}H+s^$#yz!prnpMl@$aNXT02KkZp zY)Ere53uaNf((cgKC1@n9;IzT=1s#5=ikN*kZqI{9f9vn9uJyzs_i;keG|*0p`LCmv5uU`!^0^Y>X|| zjVP9b&_)&0+v%kdp`BVoJc&00j_fo8+`j$?%}aeNSO)IcjhJa$o9V{Lre5ROEBuwU zZVamIv0k=iL#N}7Zo&?p;=>0F%HoM$b`^1{-1<14Bs1o-c=Yh9Qhs|-%sdKeBzC#nvB z;~a@GY5KFOHFZ&F9ZXd_sio<3Upx^lNq_H1Af&Ei6Z~(pA^Z;z-ZqcAZmUY5WtHzS zo6ClHzFi&gfmpk$RW-4NO&G1B&HBxhQvPb&E7P{nR_x56!Wv{N9D0AHbg18w)jwJv zoh1;47Q!=1qXRfx2yX!DH&Di7(lS~c2E zb*oMBlM?fIFLnE8dbB<{)NhKje2Lsbo~ciPHRdS zkHx`5wlB@_2FM8KoENiFSV8JKkIg>L!Kw{F44f{PMhcsbe z(#Pb$R>-A_#c)K#$|B@BXEXM~f^ZiQ5{QZuy;HkPB#)306m3UbXe0D~kR@ZvLsxA# z4O>Jp7{y%7LvS|8r_oU!Tx>#0g0sn5p184Vi-|1Qlt`%z!nRVU_iu1!l?vjY>n)z=1`lPG zF17xhdIbxs=;1#nC#DP!X(LXIH;0Lk9@p)NUo=Ql6Z<+mbOe>0P`;mIYipGUtnrOl zd=aVy|0rYtJ>CBj9j5F(o525q;s`GZhupObDGG9E4;4eq=qQ&_{0X`O-;Jc#Hid6= z8glB5Lms4aESHK-G0k6Zx^mv{X4ix01xC@!ob5SxnLzE=&a>n61XsP1rL=sW$i1_d jOMt;5l2?;xc&#L(tXqNNA4MJW0JOZ0d%JPIi@5p^PV48> diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/moderated_message_actions_modal_light.png index d101acfd46b9eefabb3ceac7b7553bd98d135a1f..97ecba385dacde4a713fb73e00d3192a5987c5df 100644 GIT binary patch delta 1527 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 KMNUMnLSTX<9VcM` diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_dark.png index 92f37b9379e94757db824e043742733f9ec03486..4c6b39c5f02c0cb4851f6dd8e983b34c59a59543 100644 GIT binary patch delta 3396 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 F`#)6n>&XBB delta 3407 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

MyqQi8 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 N)Jc2G^5Z_&{|mk;*`oje diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_dark.png index 12f8f7dc9c6b7ce772589734bdfc3141978c6a75..e5eec7fd0cac96c3daa436da703803c52327ed0f 100644 GIT binary patch delta 3456 zcmXw62~<*Ry9UCtv``zYOrldqSHBgOnjQtUe$VNeq4ndCvz6t5LuNVSMy))aLOhEs z%_*3iO1Ki{aS+%)GL zP~z-#&OM=UVS-O7RQPwxq!tZ!EJ-7?iE5JGRO&%XcbYqL^4F73F0vupj~$CjA~&b& zyrA2x@5IrX3=I5Y@ufSClwSPZNKY#rlKW>CRkj*;tmsoE1CMxy`^ji&v8P zA@(az(kUT_q%P%NU*L1si)Zu8X(n3RA@NlfQYhrAYr_EaCA0yhuM0Ko8Ef4}^5EUI zZ5;8hc4gvmgH`2WA}sasmP5c!rmV6l%0^B+UCwNR z!+pLi#7XA+*TiwGC8SmWFVv=n!0@BX62`}#XV+c3h#MSQX)y+5L8bS2BjKuf*J{EJ z?Mq>*`E2r?r=3X*uaG8gQ&TaieNPgbEROuT6qFbdRTQ>x7~?8@a6F=DG`pDD(&Eio z;&Xlqt|thiUy~fCkP|13ZguNxLzbwgq5A>23AOIgxvSxkDR1Z`$Iug~ z6Lndn_I2INj6@2gZaUOPeh>yLopyA*8jv9rR`K-ow0CAx{x|%pO0s1q%JLvN{C0|; zgw4_fcXoB9VwGQKL(UkEf0SL}n4FxSUb}QR?>v*`8QqdYJZ0PaKKNf=jQNoS%=4t< z(bqbFJ-?M*Ge*vHlXY$CGBP$iXRg3tgLas&jE*4XPUpNvVOgpif$;Hlb9|wt;st~) z1l}{(DI2Io+naZjF^-m2Ajb1(ZrxpU+T$y^fB88|Dx+czXG#n_9PR zakZK|8=t=w`)gvTq!U@L6|s^}q9~r`>{KTCVVA9~m>YR;=Vw(Wt$h^fc*}b=3x& z4cI>KAn(-*?f~oJhj2ZjZ^R19AZFhxfvc+IWV*UXA?Qh;i;VbV+n2Wz)9Ga&f4t+q z9%T}viCbKt*x&xgm^}+mkSq}G$)po{GRUntrSCU8I^7hdbNxnawe7@WYd6HxkIAQ# z`{D#9hB;bwEiG13eG>k9*{c$37*G#+I}vq{=jXp`+z6abx?i9PN+)P@&cHS07sIc-c|CAPvD%WPA2ANl)Q)Dhn$P9c9=&{x*5MsEPOpsV#Yy}QbXtZw4bhO0I4X7TL zyM+@7)d6|<)_vZbNd}WG>=t3SR(wss(5hL_Dtx;1dtiAtF>z>)JD(pSF`ZPky-oW2 zBKbqv=0hHGJMd6Y;@#(S@#gU0_m;R=Go*)yp_IirC5YD`uu;)cAFQf(P(DPRtQ-hU zpj5yCQSAeuc}LG5`Ik)O?>K4~?7vGX?jFOrW-R&mE2$@gSMBWK-fY6QJLgXTHds~eL5C0}FJU6poIXernW=H)hI&5_AzH02y6W!VZi zdyp(vaUHw@Hy$}u18cM0)im)92US)QkA*D$T+@E%4!pjzZH>&}b#$bXAC~bpmShQj znzh3k&kGkW$Ymv(VB-9&{S|cEszW1(6VDCNdP+H(vsbaq)KnJ}SLOg~Vs8T%5ZP3-I#Yr^97+f9Ql#-?%>{DMXksIxOg z*j=yT@cX{0KQatyG;zl^AQ;53i=$)nO~r@Eoq{{+&ejXirzFyC7tIgl0`BbD@c?AA zMTP8+3&(kq@iwOPn(xD|Ynu$@>l^K%yLFSp@Uhkct=ls7HW9Y-&C$U7@aMJHbbF^-!jF%|1 zA@P0sf6B~&g5$M$nTJ!|iuj}X;pB;l&+_%yNy5!yxm>QC53!&4dZ3{ z_QPM{wD2?1Bd)AR3WqOaKAaT^=d}FbhWgsZ+%wI~+{C7)Ch>z=bYuO#H}pv2iVIANq0QRCyiWs~cmO}!j|1Sa+orJk>p(G4GzXSfXmEA_`n$F^L_hi(J&#)a zU|5vz**U;)mZ$L!b=;$`J$*gMPl8U{ zUkgjM-Z(qD>W73vBMox!!N`!%ota%p%XM646Y@=%`TpMI`>#Y%tvWCISTb1Q&>O9I zVPn=VY8vb~a%S^2k6-wo-hi20K(=YF@j}D(#+tTw9#<@2uTeHBkz@ z1X&21x9e&g?9L953Y8-3w$$!!I-NeO5@`Obn!#>s3nt?>2VJ$44%Wu3tFzgoMm z`hetgJ%BwMv!wlUaBgUu{pz%JN`K$cCm&yKB#w-Xh!ub|o*%g1=ZjRK6}$she_jyE z6}mzX?8@96B=^DI1jnFP+C4j*6&Q#CtUg`TG7Bw4o;n6c{e*%z!9jF@{{j7+y?>3{ zAmYzF(y@g^9R&@AA3oD{c18zWfC0A+V4Vp6DtjbFWQ%xx2p;@%Q3T?f$n)cZSFLn0 zpm;c_eTRNd?%nzVpNUq*urtHYP4_?T=LSdSjRcwJDYRX1j-Hp9eBxk%so*Yp1+z8d z9C2}=`Oe6AqA|&3;(X%JilEzVu1@iih`+XP1iO52daSG`af2()NEVN14OO@-CZj1-isSJRlB>5@QWiWto?MYT`t z&e^*xKAJ5L7cAHDaTV&RnJvt=cqdq)JKlquh=>{UZ`Gvj#)!Y2a#$CvwrK1Qj=1?L zJqZmp);Quyr?0Os;^}D6nJTp3+9Z%jiTS+ff_9asTtJz9w+>91-l@PWe*0L~cRF6(R{a)bZ+ljUjNaYD&O`@{MS_9 zjV(0~LCs-2FU2)(W(Mk_v0s2v`Mt?8|LVYBSa?PJZH~WkqPx9o!P~2zWLEeKj-Ixxw{1L z6p>_PG|cYG{kwh6^58DX_sYQT3mf?lg(gt%^SD8Gt3I;u&kt$a3q7e4J&vCS6o=S0 rJ_F=}n1kqs(=eya(@Yf9@S6tWvu7fL8GFbZ0$$F)x;oXK4@&4G6f1UTIN7V3@50F)iT&z z6;KANmq-}GAcH^%6d_oJNJ9by2tz7JA_NQ}keK8id++zox6ePnea;@%UVE)2L(U+} zz5=eE^ZhCq|6qN7w)D@WNY<8wPAla&j=g%+ZR7OhA8rIcG$Yk957>i zSAgHOm_CO7;n%4VeC*E-4i17F4}2fBkjvcOrIufa@DELhH{cY}nklAPqt(>aAZDfe zwiwsSU_{C$DeoRHNGGLA6gQar7_xX0w*p5&A$KY5M-DQe6f{(7+U6qB9iXMSSA~h2 zG1S@my0u`AleC&rrga$T>P(5vYUlBIt0>EW^1;O?pQ!R>gd#^$RUK`^pSI|mn4Fc; z&>6TMOch%Gu#)0w&RrVJmnj()KieT*|5BGE+OC)nTbO@jqG0eBdIgH`a2V{% zw>iByg8UM$cRnu=9>qy?YZTjgVTD`W9S%*cG2i-gCdVrxfvxC=xG7%p>UL^Fte%cv z(&~0|apv9M6eC|(@lVh5@i17>^z?LNu|LtuwzO$Is7Y1Gy4Yu5xE|y&A?@t!6dB}e zb(KE|kj;A$TKiR$#CrL~Gmj{m_EF3u3-cTpn(!P9wEJ7$#QM{r>QV zZL7-x*&#z6x4+-JI5koe4J{ZzxqoR9&(hN-=TVNp%m5hW#q=1$w!_7XAA&|WnHb)k z_C-hMUmqImqe5Dj65V8GFxbN-G&(fu>Z3>XEJH(`{Ur)%HS9TmS1Q)pk8mBzIHDF3kOA!)^1`@+=RCPDT|Wkh!Qtrw50fsL?Y)}#8O z_a-KQUyPGEZ)s57M}@L-(pwh3_52ncO(@!@bT;#29?@;jnUr88o3$NV+S*|)fNGeh z4%ydk56%fl2o14(t%AEw{y`oIIVrKRS%RQ~d#6S6WQjt?1LpO0o?gmI>HUieu?6hQ z;FRuj3-o-ZD`g9=9bcPN$)Dq&X)Ycc3kwggk!QQbT)#S4tSS*K`C-qZqem(OsJxyO z?pihtY)O@Qfj=2LR`?~KvYNtsHZP^W{vBn-I)Z@s_MOwG#J~;#Y^@7E{+wWE|M~9w zwe^|d&Z>>j$+1}}f*@$fH_Y5nu(wJ5yIe4OWoCNrpg}Fp_2h3e zi8w##1%y~^(UGNi1%luBq>9tq(J2tDa&$&vpBY5oP3=3=KMNAN4dK$&*}z#JCz=o3 z6zBAIJmZef{t1>rHm{=Ki`S+vt;vhYfGs(-D}3HL_nww~gwH3~$nWWn!a_gZv_oX0 zy5a>7SQ~`jcVhXD6=4%48_<$e&g>3kCJW^ya(@$am*f30=~;m$9ra#aBwk#sJ&DaH z9H(a>#bU9nA`nPENoS0Ha`h{cS|9sB?&LPe-(?5`w&Cd;{jOd4-z_%*_+SiauL0X| z%M^Gm+GTZsV#EIM_I*SY@wSY>ASeUFK0oCx+Y%)!wd8qp>Lw!(}zzjNIg?LiWf zgguotRoyUw4`xRan-37%Pe<$zJx~>|u>2Hy!NH$1S8^7^E!3BPd>NvQDLR&ptiDX^ zS5--P>27_jc0hZjxschdH+r+e@3>5&*&0&}8+iT$gPCfMY_N{%iLkJ69Upim>6gkn zyZSrEADj-70J|iaqX8-uyC<3wF>Cf}PO}e(y1?45SZQ{0X*7|k_vSZM-ax-vN?f4d z^2RUkuzTlI8A8i6x`E)s9$mwy^S=YDE?Zu&GDu&_hy+5z}^TGgW;Y9-VDh$ay8o#D|)s_n=<2_u{2baQn}CBoUvoY z0y!=rX_Q=vTx4Xe2_ROHe)L}w@#9!rW-Z#L#f2KgYwB}`^NM4 zs%rHcHu!fEsDyrF9lIpsd6DAGJ3=1X!Nc-x_i%@+zFhOMv*5F?~W>-?x5 zWeIu$cph`pX650&g`nQv-k{iKt4;0X(|^+6>?YZgbchm zim+J$k88TsDi@Fc8)6_>J8t-}{DkfIVNlM&GGpNh+r_BXpAMjX(U2Q>eX({%p~>sx z(9>Td|~?+gf4+XxLb1)JW$y2(*aQLzOYz!62M;v zJ4(KQ%sJZ_LjETNp&z~MON!RLP(aCmS_2tK#m&DE-`LoQM6HUr4Y;-U9LM`cE#}&B zg*f*r#dDT-&J5ksaTdQU@ z8Gl3N)Pv%(DfU|Jw)y9CK0i#gWvyEB8@Zk&BcPxaSICWJQ?t_UAoTU2rB^W6N34&m zRqsRlphI4J%00=Hq2g;0Uu|vj4Kl>=GjO-CHXl%FX|xw{rzG_dBpEDcfLu&->cd&< z4rJ))0Q8<9l9Lr1=QWTCZY#Sh96|5PQi-@J>w$Wqr@>2}y74dT*$hcU;HO1H|8dPr z<-BNn(Aw`-k{fGNyOh_9kb+FR9nX)tw==u1c6HhOusXg#R7Nhn4jYh04;c zC&FIEM$N4nCGaRl_3q8Brm>5RB$4B)V2+P(dG!h997+95b6@V13iRf@nW?W%gSTDD zm(L_b<+6nV{j=Vea3@o^lh!pUu4OHa1j?2VJT44`QLRu&WiK2PQqnxVc4q(HWu+-q zP9=DGM>~UJ2ydF7bJK8?3;9YW>HVu2MMu^A)CYBkl|ec(1Yz@*H?lV}M(=8V-h&(F zHuM9-LTJg5iC!GsdF&;#dEvvovAVo533d-p78+7+Lrs7Njtx~#K4SalE+ZRn4#K{aB4KUjBf<=v`#L<%zG8CtQNHTk zNIamLQAwUqi_WI)?$#_!(<%qg^>wYhpGkqiZq*eV-vC1hgqjmD1qO)_)@8{`j%q#7 z^SjlO&+DxBmx^39^2|u9zKly`?rRUvCs$RB`Vqr2cuQwzRBr;i!)xPyZ;H%z21pBnGRZJWOBdjQ(2g2d1+vuY41P1DK^G3jL;HBtk#V z&1_O#%|5y>J{FJ+*Sn5mzeSt)F>@2WwG-#T_--jvHkGWMXoPnF3=*v~H-HUh5xr?J zy7T*4=fRjU3r6lL$6oGkOD4kp^H8w1qwZCyKc@c39a)LTNzxNer=KdmJ|vP8ag&lUr^8)3qX&~K>u5=-&1cQ^ zjoj*wyBex9gfAZ-m+wBsLZOJ|Q&H_uC?56;%-wWUqxJO!FE#8~^i>G>oI4ZX+w2p4 F<=?|Z9W?*| diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_light.png index 16c3c34fa3ff8ff471e05d8f9b8e836120623e7e..98224204fcb427d1bba81917bea81865687b96c0 100644 GIT binary patch delta 3690 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 C5k12I diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_dark.png index 77aea6972b11591bb5c1e88c11ab4cdc3b5be2b8..5c6bdddeee1f4242c56ea64a035268cc20fd709c 100644 GIT binary patch literal 8389 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 V_AV_5e#61`tI7FOferN=*bpf^IqlI0}d$2#AUi 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 D-Y$-8 literal 8456 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 D7Q03* diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png index 365dd24050e20187a89ab2ee20a016498ac969ee..6817993469ac1c0a83973c61bf261129cd50066b 100644 GIT binary patch literal 12166 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 literal 12082 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 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png index b329b800bf6ec714b33fc8df0dc48c5d0d588222..003142a4a995677192ffb5d4e553c496dcd35a48 100644 GIT binary patch literal 13555 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 Y*){yFLI0z85b)C1G1jiV?fmrr0Ny5lS^xk5 literal 13269 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 literal 11837 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 literal 13104 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 I>zopr0LgqX>Hq)$ diff --git a/packages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_dark.png b/packages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_dark.png index 9b7f30f4b57c09d4fa70ee0b4914305103977a67..ed516899af6f502e5ff0c089c01fa354278bd95b 100644 GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q|Zo-U3d6?5L+am*446mhtCe`?;smk(U-y1#W)%;uXRy3(2R#@tsq4(lfI z)Gs%Iarz;6rjYREBE)T|M>Fr^p9U}-+g2H zgP;HY`{V29+o!GnsI*T(fQ8AC5K;DeS6n)eUHrC>&udEG^1rOG>E&;~yQO+#jU&tw zuyu#7WYG%M(Uik@%sgjJ6H)?MTBbxjgp6wG0h6^ U-}}TX0h2F-r>mdKI;Vst08q2K?EnA( literal 706 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q`aPZ!6KiaBrZIC?QV3OHQsln}bObf>$#lYqZYlX;i7>rvM|4K-}BB`x3e z0`~qCIpdIfOkz3fkBdj&uph7#=3r@b5Ev%Jjya}39)HfRtgW7JI} zyR9I=!sLidEc?s;bM@heWtBVj&;H93R#8(G*LQsS&GSD*rCFLB6gUVFhthfqXBpmz z)wxzA&V6nQs)j>bc1QfaTXt)EZp3M}Mg;*5reQ;T;O*`dyWQ~1CVJUX<4B-HR z8jh3>1_q|to-U3d6?5L+arBaP6mhs{biYwbfG2Ij4t@4XPdk~vry2=NPS`TFtv}B} z&yjs;!8x{jvtw4hXuB18{c9$J{x6ei#)|VSOpXcy!-XhI=Z%|oys-9j`n3wX3G0u$ zKTfF6KlLWFvB&UO+Gff5{NK{o9k4FnZ{sufeHSZ=$CuSTtLGdApPapnKRATWqRtHW0j9+ig zm+h9_{{LOtI)=avF-x^(H#AqX@u5=)4b{(_=fVRN1RI_RX7?UudY z3h%zZ>%8;K^Mjd>`G!%(7=s!@Z+C%eBf{JfVeW`9cSM*wB7e*s5$28vb4P@^Bf{Jf zVeYuLg2S0R&U4GI^} zm7Q@rj=|*f2!CI{Dmxd9-Gy#zr>sZ+46i)ORi1hAyrL`s6dza4`d7$>!?{_ytao!{ zSrO#I=Ia-_u%&NwS!<9B>!u`GmTGDy%Zi{E&g>`4a`w?>MUV@-T|IPJC%Vb9BFKfE z_6(dO9si$mv=e$y8%d{)Sb4Sd2Zy2R>$iNq+R*_2!haBHrwA*;Dv^YLKb+fB`V;t^r)h%k3Vm^&iO9TDb^2y;h-xg)~d e5n=AsobV5sAb>ya?@mqt0000S-;1@r`vL4O`eL_t(&f$f;hOO#O*#-DRXMWrm!nRYca3{8z_5*8w4pjd>s z(N&vvq6DRzKwT9Cek7O@D$OQjRx=<IoV!G%E~et;nLFUa_{aBd5o4AL3Vb4NIH ze(S^YK0kQh%RMjc?Ce_P5ayx_WE&NhjtWahg{7my(otdQsDH3@R9HGHEFBe=jtWaB z&sDJfu?Rc&75KFQ`+EZ@Du!u$25N2v3JVX0_I6>vOd}bO0^3_4|4raV0MzspRB_iy zFLLpl*2bbpex5x3fx!^Wz!VLKDcJTw0-qbvZ}**H_HBlv|^m-w>Qmf5mW@SoC~n|xVY z3BIgD_=UYbwkYymW6MgxE==JnzOZm5U)CY~!jGHzvKpSSWu@R3zFh%&P!O*v<$@Ha)1bH8|0SUM^!9Tk?23QI?YrK7^qQDNz*uyj;dIyoo&2iO>JIlqKK;{X5v M07*qoM6N<$f<6Eixc~qF diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_light.png index 56eb4672a0430f5bc3ed840f30d8922682532b3f..37c0587773ea69a6e4011b07c45bea7273bb706d 100644 GIT binary patch delta 566 zcmZo?eZw-rv0lv6#W5tK@$C%T?neO-)DYd8gY3GBZRwnflIdgF#|Lb^Gu+QBz& za5sgO{bN0-*PD>3-jOg%frHJP+p$^9>MUE?!P2y{_h)&o|DLilpYORQQ~tZ#f9v)? zZrxB@&ba#Fp*4qFBip$*^NFX)>YcHQnNhmK;B`UbHLyf|E|;)}ih z@MA@Q*3zAL` zdN^^*?c6(g=3lC8bGF}ZFP`efdNgTbiRq_9vz9Hq{nl=-=km)2Jj|`15V!_k5a?Flw^6B87@28#=*_J49+DK7Pr|VJw z86Yjwf4n|r8fW3d8asa-?b&CAK$0@uM<@8G{kK-1>ZK^cCHV4-bx7FhsI_eCum3*( z{&$UC$m-BVbA48DbT8^~Tg*87?dy+ayJgR&2{$QRSmBnw)g-ch{dEbx_8l>L^JkUs zzB?gR@?yr6Fx6d$7&hE~d*S`}LL0gH=Qx`fBBu#*uw-0YsL#XDeweZOAj9v!{~lHv zNVu%N+I0W@^4OzNiGOa*a$77o?etUm^TsoIUVXKiK90z#w0u||b8h~$>yv}tG5~?6tDnm{r-UW|Vq^}{ delta 593 zcmaFE(#|@;vEIHWAjg>?d~|V&RluZN{yGEUlcT#O<2Z17^0d>bbLQ60+L1O(jgS9+vW?v1Cr>2amQ_EB(VBYb*Dvo^SzivFO%rx^mtS`7 z$m2qub{=!{-j&7mKWpT=yZtp^U#veo)$8fOnNe%MEqJqi4fmojdj;`*dvhnHZjI92 zq$6GQ@L+<&w4*mB=$vkgxnaPwNoW3f_i3rldNO?N|4)PDr%n}5i9CJ!{K-u@Ct95s z3M{(#!v6V@B*PiYJTJYpi`h2qx=h^d!b zufg^0+dYTtrE*t)$jVKdHZQT>{&(&DKh_zu+M1ioW9q`pV!mDazEOv}^^p6Q-+xyY z?^>rky_$Rf{qvjo>Ju4We66yu)m?D=tzQg3Tl0yu;ty4O_pG*1=3(eD6zO)2iI4yL z#b%;MLiu;okkHaaZN-PozE;V4Ee+!Q{F!Upwzxv;@Bg@tx603+x%&}jJRzdVxcE>! Y<2|#f7K?)QRx$vAr>mdKI;Vst0R1W)_W%F@ diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png index a9f0c98372ce521fcc2183b6fa5f0c0c98bf22a5..2fd8bf6deb8685d0382bde4a2c5eb18212359b36 100644 GIT binary patch delta 2564 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 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_light.png index 5e2433e806ff8bc26581341db243aaf359b40d9a..3e0b6e8cf39e2597acbb2446d62b4a63f78d5fa2 100644 GIT binary patch delta 2592 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 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png index f6f59b90000d2bff1b2ced41cc9a1f8bc8d504a9..2fd8bf6deb8685d0382bde4a2c5eb18212359b36 100644 GIT binary patch literal 2918 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 Ee<-YNj{pDw literal 3413 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 jNYXq2_!(u3guCf0DartKI diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png index cac18319fa88f8dd8484b6ef8c6c7e9a28c207eb..3e0b6e8cf39e2597acbb2446d62b4a63f78d5fa2 100644 GIT binary patch literal 2971 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 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_2.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_2.png index a7daaa3051b9b94032c5054b72b58ec7b0d95195..abadaa060213e5379654969930788691d7802abe 100644 GIT binary patch delta 2160 zcmV-$2#@#l6!sL5L4P1gL_t(|obB9yY}EA~$MM(o+WS#TTM8ChC@qy1MU>x_pAm3I z-HdLEjHofw7&GP%hSRvXKbN>Io4C#WP;^241&7=7BbTb0Lms=BpCEuANHGSaHfSj6qI`c%N{SB^hdd4XXn%PrH4{Arpr z{0g_n>T@2)apG&4RB-5$*qch|hEdusls z7ZwGztJp7($D>E4EZ5w^Ic|@ZG6G4_!BYqI_~xI;i8=aaWmGrris=5iPpKw*oZF+h zs{G`Bt=jY>y*VSOcPD%0^ZN9&IX~5ZxB>ce;WBRuy5rqix$`%2Vvgp2-l>~+gmmXM z&tCL#NK#c!sqR?ttZv=jp}AENIWb4S+4Vbh$GhDgEhSv$O~HGI)~T+&USnFKdf>el z-MR1?HDur<5sbDe5bHQk6ZQ|ghF_sSO<1biwmFid zm#fw&6b-vQR?-M0Nn4I?(<$ea@;YKFKN8dP6YfZAeOkO*3maBzYSX{Y+l>9is>|-u z#QH8}hr4ysIjOBjx4Au1(g-AfNqd|3N|LUwcJ$7e1&Vn6Nv+R|9F{*88uUjHNeZP0 zwXSf!uC7TOMXF9zyFF6U2qa03;p38|nbp#NM$JoleR2D4Nm55fZlBNAAAK-to+_#m zUmxx`?DjZGBakFDh7y64Hn*uNr!=Xxd66R;+nzWAwfGCq%Y6OK=Q)>uYFu->B&oHt z)$MVT##O8&wMG&zav&Pj313dH*A4Az)|_Ln_I!V3%X(eevR;zZl@`$3MGvUkGx&aA zo$%)<5RE3jjtsm&2Hz`kfke{N<&DRB{r@YD|3ewwU%#U_E-CIA*n5`F#1oIJ%R6v4 zE)qzRa{Y;Oht_~!d6C|K?b^-g?o_tZbjHU!)3X#G;G6o+WJIJzEy2WvjA8zPciu%H zN&50dJ~+as39b8jwI=N>?;`IXI<-$`>yIvLtJ)56bMdF0WOvc;05=NDybY0aCus^zm@uW!p3uBJfI zppRo((;nS+;BBp1G*puG-LfTakCYNV50Zko;(B!Bk5zlBR`Wj(Yw3qkEm`=28iOO; z9<5&}2sLWW`}b+}0-rXQ1yzz=td;Xq+bQfejvy)U$fE~;CohxF>(j;wLA^E2uNT+< zK;usxaCLAbp_rRIQ$>{I!mJaoeAX zhaF9tUHpn|pz4G(oF7ji|d)Kfh{u&%X_chV;ixkL&e0F;$OkOZmC;0>gCs_{I9h*hSnp4rjKf zd9OZyZmd*wYjwZ8_2~CDgjIAbplzcjsiL7u9*?89W_Y#p(%#=#;mcc(4iDsM!mx5p z&!47=d6%Epx!ph@7m-s=o1XdP_uA1|sgkBH6*Wh7EXS+rkv^q+Gjwz5O@d;J%WjnS>+zdhhj zwo^qQ=&|kSNBYH%#2b3EY7%!K**ZS4f9&z;kM-YkE z?Jd_6uXUaF*u{oG(4)Tnux8bS)tFwY6%|ivMa7e9OfS`}ny~8I2i^@A`T~If2DZC2 zqsN%6(b_sbq(z_X*VEgdkR;_t_iO9;pvtpGyFH#OI7vqjPSU@MKyVr^^PY}C00SrK mlQ9Y{ldlP{lWzeK7XJq}!sd56u4_pE0000 delta 2155 zcmV-x2$c8s6!a93L4O`eL_t(|obB9yY}EA~$MM(o+Phxq+EQwvn{A;&3x!fj zf6%+$xA$Xz95x}!+ul+9w&nTwtL^o3dFL+AetX~h+}GncP6}KAzEqmq0{{aVlK}zF zlOO>&f26xTz)KTRI<{uV1UH{$?NgDJx;$M zkaHA|$F-?xv)0tCRZ~}!Bq`v;HM=gPEB2?Uf4I$2elV;+PmkN9_N!1vhE8Pp)s*K` z^@NzVln2zE;gKX24=d6wla^_A(JXo7aeLHrLLld8(~-@3^5Z|si8{&)#&pAnj;0(; z(+7ofwC$qlI+#6LN3upKm>zI@)P9u}38^@ERHdDbs%oj$yynf?TN2Z2Gkt2$N|WE~ zf7i+@?pM{wnQo7IP6*^2Y&p73zpY-Scs#D@^=DJRXd-M6LmEI({5eABdA*! zJbl5(AxSm4Wx8eI)4Fkcm*&=lxxz=<{5f_ zuTJ`Nl^Ka7z77w*K!)Bk@-+#kr^_3U_WAecwXTyd)_s;+J&Jn<_nxJ*@xa#BE*BJ+r`OP2bzvB}BijF`1*bOEGlB6p~e-I=V8=B9| zc{J^!sT!X%UiGTifkLnDu6bUoE?xeW>uR$rRhwO@+@2QsV?jkcKDGKreJwM)<%j?K zt7?kUbu>3!r8y<4f5ZZ^BrPYhSAxZjP`BJw>N(r9_NkLq3J-G2_s_&@R{7*w#_CZ8T7d@xuK!Mw% z4G2ZSX03hqEOGRAH?Q#N`NeUq z-t=SLTKB5kqq*kx+L!gr<_GlL)oFTbnok~&M=Pe?r;?l!w?|7E|6-k^?Z-aU<2!$^ za5Suf&ZzEue>bertO1Q7SoQC8rDB+^D~F*=7~%6&2fvla2(EV?}>f- zsJU9Te{Hn`^3tO}*bvg#W0~4EYKp3wYUJ@adSixHJ16x0!U~^XdUQl)z9tQ?(DcGe zP0qjMyw2?g0=a;6IGuWO_aC&Qxmu+yJsNu=qGP#U)sFNj-J7B7%dXRsi8soh+aH!B6-Ewd>%@R6vPZi;o-25fj$XV-{~`jx892>*CISHryhsO= hQ2~CFAOUR__&=cP;1on zo*oF9X#c8fcBW^a&naXkH9wMX*UP`Eh&Ei?QXpE8e%=GnYLgKNK9TQhf6TMoc%Em- z@)SjpqpC_&s)ACN>%Ym?G!43@L)Q(MrUlz_U|IHgk9B6wB$yBFDv=i%rpW}luA|d-(Q-QHJznD)4JOSJ#M2OESpoob-9XRt;q`r3wgb~Jq3M_F zD5$CmMOh%vQjCK~2*)E-e^rHOGR8EC(P_JI?ACdY*%)oOw$;cnBFz#+lK@I7n5KpG zD_d}T9`Y2!i{{0LW{xrw#)4FEti2~d>zd5^ZVrGp8h5tLH!`fFGl zZelb#Kv5LUOt->{B1bSf!1|RMvCQV65qyvJJFQo$r?jIu1?I4xX#<_5;W5vt=8 zUINOp#5kDkX>8j;e_0kt($(Jc)(%D~g*c7?0K<)Ih$kWPJQHoB+wG#=Y5vl4xW0k4 z!FuD{tut?)XNcnn!_8{|fOs0M^of7%VA3o>r7D=Fg-)k?63@avSl98juYVJ-zWSxQ zBb>@KOuX~sU*J36{$8WoU1r{R5~AC2VVEYWszRD2jn4LQf2ti!Ud;9;Jje=mRKt501fSI66{IG)rB#&vsm_QrEh{rch2L9M-3 zlk@7jak7WgbwfPMMNvDLc_e9)z%;GJ{*3m&f82X_{!wcd^$N{p}C$<3~UJJ~H77bkp-{x(>%_ej1TU<*VuNKnYZhDP)cF@-d&i6 z3BNyVY_5;nQo&?df^js0W!t#*+)D_8Bk}#D%g(ZF^!sc0&)qvH@*JM)!(QR%VwO7l zf3ocsOv6H+W!T%@M$a3p^c6tUbi;txA7FRqzbNt?reUshENEgK#&tbtnuc+3grkE8 z@CU<{KB;SpX<8TzhB(;YLpXi}P1E4I{&|nJw55YF4GV6!4*)nie2BfB`|$c}Xt%pf z%(s%-9T#4IfSv7ocyu^B-*LNrn8xaVe~=n`2t3PDgp=9Rca~*i>)LfVtv0eOMV_Ui zhrs9SI;(J3SJU+4hrkV3wgcOCkW6Fj?amHEnx>)W`milN1pb7g%n?Sx$=%pa$3@5O zq0@0;Sr&{1UNhOgcNcLS;f0q!kNt-`r+&}+a0~Gygk?K$obx>=n7?LHIvf5Idh zV|u(MWEduTu74@^EOU(pGuOn6Y{QMK@cIJ;qr=DcO0L^SFgijoI&5g#=3V9&+0G=G zxw@~)-neyp_6n-5!_ZBXRe>}~U^@<`@dOWcx6f*1u_s=YwH;U{UzM%JvTV_N#)pp{ z!0q*+X&S=gRokBDBN_+DiyZ0xe-vptg>ARc>v{{VE>p8s;^3NPDZ=pxw(YF^!q=+1 zP{A06iEuo^VEqbu-fYc6DTQ!6f@xat+`)N|_=$I>=P*+9TMalq6ahFnG;z;zFQ4heW9Hz)9V&QXQWm=0Ie4WLz6QIIg#&ef5bb_jkj%s zrmfL+EsW7H*1+1!_1|PWjsxW=DCNTQd<1?7-w#$j*10*CV5+)6Q7&MNIgia>DArnN ztD%iX+chYw97-u9afT>NRz2R}1`VceDiq}$T5AA+QVMaBB1tlMz7M5bIF2*qk6bxx zEsWOax)w#TK#}J##$b`pe^6Ehk~l*cM5`WiFwT|f^+EO#byH!HAHZ4**L5-4oFI-< zXrp0_fwcz4SOAx6mjpOa%7No3D5c;k7iF1acJL5dYdDUBjdYA42v}G)u3Ne>&Y^kskm6Mw??y zx3@s`Ni%GWCaCN3BXO|% zG{zWIb&1jD1WB5~T8sJOVAW$SZK+_Yx`5Uld_TZ+Ya4Z4UAkrSGOV?z>k8AYZFs&9 ztvgh8vFfpw(mNPye=Uk)0RY$>PtmpwjM1WPq-lyI8Gh+`WosML$=2Z8?K7`28g1KP zb36qA6y;*A-&DPWshbMM8n~{9FpSW)jqC?2g|C0@tN8qDpX)oqsXW)i&wlhveEVD9 z9dx_P%-gmtq9}%PT^M6fH`SoCJxjfVX}iNf;v_|<0#z-%__JHn}6zx`zZ zzz28l47%NA=ha#x$+Dxb*LMZkI~aWwiRb&`RnfI;+xXdyLZ3u2q(OH>od6h z+Uo#-f4u$of5Emp#Jt96_`ZMmwO!v;WbYGqyL*&Ec3+-MUkKST3uK8iz@Uquu?z9Rhoo%it5 zU;G&F{`;L?+Z}3N$8it@ArAKUV2nYQjMjFyf3(!?4f_YX=yZ##+s{F{uIOykgxAj9`uLi&^UED+nTZu8*#3@o?_} ze}W*qbhltG!*LvhVT6af51@4i&-K$_QVLO& zV0N&FqFBIj9Aw#e)nhGf>A$S!`pD8v0Kj~!L4@6%dzjA- zZ<@-|O?dA5u8tlV>?ZK0sWHzF@4jv~X1J@pu8=l)$(b%`6# zzxc#!RB@c5u1dI`xAKR^thL8)in=OMmIa#n@O~H9^{|nRFU2RzBZCI>$Pf>*e{D{t zNYf2eRrR4yCEpK_&u3UHhP^FfNPLh@C<+rqVbc3i+3o8egHj6CT0~I{V+^{kh39&x z>+(Xya^g|hAcXJnQQ2O6KM?IQb|2nD6emzhp=oLWKoEq;^Eq_ap=}$qO@knau#t|= ze9@DJvlctou5D2kIf5Wu`x9U5Tkb*y4fbj8yV&TEyljHazomih7Rl%DG$j?+tX9%J2Is81LG q2>g(7Twq*gli>%8k?#)|k^ccXt^dz&9H}4x0000I diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_light.png index a2f9afc0bb342902a04500c6813471a03c8a4998..a74ef2d5c24ac5c44a4104827aed553aef56f17b 100644 GIT binary patch delta 1634 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 FV1h>M?Gyk2 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_dark.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_dark.png index b9fdc003ce2dad7bde8d57f0794f7a69aa0439d5..4d3e156c1aef7a3f3282eb5ab7e6dab71ab58a44 100644 GIT binary patch literal 1696 zcmchY{WsGK9LK+1WmEEy+^A`EhgQORl7~b#Oh(440oIFpk_!jn#11A93&Jyx*Vq`TY7huXEl7CxiSpZ`{5S0D#SC zeH75#*AS;>uj!l4z>YH2gAUf6??FD>5* zm+i_b(xwH+tInMbR~LU;4$Zh%XH)Gtv{zM{$3%>{o{T3_OO68b*WL1+{|BjKjsM1k z;m~;VzpkU?hufPsJUbW|D1O1Vir{mT-t%|PhRX}B(-ED*c1f!PNwS8T?uMH{IH*RImKk82PdTZR&f2(;VYLBe>5Nk`>EGgGx%M zbOf*x-D!TKu#@$$s|n3815*6HLm-~^1x^Ci@H_&j*fl_hDa{wOldkUF!GJ%*Y?hue zGxo8z(;DsO3r8J!7jwQ{l$IG3DNB4>*VRfb77dTe?IFnBjs8P|+~V|d%pZhJ*_$B6|>#SVOfAfXA`6<_wnmF!2GnI~TJV zvbnKTS^dZ<9J&%?IS>8Gc>r6n#f99OZ=ic+%Z10}yvrROh1bl)2Q~8xSt9#-tx8H3 z(G7Yo=aA&>wvT zIZ4~tbXYunLMF7NiS(v^)jQ0w=AYIcVkAQYh=a) zUp;8?(|zREapE1hR644M>K-T_c}0cZqFN7tQDrf5;a3qtYP?h=T1%gZWs^fEHFfMo z>dWHS>?zZsgS|@q(2z-&C zO8uzwM~Y{bJ#o0Cq%3wycaJp^&Kqc3%_R>Tf*L>;D{=Y5K0sHNagMnBmrPEF`onTs zCQl(ywjdyU-a@kLQO~p5+tJ*H4-O&T5goZ?*D#VmAvp0ZCb{jvE-@1fGPUOuLQk8s zNfR46XxlwtFO%OaDBd1_PO7v!D1$RCb}{mle46R>d4>*JN{q>RF357xu3!@}+{il- zc=n06S4TY<*t!T=W;a+kCfMVU*PS$e_W`MKv3s_$c#pu#rW3M@=%Ax{D4&OFZRM9@Uc%KrWKK^*t6bq{=GB_z?AkwR;LgexV9 zB^Wz7Q@Qd%8bNq3IR#+?5&Z9iJsO$mO)J%!KgiVgKhRY8n_iz-nX8|nu4Mo;DhSzn HJo?tZMTQv1 literal 1626 zcmcgt`#aMM9R5z`cIud0#xuF+655;`JVcZGUDi_+b35TICekpMxg1F~4uudMA(u>2 zQ-pHAJ1leP%*vYOGQ%*l#o75I&iOp=`+1-Dc|Onk!~4tUj<=`NF&R}E0054;INM(k zY1qG%k`V2f#fK=7fZ{GV*#V>p*s{oo$Jx1{q(qY}6_x`465=lQNK`^O`;!M&+eMAA z`K+UnZbfFen`WMaL0%+h(H;_xXn@Sc(Gblpi41ML<0)g@wMXv+HR#61(o8kZnCDso z&a|+*c>gg>x88u|gS&{szYC`*A0a{ye7)W$7XF}h?|(qjigdDqKkjCG4abbCx)uc5 zIIB*V^)}Rz3GIO=t<o#)b8Zgk2!IENz%Tn_z)_qb?WKO&DY9*y;+p~51OFkLU9=Pt|TJ9a8+ z_JvXS(cW_q@p}V<)se&&35;=XP|Gc|csg&xTAj|5782S`9!*BW2R&J5Ti02G6A|8db-u5EP1WAbG=2(Ic? zQc*q?&t5jQEWG#i`dsFs~hjuORJ^*}<9JfEF_OQ<={U36&|^asZc~+`M@o5$4d6+IdK1pI1=md#+sv zPmZ~?Bjl^tejm;QCG4z-Zko)pg5M;aP38uCx~;WD9ezRloVYOIz)LXw!s`~WmsY)O z`6VJk3FIg~7k!X~{WBQ4VJ%C&Q7s>r^><=~M&(E^@*C?f zV>aFio+%9?D9f8v#K_Be)jsaK@!xOYd@pDrkivLK)6UY)728%D=5=oKq%GaDYrTEP zB4lCrO5d0}xDnh|KiY&WCD*L3(_ikUOe&*=_|?5Gb?;{E8AIJ`%gJ|3G;nQ$Wwnm= zF|9y%G*se%KNo&xyiEC4TiZ_uyS%jP6=lhfS&8~J5oM|bi+R>OGcu?Bd#Y7Om3b+p zmGedN!$ji_gCQMRT4gof&ty*A=!N${dzt*=x^oB>TfA&*8Z3keAsCH=-n{Lyua99Z z;^X2*M~l%mP{z8SV0@;3pRRu*k(%d*%GY=GMmp0m(WKKkReKA*vt8Dc+C+tDk_o)l z37qS^cizwk3FL-ku@X_tf_`CxkKS3%fV_$+Ehev+%7JB)wC4V7262WvXm zNCY9enfqHI@n7p=4iPA4Mcu0b6|E)BCtQ{IP^BSS08Q?7T{mgf|2T7HIrxbprO>wr z?zno36>UiLZ70#nYpo|4btRDB*3bXQd2U|XAGf=twI7iqxVcL4QS5)f6r=DW zXn%AN^<6DSoV?D`aIp|1dHHoM$+b%V8p^#79lFNQ$PiDjBDoSB(J49~{oMi{>MNNV zlIaDuXC&ox++vqTuS^^Y)Tgh<<7-GGr{sGMb0uTTI diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.png index 5d5d6e1ba8a99941e35e32e54bb35ea2efd04335..e1d90e5977f0a7d79a3003fb45320505d58d98c6 100644 GIT binary patch delta 1276 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 delta 3455 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 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_custom_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_custom_light.png index 38e1ce5bf763ad0692a58e9a8104b7d985131e6d..6cade430e45b896b7b604d44a0a4b57091745176 100644 GIT binary patch delta 3408 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 a{|6r`somlT5=sC700{s|MNUMnLSTa8M^0-1 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_dark.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_dark.png index d0e6aab285b21d49e58420a323e31f11be32ece8..a5cfa0663a4db0e269985e61d59cdd9adf240caa 100644 GIT binary patch delta 3135 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 Z;eT8XRQ7`19?}2+002ovPDHLkV1mI{>eB!K delta 2965 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 EKSL9=HUIzs diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_dark.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_dark.png index 6d63fa50ba564aab34c696d8a43e6185542c94fc..b1cfc6c8715f7b1ffce7a2e8c9addf9139549024 100644 GIT binary patch delta 937 zcmZ3^eusU6V||;ai(^Q|oVRylGp3fx9QgR&GF^Y$<2LSZm$EjSEZ1!N)+D;OXN$|U z)N6;9%t;XO6u;;izHx=Zt}kgD4+VrrY2w*{yjf$dH?hC7#nrQCli)1sGR@Cr1EmVQGLXuro;^@tcMdk zx!Mj+65(l9)s#?W&7U?UD7c(a^raSqn~^gQ-yb(K>$o>xJ%i#73Ww#^GW+@(zkGGa zCH%RXlyrJf^!*M}+V2kTfZD#WhGT@oEBtb&Q^PmAXr!D`=(RN(!JwrlLQq#Wj^1=tJ zYZ+oH0)^L3h6Kau@H^+4TDy~scgFPXonLd}xcpaUgJd_; z?CZ7%wq!m(`pj?MpZeKv@6NU?d}P6JJ@)>gN!j@d6FrVR4Z{8Vua}@nFci~cWruFc)QZ~b4#tk@}@J@?8b;|mdhNf=sS=s-e`FCwE5p)$~&<@{fxcuiP&+3nk_5Z7DKHgl; zaOKLi!t;AyYwGLwpG`HY|M=;exWvg6hK!w+mfnc{{8F?T_v-AU$=L$ zvb8lcwz4|)dVOB%hZ_tG;c>OR=G*QVWybHf{bXu={~e>kOrJ~p5|yuBeSSP`)8of) zYL>Ul@B7c!aI^T?rK;PnnyNRZ7N`HKueutWJ;QW&rPq7c&wGBZ$=EwNL`!tGwb=*j z^*Pms^>??W$@cn+A5S}X^?bDAybWEd6BVY*RZD7Fu22d*P+0 z$gk(mcYYQx{PAGljlGrJVxP}0{ChNJw#reT-u0HA&sji83q6ACF%loL3Jr-h8mBJZ zzCC^aySHzZyEYw-nXcj+^ntNXd1m6g7ZqJDMxJJ~mp(qZT=FE3czx-llCGxnhqW{{ zmo8h^_~naNk)^~*9z%-{+BerM*YQmEKbYWo>HkFgUEYYKu7qse5B82wi!RMWMNAAp N;OXk;vd$@?2>?%O!RP=0 literal 935 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!jX2nVq2G`C*rM)m8e5UE$OU;qXVkG3#Eh(z_M#^D5(k@S6D>va;k}eZ615 z^8d}vm-gDH%?mGzWe8Av@ZJ0SasPR*9{o8}d_FhtV*B^^T06}cK0NR)XGjy!Ar1eK z)Bha*?AbFF&sHbL=;&xGE2~K=JJ+r5?Br~9Qau0X?c23tVq#Oyrm1>5J3GI6^XAJL zk#5(w@84(V=lf3*>2));wOw0a@n)v?(jYGtp_+wVVrVzjljm%g4kQ_|Gb zv@-3}&pl>lW+g>MN}gGnnHOKYSg~r=Dx2c#*ROXSf4tOL;P|m)SMJ@5+a|ty_iif- ziwP>GW@cGgSzcGKUY)ly#c1WxqpqrxJv}cSIMA?b_wKK24r zoh~-UGkx4npFX{7*RDw_U%z}=v48*moOpkK|E=4$sd;j-HFq6NTD5-t_cKq5EZ44I z|N70F)1LCVxw%r3k{|DO|NQy$($^n9c0@%-zyBInQc{vpQ4!JixZ;_fzW&xNTS9it zn=>b*xOj8=v+~;gKOb_gZt6Pv`{Vqr_xEM&zkc^_?9J}0tK{!;*T|nc%#?8K?~fVG zAEMDy4k7*r-mrxeu7CS>`_k8M-=amietNCrW;pdj?!k1w&wSqU&@@x@WJ>88#hCpYt2i(13XQv7`UgN ZQN6?RT?`CrqTca diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_light.png index f914ffb2ad7ac1090e7af7db6c7b8a2a718ef87a..c13687d05ca7bd5310a1536aa3c545a48e301296 100644 GIT binary patch delta 843 zcmV-R1GN0F2hazQL4SHlL_t(|obBCjXw-Ea!14EQ_h)y<#^$y{4aBUdz``gj3XzCW z^oNXy)q_zIWwi>^%7;A{GKp4Mh{muQ6&d}Z7!e{xNm0~L`)4AgBKyn6ZoAv>t|v14 z<&6qq>uc}V!{f8@%-EJ?vISdxNaup|Y; zU`Yx_y4H(v95XOD!bEWrfI>b;TWd3^RBEozCrLA+T7QRi{KNoMp=Ci607Jv05W&K8 z+vekpk_5ATBrHx$(%RBYHk%=v&Cs%-iQ>tpElHX$HG>sbDr7RJJ}qXm8REDym*h>O{N~Oen zb8{0u(b?Q54aB!)k79zaD_W!6CN3@Cp+X#l&2pkZ1j)57OG& z0>CGIpV9Z}9{#${Yvol}&~euq0H&s<*u15ik&)5FOno-X1NV1w{(sUX0DQIY8{XOd zA#ofh<}O&altx_|B(Zolm&0LI40d3NhdjE#*aepfD+qwAryEMBw_fIWM^;De9) zs8o{MIWAj%Dfe~W4JQ{oZr;+(z`$T)CY#A{Z)XRWTznA#{reBH>-D#5-o>UTA0vt) z0JiVk#r^|7oz-{o-S_>x(fcmb)6t@9 delta 801 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 qqEINJfeIFdLJIi{ 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 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_inverted_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_inverted_light.png index 1434322d641769374f83e6abf9f4c36d9a049901..685f779862a9faab874c35e94e5a5376fbc77a5c 100644 GIT binary patch delta 3211 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 JPDHLkV1kBG2J8R; diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_dark.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_dark.png index 77a1e1299b5cb0309810757bdd71ebab47c21fa8..da0889c86b1b4a217deefca7a87e6560e39db6f9 100644 GIT binary patch delta 2965 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 LNkvXXu0mjfYvsdx delta 2790 zcmV72ARavDm6bN-aGv z4$NtX-lja$%VGVJNjhYBx(a3Wnf0t0BmhDngpeE{&2#{S5Py;^N?3%DoIweT5Rx+} zVG%-d1|=*)NY0>yMF`0mOQL;ICX+!`tcJWm0RZq%{esuyMlcvmcYK5p!ihS=QkAHo ztI*-v-bWoM3(;pongz$v;TbZ^p^zZie(45xRr=c>fe%^7k(UvQlTrLl( zRH}@}LEFMM$$#vF2-=D&xE%I~uj%yF7;%0`XCftpiH3#-G&eUxDwU$IuMcLkInyDL z6j9NgWDTuW3zNx&!ootP<2E!jKq~$3TYbZZ4Uo&_OvjI=u&@w~jg8Rj^`bu)OB#&^ zn>TMpNl8hjLy0PC(VdWVtFN!e;lqak06TZ?#DxnNn13zugeNGOOa_HQ0l(kRWbA09 zQYlWII>jYkv)PQkzCO{OkCpQBavVQ?oZCNt{ycvE{F%|1_$Xl!(U?poG&MEB=kwv& zvu79?8HstU(P-ozFI~D6dc7VWK4hi@(bCd_>gsB^TrNC%^azualY+j#va&K_mS{8@ znI^1-#(x(}`0oG!YHMrJ)6>Ib?B&as+3^%dwWXb&?zB_skF2dGMOx; z@0CiW*tc&Vii(P`di82--n=>P@iQ|s5&NOgywWPu_+ruP^{A_>gF>M|ZEYw2Axia>FH_QxpN0DmrKz17ZnvDKR=(_*Jw0Z6<;hXR;-BFU%q@flX2rQ8jWaa zX-R5PK&@8C-A|{(hYzE^z8*6(GkEgk3EsYa8}nFxoEnWLrPEECVUc+>8Vz(h9RMId zKYt%}b#-x%mrA9msj0!njT_Ta&=wjWD`G7QG&VMhwkVL7mj|QK2&2)6yu3VS;|u;(s0=-Zt>|?OQy5{yYs)&d2{97>&lb32WWDb=bRi zF96`>%a^cPt#QYvqWdBet!Nxxhe%YEH5d$7yLK%U3I*!w>Jlb67K9Xy`KwOT)6+4J z<+oj!OeWFe6N3L*63y_!+Xi;**pcwGT&zxfpU)R}pKtf>-B7F5P^;D0vwvq#!trT_ zwMeii8uORfO2n1ptpNXQe5JKY1%gaMkQxmr+@aD~%q#9&d6WWQdR;#gn z`*tXmN_2H~VR(2rO_9zgD1TucJ$e*3ZrnggNeNDzI01!1flw%f_V#vIEEcR^zaA|u zEs)7%@caF^e*HSWeEGsPm;u1V!~`x~x`a?Dgwv-_bD!FsotqmKO_Tf-8(yR#w8}@x=XO319N(w=-me@S=92 z_|~sqk6pWV0kf}tY-|h;hePxj`S`#4MDK-t`}T1w!Fs(OXV0D$HNJQEfPaRL#U~#0cKZjGJkO@g4s{!&dyGBc6KIp zywz&u>TlVY+-x>m((wfX0la+qGEI@i=5#vY_xrg^fD*;+cDwQL;lngV7at|8MWUyt z2X40;YPA{z0|P02N={5nMC^b4`jugX(LH?lkn7_a92{ge?vEcoBK~MoZ7>xpKB2yT z{ff0~*K+&czJGm-d2BEk#KnsjVK5jlHZ~Ubwm)KXyWLp1awYdT5lUE#h{NGn(9Fta zv!SZ03Obz*cDp?-v$Q}Ufd2k|=Hmu~K|Fu{oNFA7b~>NQ_=M{1?Zv89tGN43#YG3IHEpn}` ztq~VL=Q6w9j<&WouBgrGI>Jo3ckdn=8ymTcpL2oR?S|QG<`z}#c6$=vl{`vVi`@A5 zcuE)5hJSni{ylelnNOcS!Q=6uxVV^6gvkpAgMteBLJSNHa5W;I&zEra#=^+R$b#!j z;fn(4I(6;q>l3YWo)Q*Wuoo|0z~yqGu&@v|n=RAfh+?iTR9ae^@}fm1WXqxeD|GQQ zndifY5BU7~GcbDr@$1*G;~qaVGlQX_A@uh4ihugwXyyzL4@blo?~V*Cxm+&v^zeZ_#EiJ{w#6(K> zf@0M+AXa>_@LM(btsG+L?d^rlW_I2;bVd-o2%e*MDW;9%NLas7UOQg;;1 zRD7{`z22l|)xEvF7#<$RIE06#xJL07*qoM6N<$f>|DKCIA2c diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_light.png index 12b942eebce4b40d47693ecf9aacdfb24aaf9925..efb656ce3b3aa6c15bc2eb020c6a994af9797615 100644 GIT binary patch delta 3020 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 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_light.png index 26add2a992128086cff58e7dc105ff0d61edd644..38ee4cfbd0ce9810aa7db4f6054affa4ddcd379f 100644 GIT binary patch delta 3154 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 Ur3=eU3%WeF_09BZbzGzW11Xeu^Z)<= delta 3414 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 od delta 3315 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 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_timestamp_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/stream_timestamp_light.png index e8a6642fed02055efc230b90c2160281af6a8d14..88103910e699cee105a46330998a7c2e32a46488 100644 GIT binary patch delta 836 zcmey(-pnzo6&Sj6Csm)E@>HX#c@9@oc5F-Y z1bZcpukt72113E9KS4EmcWLQK5h3QY7rL5VJ*A91N;20^Zryh5$-c^W^W?u*y^a52 zb9wgj$a&m{9~MY3h`hRbFYeEu7lCVX^Nv0H_wU4a{%6mVSKjacUGG2di1_Bs$u}$F z=C1>SX|_xYGNb1D)l@!qJM;G4vG?xoA3y!5Sn@l*ukX=$^ZZATzLn|R*)1-vA1`v;=rJ` zprhkYX-&+^4i1h3Ehf53O!Z6#j=o(T4GcaJ!AeRB45}GUE-WkyR7(4SVpCR}6BHC^ zm~_X8AwdAZPqNf2efSKhCO>^UcY{wdVWU7(xppRR)(Fb zFQ3;@W3(-lA>>}ncIofeuRZ#Gd;8;Ns zjs%7DpYxF*Ud@F}U^p=Nec1@KgF(JD2pAjMnryO zV>*!WY}ef%?>;6oGA5MFm1||4zhOoD!32Ts?rxB~;?{?MW3dpnpTeYYR9$ECMCOpm dam)^4Kczi5^`df|Q^gs8z|+;wWt~$(698s@Y?S~2 delta 832 zcmZqX_{~1Sv3{wii(^Q|oVR!P=1)zPIR244zA5)y!GjM%SC-7Ry5O-$ak=N=11U0@ zty}*$Uvz2b`^P9H`GH8<$|K|JdshyF8&0TH=t*^J=<<^m;QM0>go*J zvK$?0{?}K(e*Jp>wH)IGv$=8letUk$&AD^0&$?gk=v;Mww_X2VK0N&6^T)>)RoU9l z^x}H1r>7m;X6o(0aBRut*GEr^xw`*5xmW(UVvB7%&J8a}}wO{`f?AWZ>FL2lp*D*|x}mV#7E zEjR*F?L0*cs5)c9B#>&}U@wq@Mz8t~pdBV5cR_Zrtu_YQaiO5p6{ss}!KscpcJ+2? zyYDjR1C^?->N;`eS=yX;-}!rhTDEwI3f`>#mILyI!)YHakVdD;Aj7s?*`W-yLHC=D z((pLeGt`uqF-n)=K-J3E_l zKL>_ofucYUNIm@ZH9tA~_3>TlK1Uusx)~7}xwe`u_`wE{Tw-pn?z-6D%ic)}7ykS- z^~Q}GD}Zv3>J0=dQ*%}`XvF2`>D~MP==6__O3Qnebu~+(fetIW33Lp@N)RE~2_oyI zRe?S|u%Aa7=FppZS_ zF%J|u5|Kcw;#OC)@FbU(im8f;iM^UVJUX<4B-HR z8jh3>1_mZOPZ!6KiaBquZWLq;WN^J0t9-mKVfUl})y`7^jJz{u|KmNk@_}mky_&dd z?^*tAm9}Nr=A$6M!sIx-iEoS9d&+j+TXy)PN!2m6+I#C?{@l?&&u|KRqk;ej6K=v_ p{`9ZbRV+DE2`R*H%utcFSDe7bomf+U9+VJUX<4B-HR z8jh3>1_ma3PZ!6KiaBqu9^^a}z~FMwMdttu|4MIxY>|W4lGtxG?0J1Yaaq$|o3efD zZkIFtv+9*&a90!HU}{tt-o*2Z%x=5w^Db|SaXW9Zr1rnh`sdYOdKTJnurxXd;3isr p?#jD=QTf3NLJIL4GgM@MFlse$aq~$hl>?I&gQu&X%Q~loCIE}FjAsA< diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/system_message_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/system_message_light.png index 2eae251442f8a5afb6aa1e2b8a03e28adff93e4f..6767b2dda2686e5e29c8bb681ea35b682a84dbe1 100644 GIT binary patch literal 659 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_mZuPZ!6KiaBquZsctWU~mmISmzKk>6&IvSoiZ1rzJPtE2pmzcef9hk5fJYD@<);T3K0RYr5dyfDB literal 659 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_mZuPZ!6KiaBquZWL?^U~q9P$Z^avxfErx$xWw$C+9%rOZ6LTA51bge}B8s z=Ro}Qi_8zsurN6)2n=uHp;gs^jQ8iWqxQdkA-R0ZooO!%>-**zPGN6U5a3|KO&9=! psYi}6{i&k@2TPN~FeeW2&&%d7zgztHH!xu_c)I$ztaD0e0svb%g!cdd diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_dark.png index cd0a0fcf60056f05e9fc4b6f129e21acc2d7ee1f..4fb9a2a3557c53b25a8f187f04769094957a8f11 100644 GIT binary patch literal 5583 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 literal 5513 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 KP2OJo-~Ivi8?qY! literal 5688 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 Ii}{a#07I3B00000 literal 5440 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 Z-IFTHmp(b0g+o6uKq5HVvTbO${sQtM)yDt; literal 1778 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 j6fa7L#9O<}3{#;-S|40B%ZErQeKjY&62uRvX literal 1874 zcmb7FdsGr>6#pb&xs_|NWNPWLHr=F5S6wrf)Z-)5w1+5^rdv@YX^PpJq)DDKNMg;j zm!@f@ruiyD4aiQGmdB`AMWxhaIbdc;IrPAAXQp%ZuWipZf6SdbzkBcZ`|j_~H|!1J z!Lu!FEC2wrL)Hdt0supXpNq^*;XB4w=LQ?2)J?(upzg8VDC`)g`iDfC!`C76oyP$% zoeBx?i%c&be<3<4?^}@llJ}=1&!aaz(W!c~v0u_}CrofZNiX+1{4z}M8xV6%4jHio zZ%vl$IkJEA74tkmaq#1Kj%dlZb_K23$>BE!#ao7q(gM~=q_6C>E^!kZB5_t!0G^-H zi?&TAxwF@F@6sM3?h{VGd+MC!X5B6w^{9JvU{{!{SNh3)Em_a;LlxxGBF<0$4k(048} zA5x~PZ+fBG zKJ|$xEP8Uab1oUQ4bnn)Qms-HkAr!Wvi^PwfvMXo+W~;*3k@_<^KglQaN+*Dk3y|M z5?t}2C)xV&+3+1vSnm61)2M@?(>^bDMO-AXb1m)PWXu9(tk|Ha!4C-lESzBQIr}Q5 z9~gv_adUFH@28=+?gqGN8m9tlRrje7xL-_q^cN;Y?oHuzl$>rbF&Nq69Dh#dr>)&6 z!Mn}ZQR~;j{o?l@K=w84AmY`+O8kY^$bsPXDm9K{svJMX=TZ*RPP?13K&uFt1C(Bj zNBW&Sv2A|fp$jXKXWtQ|7|>isLnl~Rqzo`fuA-K>y#R$v8_6X4E?H#+ ze0H~-?U;nRoH?ZNU->g!y52SG`y(o3HB)+jkS%K3vRpCJbHbTE`0yGOkWoZU$#~Cd zhBez%FXKt2W_)|zwI9gA9ZpX*t8vC)PW0iGc@>J3>-<7iA(aC2z@{33{R1>Yb=v$I z_l9Hl6rCcu1#oyPoS*Y@qq6l;?lseU3a;tLPlFL&1D3CIqwg;hw|Eah*1*yZ zW}4#sqqbL&87VYr5)zr&j+^Q3{eI$T8%F0}qI%{cF$k|L1jE5;164us2MrcrSVWKv ziq=gY^Avc^25sA_vLbH7L$)>y9>OI{VL9f`gGYgl2;Gj1#&%e02RC?v{y6(DVUQq` zHDpl5$;HM`jH0QHu=GjYy)(vKqi-a}VL%xP5&FN&_Vo_scrx`F@-v|9lJ?&+OgvWZ-O_T^y@69+MS_n5{hM6dh@OPcoQdv95;m}LGz@?e5-w1fnYxjl zI4<*uDL$;J`W|?1pbCAa#kyAmEE2Y++57Ouu}U_aUXJfV9a)ZsI`+J%m8seNRAYHQ z3I4cFD;e51*!pvPjEm!lnuc{MkT`Y;XDtGKu2f39e6*%nERLa153rz16^a7&d;QZc zeZKMtd|nncId3Q7ceKPjfO_QIJFdu?G_hE4;Tz}SYwi4&>C&ws-`Bs+i&aIz|3wfI L7#>jPAAjU;bo~`w diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_light.png index 4b873c709dba481da848ff5a56d7818ac04c41b4..59404bb8918c8af8bb932c5c314014f19e6c743c 100644 GIT binary patch delta 1696 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 diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_light.png index 86a99f7cc913137c4a4d4cfa53d1006f79ba6013..33dae720bb3324bf0eeb08c9f948229c4874c5e7 100644 GIT binary patch literal 1874 zcmcgtX;c$e6n-Kg3RVmeEFy>scoY>5t001qL?Iek0|5(EK^7H7s-SGarItFCKN(_`wkljS2s=cXOZdQ#2AxjQ6yTjq(ar?e)bWKkC$EbwbJN~z^FjmhXZES z)*C;TjpTW@v-0SM8$c4V7JjOC0fMevh&qf<8f_=9rXP9at5GhHJPt+7YN-ksc_f za%*D*lf@~*Y7{WBBnxe>!V6C(WAU+FDvA{~wY8YMts#cem7s~*$WC?smH-954-CnX zW@q=z_B$oorbv4ZPw+1qwT=!Czm~GnXyFvdxb+2XlmFlp)LUY>5ZIr^=1QOW2d5XM zO5CHuhId`n0mU}KJ5qNDdI%aNQj3*l#c;fbM3C!F9 z_AL}O?(}lBi*zf|ynRNOBCe=3%|S5lDbMRH%Bg?HAAHE;$vOrPK#G1nq^YZsrFnTn z(A~Q-s3o&wEirTf&=F5cPO#&?9;$60(+c+hRQk4uYy(a}P^Rp|IhpJw<9>Yu<*>4J znPJlGz?fe|H2_SCL;RMGd}OCDh1fhzHC@o8w2wwuq$-CtAho zk_e?%Hr#JLX*_6Z@YN9G)2YOTtF=M#W(P)@y^XWKV_mcwoS9t#wGBLS1EJnw6kSc{ z!W>emoZ&}1c0w$b*EC3X?}zDTZOG_)e+JtZ%#koX(s<(OgK^{ICC}9XH##UNWEUr7 zbL~bo{t)A*h)O_BhX+q2+Fn+7&$?Q!ND+yh_gd-!m)j5|_IJqi(+}tueP&%-42q?v zimudqMTI&gpSc`u2&nwT2O$CiZOd{M@TDR+gLpnBW)YB)Xtt8t2td8|6oZKI_6jX& zE36ep2PP{WQE#3r#?M9{I*SzHT^9kkHT-(4^H=$-+p==UBE?D672cILj4_5ug(qr_ zB|HU}ufm6R_a3<9deiUJ`;W`UwPt~yf2xBB(Zd5hif2<}jx^qn0wC}M%PR9?iuhmQ z*o0BY4{lmlJNWpNjVu6>56jqdbH1Y)2d&=B+xbIn9`CNG^V7SB<{iJA9U{UGGE-=o zm}JV^13-mM&_uHjtKhv*xR1ch>*uNgi%QA%%$Wuq9-pju)pEheAlwvC$+zFQ(iU#& z{2H*|-f#334p3ur!zt!l3NzS`-<(r+`(W{2(=G);IoEq3ejlv-Mh3}DSC7OK*m;KH zaUw|E_HwB2)3ST3;ZL8$JhNd&CpPI&^&*A(59LCq?%tf3dObzTR(bLxHBd)nM&t^8 yUXAWCnVCMn9u}i1o}H=vf9Ud$srin|Q^%f+)LE?49=-|x7lAvTgsXH7J^MGJ+#7NL literal 1811 zcmcgtX;4#F6u#_>P^zMAu?(W10#BW0dtGSCk zly~+XE?0Wzs&>5*22OG_3a}wMTx-cD?KX>KOX;3p6SH=y9yuxPoQj<3oE8%|EuQ!4 zmUVPCJ7Zc=#+rb0Y<7sEB^&s2q!1-+HZu3h>?11(*Y|REDmR#S*u90avG1E zPZc)FI+6`kK<8D~{QTlu68$+Bd!PW@y6SX5^oqb#RK;d*?4M4xJ->Q&uqo4ZYdFqo zpQK5BEBMeyqtV;BCMC9c8XyRhm~ftu`yg3e2yw zY#&<5DY1(QhdU=%!kj8xX}mql@~0n|8g8eDPr2}H1wvsFVW2)ZOAp|Ks=UbGnzQA& zRoQUM;^fQfww2iC^xYS-CjySk`|0uLTTyE}}ZJYy1c_8~^G5JX&aViQ@ zytDZJ7MQ&a)>5g31IcO|YzMZN&M)(EnF%_!0H5lmOqVG+_k_*bGV=4nP}@q?dea1n znVD>g_Da?$l`@sGaD>q#gZbvd3vPCdtyWGufp?+J*AzjeV4qw&kQ>i)1W z?sQD-aTP!uo2)4mwHyo$Yg~A+Edug~H_OwWLxI-M#vIrJsas*4Adl5NU{2Z#a=Qq< zJ}gxN9hD}AA_&jo&^ZmUgcKUb-P6-u5(EI1l$I7j5b-#s?{lb*27nVZNPl_AQcd!q zA?5)zofL{GcHxjFzv1knE*KqbXrt@+Y2o-T065=YUP-8qke*vvf6ln2BX4X=AuLJN?LT}#0MvH&PesHP zeeGjU_zu!J`na*&;ubV-%=EqMj;JWa<3IQxTZzAHRwO`eN~j)g?)7(5@pkt1m?M4r zdo_T=&BD9+6P4J7lU4Xwuh#7H3IN<`{u}zgsbkp2r(|%c&?wa#Vx9}80;=6?Tr#zM zBg@akNweoNV?+RSvSa8)8wd}JW23|7Rw!dgBTpo<=;_*kBcg=04cuXsbVu8jEcv!R zQj^@HP@W-cYinu)(o_KT7<3CUCM_}h&xKOUX4fupxtD4_RbxQzkl10%|8pXrMg4MN bzPQ%Zs551HI7E9f^kW15m=JWm5B}mm`o8G< diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.png index d0da2bb493a681276516a0876d2d5e14ff54cb0f..53b6250e6d2b4382fbe553e90df5af766f366669 100644 GIT binary patch literal 18847 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

Z!uNo+$z;Wez5mPr{w|;YzrvUQ eMFLK3u)v>BF*qxd;fSupxzpO3IVUat_TK=!aJ16^ literal 18790 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 diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_light.png index 6be35a5c05e5765aeab15d8ed18ba1449f73034d..4d5ab3a76741e7b1bd4b011964cc691ba2c2db09 100644 GIT binary patch literal 18325 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 literal 17821 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 literal 13767 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�zEuwqCM^}NI3 zcB7ayJ{kB5o|UzF8$oOx{uQW6RN@wI1NXSF>ZiZF95VKTKekzHXC?ps{rgp)*;}Tj zGB`Ln1;xDd$Pc!y9oPKtrS9_!!QI?!u*p&+FcAk!>2aqPBk>mC|HJD24oOqM8x z?UCG+AY=8-%kuk!F|8rK$qFOA^$`)~;oeSWUzfNoAFt5u5E&GKoNWZ)I~Z4@@3$uy z!^%%-_IPwpwp6Jr*BaiY;P7ym;qd1u;Aq+9o6MX$u*ek*p4;5Z%d39OC`@o?wrZ_f z_b5m!aa@%LF~(pM=jw08J6olC=5#@e1y|1Q*y!aalQ76!$aK~L=W>w!FK0r30}Ji#VcmB*LFwtMkR4uv z(p_rLtOI+n@0K^mZX5AX)_Z&NL^A9;{Y;h9gm`Ek zE-vC>(q!*!cnKh)q{<4Vu$?1O4OZD!NMO6BrluGYoTThbOj3mGvIq;0W!y`)rEqWR z^!V((y!4|`?|z@iFJ9f3{1cd6>3HR~Bbf=1mU~bT1K|=D=lWy!rlk0dwQrn&4DG6^ z@mEO{dAdE-A6GcbCXeveF5YCWmtK+03&rzzm(OW7D$b*igaz}CbyuMK1`iE zdK2g8p#kpdSGeVdRXJ<=W;mTT0555qC>y9Z`mTK%92ydox|!N%ERBl0m_TT^xd~i~ z4$Rv~*kM%D+q)u+FrG!*Br7vJWnNe|y_!kzFH@ZzX*~&P$N325X>j^|)a1@oyOtq| zKnzwB%U8dFP<7!q@rWQKE|APf2NuGV`avwE57$CRX4>X8v;mm9ohErwReo*IzBG2vFrpvm-yPYo(0fR zyF?s^a@%$S9JVi((sw*$TVn%6#`PcLB-Xu()k2R7(ti(FFXkKzQ9T;PuK~p8=b`q* z$fnXLr^MrpJ9WWAjxr+99fa)Fs^2dQ?<^#ZtcN$6O5A~<>tDfBal=|?{a1obFP=Oq zG2nurC6KqX(>;ypq!)ovgw$Wzxcb=qmZ%o`nb1w>?|F4s+l0R--`>r7QU*%MUGX*Y zTTt)&_c=FBZtioz+%ezrYjjXNm?U`jv0VDuz=iy}8iqzxBaJk`6-UHz@Db^9jymYw zt46>T&(=2mU!FKbEOpu%0s=if zBrX7*o}P|r%;{-qdE>j@3|knj{5&W=2w(d8DA!<&#j52)?F1LdU7i6ePpR5=k55X{ za&QO-up!O*$yIq~W@fMHucx+_1~UiZ^pbqGsHO{7gnk&33Z%`NC`|wmxLR9Vt!LYg zNDiOsJ(m3~1dPAZRaR0`GCm=p3l$~p@=2~$f#e=P;w;;EqRVqvFnr9u>uMxVM~zsm z01S{Ou>L?721cRq8O2*56J7Gro(&oUH4QQ6sSX{X5{I#l{{Hu!U0n*uuE>nGHWj!V zrf&u5W{aCq=5W~tE3$}XRPPP3F5=g`f#1k0tz$s~Gk>i+J50hFZoz5oCgmc9t> zG11NCa#q}9UKH7#P=&xq00#i9w6bz^?5K{5kM9ik+n_W0;;|la5Dt)mQK`qHysGVT zfGrk87RLb40B(q}QXt!zT*w&sDz)^4Nnt=(_6!}s>z@?J5oZRAXaprCHE{1WG&ITq zoCqp3)V~s;=HQU`efrbWu(4aBGbESQZG~@m!8UJeAjH4#$qhGPcyK>Pa-}}vY#}-^ zuuOHB2;&8E&g$qMspupeTn;I7-ufO~yq>3x-XHJGtihq{_YYiPyFW((ryI=%3SDy2 zDdiO#=y&t;^XL8CMSF)+4t^&-c}?OGZpFP}L*?e$cVN57(h3p}r0(*5y_LWYyzOUt zH*e#GN}<-$p_)1gtZhFjbL+NxOflC&t3xp|GQz_mP9hg3xb0EqwO&Vfgg+*ICFL_~ z@#Q-L&jBYfGb=qdLE@9?hVs{O*8p)AB`3YQI8>Pyn3wPo4o`FU&QkLrLO9IRU0`4glC%U&HE*?E`UlRe7JV!Y`9 zK*Q_F#?7UgnyV?lfFdV3Ik}kAkJ5oCQ_HsGD7LL-y@5`cS}XBaR!~U|;AiTNECjHzo>i6EFqGSoXiqxbWuZ$(7t%8H?MDH#4V4rogg{X(AapMItXOHZwH)M zWkD;>#lhYp>s8?$o2ehKR8o8m8pBx)Hg<#)gdJ{$eh0oZa#V~^%r>8Ju+2SSL3|Of z3rNFh@m&g;g_V`g5x{^gM0nE`!Ms;hkOfv5#2PUnR{~ZD+HOe;3U|ioGhEIs&Bis z=i0Mms_}v_f;PmQVTG*JLCeRvjdQPe;RKYTQ2;qqb8KaU{4YCPjw&DU5vM|RRF>Mc zY+Y_#o$Aj?e)f%I*HM$hn2;>e_#91cP?7^hLQK#}sQZx!llm1Fw4z5M1!oFBH|$y| z6D?%IOCQQj?^4kk`j34h1M^`W|7q9Amqh?XNY%bfT6~QB_;_h~H)wL;XCSpjfCiMG zT@pt~ug)1%L!=mHy|&fKq4!yf#x~GeX}RxKxzragqj~S0cdaw;S}nBrDk@J*{K-Cn zbayM1vpRK@(>sZ!F0;m9s0AUm`cw#Hs?&v@Nr>6R`_dP*3i{tuWCLb8dBsm3=;4uy zc^{R6RUM(4XAu);lf(}&8+%y4xN7?$q2>N6BZFeQN4MhC3=9%LO4DT;(`=5|9HLjI;CT6EuSwu6s3-`0%V=n`~kmc*`VH5?ZD>(p7tFw6E1hDGM&D4%dXpAlUo|3 z;IE@Y;sSEQ!otc~3bk+FzP(@1?}zf<>9kq3>MNjoQ1lex{o!W7$si=iT}}YY_T3*G zBh@)7DVEpC>z|>l~lRtF0_rcu(W`0^a#JhmJhvhVFw|MS0hus0~Li75Ee!z ziMx|Xjt#<$_gvo&qH?qI?AGR{)zhacNR`8uCVD|0(D`T**Onrhr@2sEUQzD4TQ5WM zZep92tJ#170v6BEW@Obb5zpTQGSN>sy(Cs&)#TavZxIh*1H)B_2d1W`3aY9+Nh*qw zV&dXG17*e)DTBFyDvfIy04sXTy*-?9@XNu~t&)7j4{BJBHcp}?{1*t_FJ3K`4pO$m zLuAir)vod`$mLyDscp^7rW6f+S5i^2aduV*bqT?Ihm?~PG}q2$6Q5{US|YcX=DPrx zNZQ-dL(I09Ec&(t6=a-*1i8;EkRSknlBu<|azqOo8wKgZCRNw?9uHyV z1#lAYQ;0r6eqb48ySfH!y5nq=Dm~##p2JSC@hAG%vY#zgVdHx}PadxT%KgTlP+%65 z6q#{JxPgK2B|Tk+VtW;~T^bNT5i`uuShRlNGB!}r{AXojxuUokC!wsO;#+WWw(jJ~ zZR@(1gLy1MuI{$0x3MCL)16?)f^iCf9ke~bjNSeNm|dd{wQ?WR01XUY?j9Z;)$0oayGtz175(lC5^wu}WQe-TQB9`-v#`H) z3E~KhFsTfvG zcnlw?kg1-I++xpEmzO362@8U|MYeqlb36~GA262WlZ^I6?`L-S5(PiHveIZ0uocT& zQSosF12nnxz@>O?74^XZaxW?=S?s3?nXt8WvhCtM`I@eF-9#VodF7$ zZD9|9NytyRcqZ*N7MA+)Warq$+%(kNoIq9cd=Z(?!plp2z*rxV)x@0JvMzPneD1sVsO%kKFA!GMym z+BXfhAAMU$J~$OM1f4EzrumP0X8-qkDgHatzt^SwUpf6(PXA^@`+rsC|G%oNkCDyh W-u}R7Y{v+JKY2M7S*gb)N0&Q8wt+* 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 literal 5513 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 Ii}{a#07I3B00000 literal 5440 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 Z-IFTHmp(b0g+o6uKq5HVvTbO${sQtM)yDt; literal 1778 zcmcIlc~BE~6#fxFkQU@dZUIFr0Y)l^mMSWT5lIOpkZ>hBL5dnQg2)jeSc^!2s1Y0$ zib_icNVq{Aj^Id$BISyNqYB6&S0O|og%U`2*S|Z{Kid6cci(&8d%yR-@9peOf2@zD zhKU9MKofJ^GXMY-0ea6<-vZrHrm}s|Ln$`E=O`%eG@F48mDr=0Ky~P%t5Y%n*piR& zJQA3YKmWcdCp6l)MJkjTf9L)+_RO_A>FFpdjh))QHG&g%CuY6gc{uERek%;L_fDV~ zIqBwUo(5J`s{2i;&G{V^IZaE|nCe04teT?Hb2irNQb>gy`5awl{X_#WSQ9d`Hs69Z zzAY+BN;w#wq~H|c(55DeQ7et+g}QFKSY%gn5bAz198CR4Ve0olgMW=>K=>bW+OfE>PlYCdbQ@-Nk;lf91cgiDjoM@DFN;@ zL?kIoC>7S!Bsdi~G$}+qds5uZ+9bB@1bklI+&Sg45K(Y(!^DS|H)xXKCO9eVm^WpE z;+8eylEK|{{-^?`v!a+@^aJ->r_|J>MISECY@{AM%;NiTqz|QTF|rEm9%#TnvRDR4 zt6y2#z=K!Dip>!lbMN-b;172#5QErd$V^yvs7|ST`gD178$xjWP+4`B4;v%@G`i#S z)JqY$k@Wl9;fx&z;9@P`5aBt&Fk1(9j;4mWB5nn(0HzCAR-T2$W!Q0b;rOGrY6NaV zu!UhB$NUhs(2p?)YF8g}F5w0KHvTO&WpVVy!Kk_GB9X|C1wd_gB<1Qp3!$W|b8K!9 zZEc;TgQF(70fs}vphOXj6i|`)z$zTSWQ?@f^IHlDS`f<8gDrqTftx1ICs#fg7_s!K za?Luz&xjz^D1r9@xsmAh#EvM@vuAF6nSw{(7KGEMCB*3ph8Ks9K_|bayJWjo6bk8w zNYRSkG`zl-S@s3tqt!*DUz9-oi_?dg{p={;8{z;cluTP%#V#i`;m<(&F?^)Wg7 z3cE}s(e#&rss61zJsPA*UPOh_Q|y9gYPVdx;+@tf`Ez`AVxd7V0)U2MBjN5VMI(!+ zn!U@kSlImMC=ee~(a-#`Xx#f8v=<{1;YEdaTNnTZ_58zU;|$B<1=HkwXFcFC^?ti~ zUwMfpx9M?BFaY<`*NcXnH63)csy`}$=|)>>peZ3HMh&cD*)E?xcmT$);RXH>FXZUS zT)qaR6GGB`m_l1f)jQ4#^m1m3^mUi`syYOgua)t+D~f&#LZMvFnLDHcS^~u81P2`y z*r^Ap{TkNP3EH_^Cn4JZdspUV%h56szkFRA0A4RMW42Uvq+w};<*Erh)adKWq~Og3 zU8{d?fqR4;zGkQf7zF|N6_^XA!1|m8V07BO`OBqLlRG0w6uU#TUXjYU@qSct)3>Sf zPFB#8PerkZoa@r?d67i{%3vT~aX=ba(ewTFirtP+&~N5CRX{fpPi%YG?`X=S${(cP z>*CW&w7~!l- z%3%8L8eO)qclc6}1~(&PV*_WF!z$`ua!LT?hCsaW1zX3l(}I3H&x|1Xolo2Dg=>98 z@~m)t1{g6V?M{Z1?jM&D!y2!~&MSPO&ki(?$3a{1KPvL?1mDyw*HRh~aO|{ z|HymmZL(8id_VrEpI!3yFD;!jjDFO1U@Vsj8fSa|u#9!S8GkYUVS`BcA*tvm8s|aK zdMHOIEWvbJ0kFdJ8Rm9Q_C8F9-1YS{qk!eEuM8y`+-9_OYHGuws56_k1KqpcteW|^0*H87{447h%vB`V zafZP&yW7KJs1i{vKC@*LaA~vu7&~g6Re6{F$LJw4bSJ9;!$-X=qjErJof+n76G6-I z;`chz8&#iwuAVQvR$+}7Qwcvf zQK*9LXfyp7I|`i%gv?N3#8o+i=k)l3&&c~I)Q$IVYGbFn$~yrt(+xW}oxz1R15bnn+5v@I zUwE?Cz9^>r+xL5y3|B`nbdt|jtu19)Qxp=exl{)}ZbXluI<6#-SrQXHF&mK%Gt?1S z#M|f=R$*0(8XslwHpGJB|Fe$3kJYX~6>G-5(XL7sjR)AgZ>dwx?|6`sw5N%SBNg^_ zP3Z4E?xz@VOS~r(k5z0sJCxV!nG6q$$D_DLsY+r_JVq23FRtXdKid}->65Px3bT}j zp^e0+wE6ZJ+y|R7Q4=XbVPY4ZB6+C5 zZ0J~i0Rj|Oz>F|)aVZ$r>j3D)IUL*tPrdwlmr~a3lYG_omh|uOnaSg7K>N~0>qYpS zn-Gu9`%ar!N-+16?qlSnRQ5%I!;R+>Pzjt)Z^QIQkIJ}PrLS>8N&OI62d~xBd9R|T zZm%>)H+(0cd-d~{?qoekTdx!HmgHz3?j9oE>uK(*upgqMZ@j<*azLmridtp;H7*ES zZH6Rx?V`-fpNt42maR=-56+I+=|C2k0|Z712T^R=RZCqBtR724sL`JdgxiFy)7)7z zz9%KL?cDuo*Tejf-Cs1nG28O4 zN@f_ZwSlgtblyOV*g||gUH87s_4-=@8~FQ|O4A(wkmXf`0|1{DF;k+s`a0~FNE`M}B+{tjk*KNVK~T`R z)E(G*_MXtBsnfAllB+dKxdwA9MzE?3!=vmLx|W99io=jJ%9hjg(KDs z`JV{DEOG1(p(v7`_r71nH#Z?95$Se+8{jakFHO$yeNH>(s;+0(|L6_Ej8^Dhn-ov@3wM;Y3axzm>8?(sL$}J!xOidee5980MIisb>;8JP1 zWtkg>nVB0c8fj@(Qc*;c1_Ba;ATEdw(7bcr`ObUizWaUme(ybo?oHhSAL#c$KcCQy zG9l|#ycyS=CT35>9r@clVKYan%pk zSPrh%*^owfFGDdpjsVT)Y@})#f=&7y2X%Di*s5a)$5I`W`D@f?0#oxHm2@u~9t9LD zvtlF6t%J}@fGZ`DWZMkRN7RO>=qlX#t5xvYqTl>fu(%k8HKf9|x(%pt%`p*wo16`}#&z4XEK7NPnCqHa@*tjWL{#c6iObU75&!Cz$vXxX9Zs=m=I9n_5T#3V@F zsH~hM^@it@S`{zI-?T^7fb*7h>VDc+?!l~7ydDp7KDyr{a$`b5!akf9K*I|a#<2|E zgu!z!bKsq~vR!$K z1@!o%%F}wqv!v>Vt||FFnWn@Ng(42_hc*jcKp#UieLVJV=GgVht=UDyOj(?;ap#p* zi>tZ>O2RTnv{Ru+iI-Hbl5$@YWL54pUAfYcO97xe_;y~OJpNAr<}Ju5?cZ!7uS;PI zv-Kr*=X5IIxoJ42H83m9(LOASWS2>80l?<&zDO3s)_S{(MQB#%Z2v9iCEore&Zr!0 zi-*t!op|ELATsIQg`ve(R|d?z=aCBo58lYft0BLE_fy9(#2ZoDCl_~EX^~yv24oAk z-TxB?!NPO41U)r$Gs&Y%vc@c%qPpBCkzif*@F@gNtG2PhWqu)4bu)Hv{J<9V;oC~i zI4P}scmqHhKX4qxI9%(e?dsMt}bqO!zhH zqX0-82B={Uvlxmr@?yN*;l67+paNpl-4Eu`;@nK`bwA)E3_)`+)iL^9!WI+TFKax5 zdE3MC0;~~D<$qz{a$CUp+4ra1zm3gB)I7}HTppWIh@@EHJR0oL_QJjMh$Q)%_CLwn{C*rldZ*7pMx$dD;m-`ww_#}y_UQa frcXv{dmAcDKQrsMY)6x#fpP@;BmA0t(HH&$+MNe@ diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_light.png index 86a99f7cc913137c4a4d4cfa53d1006f79ba6013..33dae720bb3324bf0eeb08c9f948229c4874c5e7 100644 GIT binary patch literal 1874 zcmcgtX;c$e6n-Kg3RVmeEFy>scoY>5t001qL?Iek0|5(EK^7H7s-SGarItFCKN(_`wkljS2s=cXOZdQ#2AxjQ6yTjq(ar?e)bWKkC$EbwbJN~z^FjmhXZES z)*C;TjpTW@v-0SM8$c4V7JjOC0fMevh&qf<8f_=9rXP9at5GhHJPt+7YN-ksc_f za%*D*lf@~*Y7{WBBnxe>!V6C(WAU+FDvA{~wY8YMts#cem7s~*$WC?smH-954-CnX zW@q=z_B$oorbv4ZPw+1qwT=!Czm~GnXyFvdxb+2XlmFlp)LUY>5ZIr^=1QOW2d5XM zO5CHuhId`n0mU}KJ5qNDdI%aNQj3*l#c;fbM3C!F9 z_AL}O?(}lBi*zf|ynRNOBCe=3%|S5lDbMRH%Bg?HAAHE;$vOrPK#G1nq^YZsrFnTn z(A~Q-s3o&wEirTf&=F5cPO#&?9;$60(+c+hRQk4uYy(a}P^Rp|IhpJw<9>Yu<*>4J znPJlGz?fe|H2_SCL;RMGd}OCDh1fhzHC@o8w2wwuq$-CtAho zk_e?%Hr#JLX*_6Z@YN9G)2YOTtF=M#W(P)@y^XWKV_mcwoS9t#wGBLS1EJnw6kSc{ z!W>emoZ&}1c0w$b*EC3X?}zDTZOG_)e+JtZ%#koX(s<(OgK^{ICC}9XH##UNWEUr7 zbL~bo{t)A*h)O_BhX+q2+Fn+7&$?Q!ND+yh_gd-!m)j5|_IJqi(+}tueP&%-42q?v zimudqMTI&gpSc`u2&nwT2O$CiZOd{M@TDR+gLpnBW)YB)Xtt8t2td8|6oZKI_6jX& zE36ep2PP{WQE#3r#?M9{I*SzHT^9kkHT-(4^H=$-+p==UBE?D672cILj4_5ug(qr_ zB|HU}ufm6R_a3<9deiUJ`;W`UwPt~yf2xBB(Zd5hif2<}jx^qn0wC}M%PR9?iuhmQ z*o0BY4{lmlJNWpNjVu6>56jqdbH1Y)2d&=B+xbIn9`CNG^V7SB<{iJA9U{UGGE-=o zm}JV^13-mM&_uHjtKhv*xR1ch>*uNgi%QA%%$Wuq9-pju)pEheAlwvC$+zFQ(iU#& z{2H*|-f#334p3ur!zt!l3NzS`-<(r+`(W{2(=G);IoEq3ejlv-Mh3}DSC7OK*m;KH zaUw|E_HwB2)3ST3;ZL8$JhNd&CpPI&^&*A(59LCq?%tf3dObzTR(bLxHBd)nM&t^8 yUXAWCnVCMn9u}i1o}H=vf9Ud$srin|Q^%f+)LE?49=-|x7lAvTgsXH7J^MGJ+#7NL literal 1811 zcmcgtX;4#F6u#_>P^zMAu?(W10#BW0dtGSCk zly~+XE?0Wzs&>5*22OG_3a}wMTx-cD?KX>KOX;3p6SH=y9yuxPoQj<3oE8%|EuQ!4 zmUVPCJ7Zc=#+rb0Y<7sEB^&s2q!1-+HZu3h>?11(*Y|REDmR#S*u90avG1E zPZc)FI+6`kK<8D~{QTlu68$+Bd!PW@y6SX5^oqb#RK;d*?4M4xJ->Q&uqo4ZYdFqo zpQK5BEBMeyqtV;BCMC9c8XyRhm~ftu`yg3e2yw zY#&<5DY1(QhdU=%!kj8xX}mql@~0n|8g8eDPr2}H1wvsFVW2)ZOAp|Ks=UbGnzQA& zRoQUM;^fQfww2iC^xYS-CjySk`|0uLTTyE}}ZJYy1c_8~^G5JX&aViQ@ zytDZJ7MQ&a)>5g31IcO|YzMZN&M)(EnF%_!0H5lmOqVG+_k_*bGV=4nP}@q?dea1n znVD>g_Da?$l`@sGaD>q#gZbvd3vPCdtyWGufp?+J*AzjeV4qw&kQ>i)1W z?sQD-aTP!uo2)4mwHyo$Yg~A+Edug~H_OwWLxI-M#vIrJsas*4Adl5NU{2Z#a=Qq< zJ}gxN9hD}AA_&jo&^ZmUgcKUb-P6-u5(EI1l$I7j5b-#s?{lb*27nVZNPl_AQcd!q zA?5)zofL{GcHxjFzv1knE*KqbXrt@+Y2o-T065=YUP-8qke*vvf6ln2BX4X=AuLJN?LT}#0MvH&PesHP zeeGjU_zu!J`na*&;ubV-%=EqMj;JWa<3IQxTZzAHRwO`eN~j)g?)7(5@pkt1m?M4r zdo_T=&BD9+6P4J7lU4Xwuh#7H3IN<`{u}zgsbkp2r(|%c&?wa#Vx9}80;=6?Tr#zM zBg@akNweoNV?+RSvSa8)8wd}JW23|7Rw!dgBTpo<=;_*kBcg=04cuXsbVu8jEcv!R zQj^@HP@W-cYinu)(o_KT7<3CUCM_}h&xKOUX4fupxtD4_RbxQzkl10%|8pXrMg4MN bzPQ%Zs551HI7E9f^kW15m=JWm5B}mm`o8G< diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.png index d0da2bb493a681276516a0876d2d5e14ff54cb0f..53b6250e6d2b4382fbe553e90df5af766f366669 100644 GIT binary patch literal 18847 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

Z!uNo+$z;Wez5mPr{w|;YzrvUQ eMFLK3u)v>BF*qxd;fSupxzpO3IVUat_TK=!aJ16^ literal 18790 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 diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_light.png index 6be35a5c05e5765aeab15d8ed18ba1449f73034d..4d5ab3a76741e7b1bd4b011964cc691ba2c2db09 100644 GIT binary patch literal 18325 zcmeHv3pkYB+W#|DI!lC{qf&Cnt3r&iOX;jorF{MR$IzkTh!|NDEt>wCY$|9`z*S66GEXRYU1>t6T$yMOn6ucyGP zSG0F*71|0x(2n!xv~(e8BWQ9;Y~BR^@p(yPfPWCKy4t6p%w~}>@MDAPsq^}q!5^Q^ zw*w$Z0y?ktCwFrOdlBiY#-sYGH?4*QZ8`$D(A)M) zJo}3Z*Fy-|EYURUwpc;*uMD=@^44!zhcz-^JUNEJjJ%sbQO7W>Z3XHxvDRRMP^HkZ zUoh%ZzLOQz+$5w3>nMwK2gS;r$O_TXxfkrK%t}kS{@%2!GxN(kot0dqR~S49tNwM< zSu(vdkLEwj>-^x(zAGJ(@)Ju=@=Y~Ytqx3?cuSLBm8$0GCfOSsAAmT(i0pUY;1Qn1 zJXfI&;I~E7#O)0}9xFRq4{<-ZH!-{$LV&CBk9h9aed(bsEDIZ4-oVGcHsBi@fPIAP zejkM8kN|xkpL2HW55Z#gCv85&etzY~x4RJ=HR1b(0eq72&}O(P{-$5*XEPE1vl$g{ z{?}%T_+OiE`hO0KO2z+d%2A@$-=G=1ypLlm7Jh8Y<8NZ?FSBj43tgX=TcsWDXS3ce zLnl$FFCQA-9Cl!!m-SPC!pK}d!m*lvSvwYy^NSBthpSP}f^Q_Ok{#wD$#j7$T zIQ$%k^<#|VsJ82Zx7d@iBc!%uLW2iyt|68zU}N>J+~+2-!tm$)h!lhOw5ej9YTqMu zI@b;x(T`$*m3WBc~HWx~gog5p6RAL^3AA*lUD(y;gE&+>KX(Ma;V6}2Y1 z&So}lL$(Z4lB3qVmYbv@n57WMNUGbYi4DuXwQ`@?Ml=`ao+_7jEO-2cstWY89>v78 z(T2*E2U&j0=Puz*KcRPOW@^ZA@H=`9sWq8&Akt4sRYlM{SaThN1>&nObe0iNy31^E z9-YV{9-)n5Ru&1RU+UpekNJt!$R~cPumHq$W%dj{Qy>Yl7AAVET>7q(T!FT4mrfQK z?DwVC&{z9cDxMu*N!^xi%2MHoJmEWzpKL($Roc;r71?sD1(-6avuP2f$q;n^)!D~K zXcPD@k+#vu!EYVJAtaZC^8AJ4p;;vwQ^u-dHvBeVeE|U%iUh+}R-5U{=KW$xmiyr4 zeMr%ltsb4~6cKLct}ExHYDF&Xm&iWhtHQxQE5?~Eq|WTpsji?8=9k(4OW9{$!K$VI zYT7Y`@p35EeE zhB+1I($KRH(zM&eb%9pF>gl^CvlJv?ac@>YA^V;0dTSpRk45Bf`tw0>CrX7*nN-w_z$+kIOO`z;oTO$-^>2zmic#YPLElHuzq9CGbxA=aK?q|M(<@{7C3gQH}e_!eU-L(Ew`@XiO`A(~_VdNWykg%{( zU@nlwW$+H85A2nK=~vddYyl<#LBCPQ3}O2?Y;0r}YLvlqvpqo8egw${SzJHNzwMfA zWPUAqCD#))gGruED@eDfaM&=g0;p4G+T_u;1yfS64EG z=myC3!Pf8AVd@qLvakI$!Bqi!16ZV-(alsCi7c87Z$6mX*dhZabVmL(Sa9rP&?OS? z;xfw(VM)&5?n&5ovE>p7jt^&HtBzOTn-POrlK-_0v-dJ@Jed*Kh~|Jab^1!|ZAiRO z`+meO32EXFv<5sUB#`+~)qzTQJO4{D;&;)~;ZiOr{d$Q(SHIO?29M1bMF`ddn(~oRdpH+Ve5o&ZSC0v!#V%25Y(qD%WvuMH9`QI z+yyk_m?}XY-hl>}%#AG?utL^YDjt-sO}sjNUK7GzIn1|JQB_gwj0bC@ZM26jcITm} zMuKyd){Dkr*kR8hM{hu}!+m`5kH8?SyI!gz)&i3DCuZX~p%#N6|5G8M*R5<@aP82^ z^UwxL_M49%&0{{u%gbp4yOFimirn&Nz=m(g@+TO|o+&a3`o6D~JKh+qP2NRv8-OU1 z50?b26u;5Ne-}UUyXeS&$o;XQX~mB1swl;%rEpZ>g{0?;+rh%SuNDqJqaK?TLp*(A z5J%6*k262ScQXG@-fKKQ%r5UW=!6ZW=Vh&U0i$yH{=ePDMa%-k$Pz>UAe2hGnI`Er z08D_OdmzgCy@CDQrF~nk9RhlFNQ=;k!BY?M5vlS~LD%FNvwZQ!rB(lc@xn=#iom!M zPO5*6QslKb4%Fb}TQjHXqOPKp4q>(%P{YXv`}-#unwW%sfAcZrhQB8E3e9nA3u4|I zX-!g-UPVA3Qo9^#e;w3~K`IN}j2s5^bqm1cXd#^JJDcV+xnpXp5Ogx>Mq1rxbZ)u! z-gr)+>nCpC1U>+;c?9(I?b$>g8)DP4_7Tl!_}1qpxs&@g0+2V#5W9Hs$Ug;nzmF(W zMEAbG#rRW^cL+JUjev6Y!?GRP55UCZuiz4SXAMj2=DmT|EJp%wBH4c$SghL3k=||b z*V)ROW~S75ierN<4(1G%?>j;QPLZUbKzY94<}%0#X0<6p6)nJP>K%?^!#;C`gb$@6uDRQu9gp@R z0wp-Y8F3*bbSEQOM)Qf6!A7>L5EN3!cns7e4Fdywb_ZAg%b#{Zl=M@430Gyc2v;eM zI*ogRMm?f}YEtx>URzt_NVgEhww|^}VTT5#JFhG%NW!W#@cg$$A8-I6aR=D)I8GLj zDC_pm=$%0Gbzu~dJzJz7;?jjrhWZ9Y`Qxj=egB#yLo=hmv#^x|GV~&-Mo>g3V0`*2 zU$FcQP6{A6@uxwzB>)&kMxoYi$tw^fuPxPRdF$3;et{?}Fwytd_w9<;1A^XJpCj8G z7aeSr5yuu;JK%x0oDTy71ybLGK%A^pJFFRNFn7tN$fxl>>4!{+D3V=fOfib0JjIO}4RM^Aluek;fpYY!Cnmh;224 zeOTgGu}-BhlY?G@jCx{U)XNZ{#!xCij9{JwtSwF*#8Ok7jrvc z!o}(+U=d5D*#HL(d@1_xgN=1c8z#0whK&o#-UODV>NVHu1e0k9d%W^DGg%{jS?_HC z-uH}}K^e05q09E(B z2nb{Az<}n93#79Ms5nDkW_k38rZ97OYs=$jDq11P z^w`m>f%~FZ93RerC$tsQS`S5BfTR6$S5ozZ+{uZsw?V`1YpegMOX=dl7iwb1VE3ha zxUPDca0n)?2zCc9zTlddhA6Rb-`}uVVHvOjFd)pb6`u~p4v=La(PJl#aBto`d>L&V z5@93uuAmRL;kQ961pN=DDE?FaXAPb%Ha1>M zJ1*HM^z2Sk=_oKJnHtM|K{dMiGD(6$A^@>8b6`A4>kw8{Qx?xNLQ)R{QOENK2lI?t zYRE*mgy2H8icCJC`80Lmj;S5O&W;b{$LG(2h!a}Y&A1UZ_A2+9e3Ye+gZ}0XlwJJ@ zfaw25aNIP@NS>_TPkZ)2v2a+K+FB3dQ}vxe2ZS z&jD%XSX(!rjSR%Dg&s$h3n<|r=r#Qcz|PT85oFnXFT=49fSV7cF)*_ol9N+l@BxPf z8$y$U?0T?j==L*MJ#r*(%{Y!U{`8IYcMbvgX}b@)`~u^cBVc7MYVciyW;CoOeKgYC zr5M%YqQSwzgu-mWdGE5sx-5Me#bfGxRo}jMX48TUl?mmEb*#GAJl81WN1(SLb^%sV z&+I)_TFi=2ndyF};x(hMV~%cnha*hZ-g9ouDA02M&`l!;W1tKkI0d%*s&Q%!5zi8* z%?kL5;m%4)N^aV;$OSthu}rPNYEa%;jE!GAW3)+@VwZ>#wJ@v>f{V>`gE$^Um|v4dx%z z5v-ht<~zv4QRaa*i%0>kg$faF-{Cif%iW|YXdnuJt?JT30ZSHOhGrCUnNm=^Dx|Q& zOrkf0vE(HsHN0k<2(F`jiYHHY&v%qPZHiW|8)=FrhZ21bE+82uA{ss_ar8#%!EyyZ zjr@KBGU_s<#RsPq9g{YspU+aK8Q(*)hEm7!<4}2HLHTjqP`aP=mAJ8S8h)vvoZht! z6&w)2HC2IfEOj>Vw2W5=S)>f`OPx9V#H#JxWiOrLl+@Hz`jyB(#%>@4R-ug_WP*zEDv$ey*LRBJkh3P*Fxr(<$#ejgfK$bVsJ`F(KL` zDr#@jJEsH=$^m5r*e!|_m-*6@m$9+9BUv#)lRZvl6k-#RSl7QwA5-z3qihuK&$)Ba zhqi68roR51K*y?1LBF4|$VnfSE3qf{aG9$L;+b>O=$T@OzCi-S!se>eUmAIM2(wcq z3d>4d++so0)tW_lA(o_Ms2EbHe+_@MM5>j14 z6$@J`T8b+L30rs${VL4GQECFZYKOAPG!4WmXneOY?kxFvSeNZFOKRBaLQY&;XohjY zS*_}4r?tIjydk#B_a*mvkZ=J386Bn`AM3)vbd!lOML)=K8otX?3IbDaGmME&tN{;1 zJOfTAVKo%h)C72V3{0GBHj1Mb7S!a#8FU)29BR?U!4t#yQPdSzDz-kQm$69kCYgv& zprbR>v$0OYFJXSvER;JR58&3DovNbny1I^{5S|1`1*z0FL(qvGZ^CJA;^LCh;8Q|S zK;8qSvvjs|b8Bl=|N85%8^!T4FKw4PC)F2Se6q`oG8TsBp>;WOwL08#ru{k0sk89S zuvNiqZ=<3D#4#5Ghea*Y@4wCBA$8y7U!x`*dt1D#?MI8E$a9P+p|B7jhcb{c1Zo+W zdL&s=a8;zQ>3yZ?@rtsANUlk=0ndjym>Q_Kp=Fg@-E2)^pb>`e@JQJ1+6rbMLzjU@Y-xuAH?`If!ht_5j7Z?zr=F!_4 z-mzhz)P=+e47bp&hgvFU=HrZs@ufQaKreI^dMr+DTkQoZ?=yddyAA-^B^{l*xw%VP zT9>X|sjjZRO?3JdJZzzc$@BqNY8TYJc|{Q_Ixq%Pr2J3qD`$RtGMH7)@GPYdUWBo) zt{v#r+-TZ2JN>k8ouyu`Iv#$V!cHQ%6~>}=kx8fmtM+u!BxINdsv2NzHYZGr4vW#h zaPsibs*>Y^!liYFkz)y0V$}EQtWG}xR|igWSML$ds{c1scq5F;lY8)^mnY9iZgrei zM{aoovTMtGU^A=}$4J`c8U5(ZQ*ta^dR!`vNIwsPz4``mN54DQV|uaJIUb($8Q z%raKbThykF7(3M<)jVn`6x+-aYa1JK(P&)QBdT@-5%b;ExhJ+@xOj_&98h4FnRVLx z6x%aZj68Tyn(S20Qg)smc%$Muebu32zP)hu@dSB1EpvP<5+I0LsE8MGXDQP~OKbaf z{lV}3o+_Dr-uHAopy|dn+bS4dmZSCbGtZW0Q~f(xUsgLY1DZcj_ZzeAG9hT~EP%w{ zI;&8vRQ++vM7v#{p`l^Oy0c18|0*e&pf6LC(c^?GnJQ9xk1X#w3RPTS`^w6C+v8Iu ztXYCphbe7*)qp(xrekn!tc})g>@@FCRf`iQ*GA{pBs-QJID6I~h5dGF&BfMJ&i&{t zlX~!j#6!JItbV1}Mkp*44Bi%eEvrLq*(l<|fya-ZSQefX5k6tYGjXupV~!5FJ%&~G zY07*!FTu}667Yzj^p}gEDsug2!wY09SE!zSC}ePIS2RAYJRN{IHGfp9EH^XnesvjpLD(A4U-mJ`&s zkmyzUC@b>gK#*KzCz{aB8PLhblEa!@m#>7>eVK9j+$68n?f@4o;>?4TC@_qUv;lxMl$WAk!f&et@o} zOFIF`{^q({Hf+ke`5<1;Gm^?l2X9ypjMvh(NxDHGtqZv5eh`RIvcVK`U1tG-pM?t| zTy}&)L1+1qL=ZD{QqH|-Oe)nz><94%V-Ygl~XqiN+Ea$aOSXD~*isgTxzqKl$(6jfO_V0TCs` zaWGsl0Kg;qk1FlWypXi}bk%7^6VcEe!dU_Cyc25POicP-9{-q(f?n^7`r2utsB$`2ixBL`BoKKKMoi`siwA}IKH6$~ zOj6R)!b0NRyLTXmSWBrt_u^AhXt{MFDWGU+3D|Q0uXJc#LwNGwP=g+g>8em|sx}p( z_JG7QoP$zB%#6f>bX+`96iv>cXJJ-u%gV}XX;m*w7Szsnn2Q^jyI*(m5K-gTHp3vz z{FWj-AN0FATd*2wEe2viX<3t#J0ZVUa6-%p!yv+@=GK)M=9e~+Mf*ZD55hC)RNx82 zmHS21JV>I6iHW9|zHMCq!5v7Ys#EmOHkSRl#G3C_Pso84K9W<6!BH!QXpd{x22HK+ zk=o_t8y6~H&wb*p_|`tF6ZhJ2Vo5JL({^GBsvP$i9D0>0#(IVS5sWXJ&J76g99U(L zYlREk=jY`+-kg3im|BJk3J4JOpaz)YOOi9l_qtWO+GjD7_83z8EMob(BB&QakV*NY zERhiS5rTp#)lPmZ_G$8~XS90V+Ah=Pvyi(1BAI!v`m4~#->`w7O_T6mqn&EBui@y# ztB0zq%>7hO-0Oa^_%`_U>(@aFNV+E9R{u`M5J_dVnFbGHADPh?v_TL|!1oK|mw+8tRUAs#>CW8P6L(x~mTOF1U%3#f0 zc!36BHC(16Facd%U4=8BQaj66+Jjenfiq=JhT%gKwZqJ&X>!K-)dCgw%>l=AbDm_m zF(wOY-T*0oP1SRrj(9|C(81(LXKlmkun9{9r$U(s504tPoRNTX1)hgKW$r^wpeaZW zQd$#feHC;w5!D%Qg9m2y&9S4(;+|ugL^EIlFspKcb(cn#w!HmTsKdmyX(MK2?v)aa zoQw}09v%)ul4fRH)bl)?Vl;ebe)$!zXEIv5M9)a%l9kY#q-PsZa)F2c#UB2=H|Nc@Hp4(F#rVD%Bcdd#V~PH z>x`>H-Q&dqVqElO!vtb|N?l#Et?9a{pd)WxSb@(Eva}IqYM5@pPz5Msvrc4{Jyv$)IJCTCGW z?^YZ1LD9Yj>}=_Sp?ZIewVljV@kH}QjghIo5=*NXbGxKN1b8+yq;=`ir3L0e5tOgB`DYNN4GrCPs7O?9<-yLbZ6xs7gN^3ChgQc+ z!s>z*%J~5HxjXcE_npC%8)cl$Gs1y@dC_h3Ng1uSwX*_)0VPuUjFb9{o}JjdPX{W& zoP4d@BBBQ$Dj;|9@SuFgQ{f~6DO`TMx*?o4#ElW;;o;Vp(=;K_g8l{-ifMX1mUYdd zz@rXkiDA@tik<{eVh$5PPbN(|;YM0bv#A>SakLYgt`6T%JdR zk`^DzYq_FE4~^k-Dxbg6o9k*55*j*EZ2#cFi8%Dsk_z4L1(PYDAyClgWtJ1071z0&pODJ zjS3)$s?^c2=))a{aA? z0wm!Aa8QmJH$bhe=BI=DbU{v15)>hNi&xqUC*sr+yU8UxIH%Ltd$S=V70ggYi>0pB(yrTPtCG! zO7x%PgtD%u>RZ}+9(tTsMYu)YLvXb8)ehs1+v2Q(K1|MueAXxmz8ae&>UcA!NQ5DIqTEuodiBOjdNh*-3bK-@sT0ZwFG|d-WaeSxj zs$3R5*4wmSX+N%kyX^ekkjvP7i;y=@4n*tcT(-Z(nRDP`{(%fxdk=S%px*A=b{ErD zJW<~2etj!G8Van0CAw+}BUKi286lIB=zGTG^{c>!z*8?qN1lU21XuNPUS0Z-Kb)A_ z`lua}0g1Sj?02=bI*vxk3Qgu7bam+h%6cej6rRg{y#{Ng zXHD&Ae0@!i9Y1jp6nFDL7_jvS|3yVb)jhenHE)w4=qtACWn5^Xpx!led~kkyB$&{1 zv5il`bTs|>f|CkW6!+Fx9v%Z(+2eN~`76eGyo5RD~VAh-cmywYXOBa`uV|$_FK(P$tU5Z4atgWBJ zv+A;dF5}&#OW+IF)4K-1{PU~tD(DCMo8v?Sl>w%4p$lr-Cyk||X8W&T-!5GQnS!h2 zD|q!in8gB^#{n+^vZ0nM%kzYhg`Tt$^4ypTjf8d{s&DlqSAL{W)pqOnOa>ad+PH&I z8!p}ag*m{5i38HI2t+b|EJiYgp7d*oWR)`)0l}am7XgdrK4Wh`@!Z@)!@eUEmuKHm z+YUS|r;|vCRb6P!EM~<=eIY{IYPP*8(1Alj(zRb1L%DXLGRJLh31#w?W}{up@9xtv z9ua&}3@TiTRYg0VC$g5)xCS#$JDt(0&a4v;!wI7!=e(8e0OeSi#2l8C^cEk-iJE(R zUK=&;>msC(F^n;Bxp7adQN(3$*b0;#2Pm4Q?vxB$+mtXAy}eD@lo=dQ$e1c28|z?{ z#wRAoEzwUb2l_s~l}5;3WQ!iRG(Go(03f9P_Ah|;>eP&XOAC*4yKHJ|O8eGVA{pLL zy;{bwqE~%~$EdN#>^L0NNDIb;le9%56^wc*f_2j<%EHR-{jOvkeCX<`RBJzGKLGKS zhN@HVlS)d|9!z!efYOs6ZMIBNc{C~odf#wb6HM5yzOoe)8WR#7l$7FqH;Jj0Sah0;DdfWe z)75u#;u^boczVRWDX*z}1qDM!{g~nQwG{yYZ{ED|oT@_w@=BA8pU2L2m9KmnS*=>R zUb3DVZF>1y77)2tws#xqL_K;HspzxB*x)F0uLIWB)~kK9O`ktkm#;9a+}zx@wEMN2 z_Vu-X`LbKw_n3%YxZd@mpHER)NIRm_+LwK+sx&L=LQ-di69)Lh2@M-il3P(&nRy&~ zGsJzO9qex4N8am2>q*ciI;AQM1bTg@9!-qpmX@m_acUk_qoSgsE4^9U489b*8|0g> z6hPT?Y|kg8sHnJ?hv$evX3XMzo48NmfGamQ{^m46+45UmkF@+1{o(b*?Qtv1!3)RI zva;}t^Ga1!+cXxZU-^rpr7|5Wzy}Wc?86~fr4CAG`EX1dA?`c)_O>ox!V`Ewq!jka!}zm9vj!Rnm6In~9qwuda_WO}Bb~yE%QOR=u@SH~J9gQ{POIad zDahchGN?p`w~mfZx?$^ss!>xyf}FRvH-8z`d%JJx%6P>_Y!dL40IdV!(3x7r;nGh= ze9H&~#Rt^xJ+Cf}6cb-HSz9em_2JcHtWtOEFzxc2@8_ue!shGX9Zv2wL3{2gDk%YA zih0RG0zDsi)RW1GQS+Dz$o!Ueq;RGi)C zc7i%w+#-^DexcT*eC3jxhllyBdS723E!GLeYkb1VEGGkhLq3X}*I^F&-zzgtbGZy< z)*oQg+ld0No=DHp*z&^rtEWUf$vDs3qs?CZ9YCi*K?DXkO9uzp+S*zv$%Mp2WOt9+ z`_)~c9cHLqdU|@Tt*t!K1vjKma@_ZaIs4Vqzr4DnzBDgAm`t1u^dPB<*gKl@PPF&A zH!XqUnrr8o{_o|K32IpR>Z+}+Z9rybCJj4l;m-@$LLNfYGKzM*6q{IopBbW!amXF5}>RJ6AR`^6srP z^z|5EGd$hhMv~FvA}8vfDuG zAQ?`eMm%r0odCGvZRCo8MJw~b#uTiHyg+PPw^UT)0XUmDQdGc^@&~2-gHrxMDgU69 ze^AOlDCHlN@()V+2c`V&lrmrMt~La5NyGmyz#sJTe?7hYcM_Wa-`<8ZwGh<%8JvhY zuV6?jXE7SgSe=2G^A9S2DR8b5cpe8m-3kX(KA|j0=%CCP2ik=!T!erx=xUQ7bEN1)jc*+hKkVWL9NC%?pC?WCq7TPX0A$gTzLkjqHzKbk{$h z=DZJRq z9QG@EO{!VUo917Xz}JhGDDUqEAj&%j zRq?E)NffAv4g?99F*@k|7}sO$TlMA|{Q?T*iZAB2W265JZJs7ncuuiu@GIZ`WX^+t zQf>{;m@vD{MMElj$+w&!19(I3D|O{k4P%7j0xIZJiLKox_&E^>a;zMhb70o7mhDPg zS=T^b-BIQhqkQSKxI2QrBX+Wh_PK)^%$lb6wRT>Of(K~Sftmm4!pN=?Sx6x%a@%<# zqHqjUiSSnLXpQoPB!%iJQIDFkiIZ>YyCMsLcWU$hrEK#1n9Bcq4_^Quz)W*o`18$M5wLZhKXXMZ^OVJ({|`w=ql5qe literal 17821 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 literal 13767 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�zEuwqCM^}NI3 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 P1YJW|!(V=T`~Lp`>cAan diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_light.png index 3600948ad2eded4c2e001f15f15e5c24bb910fb6..32a3d52dff5e71ccda53e26b3d7a4ab061efe9b7 100644 GIT binary patch literal 11017 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 bZjg<$oU(pQ=>tFNgm{06JVH5i=F)!vy)4Rz diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_dark.png index b5625024ee898434713ce41813d21c01d9d97659..8c70302aaf0e5acf10a1437ec7c185f5a6239b03 100644 GIT binary patch literal 14145 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 literal 14055 zcmeHucUV*Dy6-|n6h&reN>OwKX$mS;T0{j5NGBj5pi%-siqcDhVqs7M7@G7>NGJgz zA{_^*0+AA`0i;Tel+epvL1&-6XYYIOnZ5UOp8K48_(RBA-?#Fuue|TCyawy(Xt1*I zvH$?U3cYdN000;g0Dv*_-~sSTH2N75{KepApm7z*Z{wc=KkRqA3N<=!i<{Pnep3c&p9>0e&e zi8a{W=!c3yg+#SvIWjSku<^*RzrINn8IR;q5PJXU3>Piz1ryIfu6TD5wPIC;8io(5 z%=;S{R~Sl2iX>f1^;V&m$xmn|?$?7>s}e&5{I<1=bJgZdz=Q>*bBWJwc1=_qxRQ1D zej2k(hnJ`4GJJb*0JYN~#+4Y1_wC@6zA$m6TV6tPh6w;No-Zsv-G?l*?3t_U02?J2 z50v#fOjVo^D_&O$J0%ZJ;S2}sJH^##5sli%)mnt z^jD>rqOU*k1C6+J?!AVdk!jalfm4&An(haW0{r_lPSaZ+4X!;&za7+gHvmYp**)&}oJD?-=u|Rx}mF9}7+eLAG9@ zzDQNSrdgrPqi|#`f{Wc_@Jwc{#o=d__fJ# z?}4g5A@uJ*Bj&RAeNV?l>B9?sS8<&_9MU7D@4tV|-5VDCMl`+IH>tBZ^kJ>>MB2HF z$@cZQfv>g|qA976j#S(0S0J6X)S~jePr_c?M-lWMkH${XpYK{r`+Q>aK?IoRGjV04uhiKRSMv27um}w+qWB2;V|o1nJF?e8PJ}dt1>-A9c;ZiVl4h z0czs_8k{bm!rEo8!G-8;`mzD_Zn7rr7sQJeb5YIX)6`wN6l`iN=BaA|Sv1NY%m zqVcw+IYq}1ia~iBu<0C+HcEVbRvK`Ww2 z%KY&t&8dp|uoL{Gfl3+=;41yB4x>a8@N4URf9U0S;V}lFu|!(u9DRb$XD*mQJY54* zF0A|l0PE59jz|_c)^7~Dfc!>%K%Ri2{HzE7Xjt(QX!NQ5tC>5xyy?1Pjr6!UBLwc` zr+wDKQrnveU;g~W{_`txYKE!hq+%?M9RQBHKL49_tv?z{lue8RfQKLZZDx5!nT2@* zeg+=-YZ-XcUn;%bbyf`k7SEqV*C$={bbVgC)B6$t#s*w_`TXkF-t&Z19|W#cv3_s; zK(86pn|%3`nQu=4S5U>~1Dcoxl5^w) zGi0+ev@FqXZ#`$g^;}iJwMtuPmKH+x`!4}*yI37LD{8)(;b8+I-t{`wH zIhUx3xwT-Q@jfL-wOZIQf^pMN9i#1+{ompQ`AHHVcyX=~sy4(&B^YW>FD*+QTTY~I zS(!>&>rw-DDP_Bz$<4kzxJ@)+ciU_0v$SUzk017NZ0WN??t-c^`R*kKew8q##n(F% zCIK=twzE?otv1q7OEXp;U2@N(Y5rA705H7&J%eku|MKSB?Q}$dO+E_QY+IA6yT5WV# zkvFE(jH6L$8mLKu9Aj&@FS$SS1Enidx&a0OG{TlGEQfj@Lb!VRlcbWnrPbC*b@E34 zw-qo@mwMhqS^83VT4_?ROBOqKcP&aNo+&dQ%+JUJ59g-IFsK3Y%}!_%L`v#B)EB&9 z)bp$)Y#3-H!X<8p3nE88TXl4GjScuZr~dTySir(vXh#@o+2yDWvKJD_c&aBl#$>q{ zvTdP#vuinEt5d^$b#t(sFqv4k9*Nov*d20jn4`8=qo#v4jtyvprySXg6+f_i=KMSM{o-%tif9$Yw3%6IR7XN1t=5R$$}ub`fNY zv2v3_?T8X5e4Q^6=#boPHX&A3CDA$_u*P%&{0h740Sg~Ds;gHu%BHeLH!6pa%OvIQ z8QOBsZu;)^Z4{)4_67amIpgrBQeO|)>fq|3ZBjLjjchM11l>ki(YKI_=aBI7a_6x( zmcI-F;Hw?YM59@^6L-Hj`qId1+Y>$2Swq{EE_0jLQX3C|_y3Y0hxOK{sI{d#tqE2; z9mm#H5)#0*1ccu?05z$L1Jz5q%k+QVSRNQ;Xah63jt%Ph5}(!Xrl};uBWqnq1eMgJ zwA~_AA$tNi(-bOo$Ikh5B^iv)j@C{Nxsz^C*1e4j$g9#j(~%4ZnCR(y`QLWwdN^(0 z$|X5BGa`_QVh=7Ub#fab&Bhm4(tb;y&iNj?7~oROF=dmWqrF zPSStp%grA5*Lk_O$t3~-4@nJ^lVLMO$(O0_+7kYw@nJR_t8T{<9zMA0HMEd|D8h0c z^N*4%e{ndeB9Jh(kumYHe7CC4N1J5ff0Z)t*{yW|n7x)Sfji$)tqUJo3O}2rBetN- z<47#@P;2eRvk!@guDw9&%6>D7zlpwQ*$;* z5#W)s4GP-Y_;t4Yq@J3sOpg`WzSj_W3nTFKO_IK}&&|2JhO*xx*VK`$k^9SI$Rjl( zhm=H*c=W_F+lDl4fUD})xOD`}+nU{O+2iSQt$VeLD#InLsJYK&wLxxLTFxjqONf-+ z)2qj+-Q=s@Ep;jV)}oS7lD^Z(Ss72`H!6Za4PT>@{DNx+6+*KYE1IvERHD;^<}FNr zK@Zf)*e0#ZjsfV1@^R%&Z0)jxA>44S`+yAbrC~u?9hY0->s(iXnv<8xdnS)C1B+rya>~9Bw6HGQ1qW*Lw{E>r zFIPM$(r(`yam?IwC_R5*kbcY+nrw6@kkrAzTP=U#~ID;AV#3~+QfS(=GDE< z9u1WpuD&Q3)A)_NmFH*i4Yn^*1Lwg>F0L%fZkpCcu*FXgRIv{=hT$(&K2GZoL48Ya z;B2VPWn%^kf?7aCkk?%%p}cyc)x@R!wqE=4hroM7A`4z#d<9j)kbX*|6bszwsHYcq z!DH;iifv`ZvNF+p##G<{FsyB}bF$4tOPqx8*%T6bT*}R{tM1A^l&y3*XQkk@-{^yM z)sCJh^5HUn+Ei`~8{mDoRKB*<*=LT)NhX>$I6%r#@mrdIo|x`fe$`JsF(ds`Jcczy z){~pIRTP#pLc(GRK>t7Si5&a+4k0 z4od_4XVoz$;599uulnXN0At+FmzBd~H>4lXaOn?Rm}&zrc7!i1{y{opVU!dVVZ zX`VLwF8dsrUIW5_$!QUBFhK}jBQdd@(jB~dZPIitX6sZWEhMeU8r;E890k@xQu7ZzntCL?ceqr|^&N|X1mGMuYZu@e4T z`qFtDEuz}G=dx9hn%%3#%Dr8SFOLz4McF#><|z!r7cOFEhLm#Ce6t4bNcxCl*u-Fh>p`xg2|L=X&UvQ*t0ieObD+v!ZtGOJ*pl}edP@&N^G zrI%|j`;6o|L)@z4_y}SP=zhfLN=lQfdb+xK-uq}@N)?N$slJavT?)R>Fgfy7 z`$+$islYxkiH!XsKW<=AlC+b3e^_)SR{a3PQac}9wKERoTg0k)2?d@#ncRJ zFQ64#Sz&1oO;Xb`vYcv$U|^tyw1`A2=?24%;@?5hiBY+1hk$Pfz|*G0Keef=9M_zy zNWH8J>V?=#)fuw09tQDTu_8oM;E}uS$pm${6wx%Q|2Cos0H&Ii=2dvYBRGPUO9{Mg@LhM|Gt2|Ws7Y%+S6 zX|KWp)I4ors+SFNDpP}}AH?3vPEiCW*@=1%@y0izzcy>*E#ZUQVmkh&OG>tEy1>@g zi**YZX21gj#^d1|206rhEfP{=iEJ)?%t%_fFr`;cbBjVbkV|a}^ORc*`Hd&)2_=!~ z{xGf-X(}m+)Sc`0?G9o9yg6d4gWM<`%|&K|C@Az!e%*)apA$aFiRrfCmG3tWdVjVL zU-q!21xi>U6=ud6fx)X1ZD1_1^iwrQ+g7fwEa6Fm73Fs)zxL;UO41je5?Ri&VN6FS zswwZzj!v(d|Jal)p@JTptjZo=%wMEAkl{KGzV}pVQ-)yppL?GbZB>z-m#F5^|9KxP z5ET5%rh(^zR7vR+1m)w?4g8G&H9u4`Y6aT-|F&NaJW^J7(iV=o~ za+vrE+H+$DL6CGTFUOPfK5oVpRh4-UJ2D;Z&(xBf9^7oBtRWEy1FN;I+SvT53+AS! zco)ddSW*~?B+vtgxD8Il-CnDg6KGndPD;p+k35~P8dW9R>559MiMe=k9aHjQvg)Kk zTVuR-kwr^!N#$!#%P4cXF-L&jpxYJ(=C1>i+o~o{Yu`*X8u7c-jj*115tl~?0|wu? zHj}`mmUT0LL%v-;-;&tm+XpJKjjcRwO&oBK&Dc%yXKz@rOV^+&jFQu|pGo_<6t7G_ zg7t0J%nIya^NZ#Pu>-Kyq>YS_5bmBN(#B8pBy#M%Xv}mOZCS&XQMV9IcF4s!pNYMC z$`IFhpekfR##ABoIxE+USL~$5jU;wQkI5;w{`(TR&Vi;4y*);NiF?)F=cSzTq8X82 zjc+f&ZWIVY4%#ZG+b_NbcQ_bu7SJ2KB8NOBbLt+0fWYARbiNc@^YMu9XJws7MX$;~BYsa6ZhX%fUIDU0W+jpHP@85{IFM{7v8n6G(Afy%Iajp2S34?g1J&pjq zpD$M;C`iOn#c?2_T-b94`MaBy}U)*+C1Ku7|caPeIp ziPjm~xXb$7V!hA??dkQCURryBu;kk}Rl@OtVxo~sx@9Xo3GWMXE{HVorl;KM?(PNy z*>^G!A$X=PixB3&CH_V{ho$+I*&M63QP@Y$YfKbylI{KA`Vr*#u9LFl5~NVoD*>3T zFQXcfXM0#9Of)peRNyE*9y4oT%obMA->~Iv*)JQ;Q}VrL(SheCCpV2H{kLWcX-HvQ#(h+O|z5ZFkUwqLsNEQlO=AA zs5#A@!*@<_+XM19Lj)Du9)V)nvN0pjn1?227A7UfuY!bAgYVy{9{dT!uqR>cHo>9jAYSi9j|sc4o?yev`e{CR zZ{kyw^KQ6Fd@U|t7g1HQNsUkJS^iun+%@M6ue71-2Gf}S-?ld0SCrWt?oDT~4@DFj z^O>7;-OmHT049*oyK2LzON@0kPN`8(9u^|T z=lw!CN5@**gRhBmU#zB@>^IvGLQ}^fAw;%bNTj!V_iE&=97WyaPCGYf;-F4<&^|hQ zj_C>sX{(xHfEgLPZNt#dmB~Ru>#8C%JZcdQ;0^}^4j8O@u0RX?OwS(;!PG?jrstLD zqgVg>$5|n{;@d-b=RBNNWkES(+tTpCn{>f%o&o;pI&RmZ?9CQKe9^3G?U7($P(CB| zLWpEI!b3jmY+wx+nz^(We{UmFMAb!?HuvHB%;*{Pk?{J|iw z?R_9e$drxwT~4?+y8N6e*6Q^By)-*wO|41XyF#*!Y(PsY}!)XMFO=^{C*bMNJ{ zx8lX{E~o-arD$J`y)|5)1lfGIv2FZ)Q|1Srfl^S{bS>7R)9lS?v4(L;xAc%3k-1a{ zzXII&F-e3YTt88^)9xLBE?&H_bkBgv0yK~5(0kYUum%151bl$UOU(;RnOLT zXNztqIfeh`xZV3cc=YFX(DuFmi7FaAS~!{U(A>S8SW7_wuKPj5&)ErkNjz%!!-5Er zi2(qowci*M65yFG4O#1>dUVZ6ck(g=jkmBAy=qX|8tk>w{nq*0Jt(=qI6m|80swG7 zqt^n2TyzL!0_5-I!Ey>?o6-9SF}|*XO-ueTL-V9R)h; z!rQHiwHQ3d{lP;(P!!QPZzAi!Howat5A3W_D8d2F2-swII%jMUrEnB!y>n_G4gjIy z*_Tr9iE27oioF-*d;vOW9mkn~##aa@gJ%V=n{$l<4aH14kArF8M7n`!V$WLPlTn}Y z5*0=uG^^kiW^&z{#G@#Gw@~Sa)fvnLCWwkmY0H_0qdGrv*6%H6hj*Utmn;UA;X{DN z&>DeeP0f^@58XGD^AdD#fWc^ulRh^CmU61gCP(Q?I4$04H?C8r^n%~)m?FxVx4fai zT>4*dng4{M_1ld%qeouHn%{7d0Umwszh%xlv;JSbc zrlwQJOFI#5>*Vq8W5gNLEl{DlE92-;FhR**h)c?Ltn$}{esxU$-{9WC9Z*T<1{2v? zXmR283r{nXC{BN&$5_E{oSR8!?R2K**|sp;6Z0*91AH42R~_NoTp)Gzo5W8KJ{{YP zlW0Q}Pz)U3WjdD-?xp5F#O23c)h@!eHQo55UiP+g6-=O@qDp>;hnh#RJl;aUg5hJw zG~>>Z#PtoI-4mSQt4k7weDj!iOGmyrouiAqbQDNWZiBn?%$&H4?s|;+ll(08R~0Fz zW_Y56C%Qt-HI+mclxZ^Im7b=pmgOHNxL%gcwD|ljBkp(3bId8neTX?w`F6wxzPimD zASaSIQHF0XX4jpTlY>d)vzPA>_&Xgv`#+(h4`by( z0*r5YVu-tmmCcd6kNpcFuIsX+@y`67>GnUnKs2pHiGK&hD06p7=c(m9f$lrK5fDu< zBX>uzo1zaW`vimO*O7yZt9dOc_aX)^ecYXkyZMbe%L`j4CyO7>fs#D*lEM808|&3; zwo}viK!XfpziS+1>q~W*t$DpgWhbY~G+h57;&WD-lU1+_=XDrPQO_uu%!XRa9`Szt zJFynTkQm-eM8^$4+CLtv z&hdP?>H?f1T?$~EEUSw;Y}SW@77F*>k&~7E<|(&)&Ra~UC0iK*s*z)UAh&pYV!C-+ z>JNIl1E{CVMtk(kvDrUd;jXKCb;#dzsBuGmPG3tcKoc|q$hW$}K-CQC%n26Qoc^Ji z30STn)!K`vrLfW#=6c8pyS@+E7e9A2zm&A6XE;w^MNY8nA?g2hW-Kh7BMK7^6+fgj z=ibxRcdOgj3zlOZvnm5edMwoRu<#da#aMP#t|pc*Y<6{JRDD|ylCtQ$`}WO4*br)~ zNm(E{8In&zO;mtE_8Zzo1v527vT$v#J48V?T*J2|7#SQf8vIIk%ox+Bg3Bg8Vk4hc z$tn=0N?+<`4^Y~Co9HZ;EJS>^zB)BK2jX9Zs_Zu#%yqs2f<4v)2I}eT-k|7INOib3 z5jnq8BMAcFw%iz2kWqh5_>!RXz}V}vPqk;a)hn7Z(JLQ6uYIG6Fg22UVBkFQx%sr` zrWkj#Sj=>sXqU9#bV5i*9dWWqWj~!Nskt_1mN_dT38165fHp(t#1+GEKQ$7JqrBBo zsToa+73?xF5%o7!`m;WZj8<@GMQrQD8wF(v0>c$c+da2!n~J*fN)zF9&O!Ps0>RmI zm<4p(eD3MYz03R%!9HYY#n|TGZkovbSaNn*I)- z9L04!J%^ z{LJ>kAJH$`_dkJtQNEyrh65$EsAhLWk#DW%?~+=o6^NAyg-O3-WxazSQJyLJL90vD zR)43)%IoRZL8(kx^cC6uQ$)-SQ1+MA*G~C`{~cxv@;;@+hQ3 zn;b6#>Si#-!g9r8mocU!P_Q(bF&GvXYs(&sr%0V1$}ZjJsPtbbN0fN)9sm~4?J4TF zOH-oeVmSRUte)1^j4oc+NP*aq4vXZd1lVrb}Gm#&jUqh%}z-_6l#+iQIdKA#zkuYz&qC`(n7@ z!Y9^qx8zD0fTIkK5ryy&fdrd9WP2X^g@~FR4pG1V8iYm`O1x-g>)GKWLEGQ!$-WfG zt%NLqlIC8S6<@|TdRf_s_jPw*_#of1pXP}7>}A|%Zi@4qD~QJVRlCiI<^#AEO(FRQ zN}5ipz@shulDAQUqsbJJRyNd%-w6-J*5Y~w;8M4PTo)BoYUNgXIJSzx>LH@+dFz{T z)(k)>h$j*EvmU0`%w&RI$fA-}RDZ^A1(7TEKn(-$5nqH{XL-nqFEe|>49l~$z^mC; zPe)ENFDfNV2>^|U_Nw;S!=!mxW%!rbmW!g8dHDe#-@3&9|5AMLGyj;YwGvoT_gld^ z$ncY7AY8Zyvc?mp&U>VcciHca=N17o_>sZMX%xp#HaZ78cm&{Q?>3|PIe92*3qd!& zKm(TA3Nohm$9wIoxoZo;_fniHq#@o*{co!OaHzSP2su_xt)B})CLxHwnSJYpL41s+ zEBG#WB2F6I2oE#N;*Cz9%c7Hs$Y!#1Jy=lDkZq(nDFZH)_uzaU3G`LLip4RXonE*4 zqdK?Fg;mna+A<&9ql*+SqG&p?;n@G|M@gXNjNvv5>8OekKgSd`lJnqWFt7IcKvMiIXGb2I$d42D$;PwDE+#EQ{`(M z=OK&L+0`p%KT1gg-L{6-BLfu&3F5I*tU~rb?#yPOVjUN7znObIBGH7Yh?B%VV3vV!GNn z>``Q1<@9eKS`pO`O`-35K3Kp#NQ5mX3z4V3bLF}=zt@&<+J((TS1$^Pi$#qEsYPk2 zJ$rVg?t&5IWVUf$wt)mr+VA$=)RYb;)aQ3`{kaAFzq`%W8tGkjTrB?~28EHZvf{&MWk8`4 zRF{r5<68SI&42fzvBR5Ftd26Bbd4Fd;^KQhcd84!t1JZ8kUn|rPl}*!E-If<~JUIA7YCegUkvu436WA+|@W5LUZ&EcA2CZ z92YxsxNJR%4PpBLnp3^&*T2z8wf$~EZ)H918QAKiPLr!QtsK4AN#GVR662ET?K38_ z;|wHnjFXKn9)XE*lLN+WD>qhm%#+O&`p{EiJ}P2k;wx8g&T zt+$2+M&9kiEg01Ra0-)zdMkoD8PXH{EzjzmBc37$`64BM$Ea#x%-_d4fE< zv+540Z$(2h*#iz)GN9*Bs8gPb0v(Ks!s?`9ESRbALjyKil2a;*kI7P! zHhcrrMDSf_xt?bhYcK*wKi&CcSROlQTil})ozZTe{Us$JB{@&&6Iit4dZJv7@lTi2{|TYvpQ+aWpU3}I@#bHb?f(Pe^M5Y= j7yhS(|1KMIZI{99@DOGH)XpjZ{y^1quIFF96ZpRXX=AFQ diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_light.png index c71faa699e17c988e6adae41f91bb88db03222cf..9e0cf20629aa4d4985f3e1ff432117352dd8d4cf 100644 GIT binary patch literal 14471 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 literal 14328 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 diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_dark.png index 716fe34defe85d5eee8fc6867ce77a75ac75e28e..b41798acd92734cad6b70d08ee238b01f5a31745 100644 GIT binary patch literal 11632 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 literal 11524 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 EA3gWxO#lD@ diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_light.png index d0b26c765820e165044bbecf0f9ac0a8bfd4a5b7..f317d587708a603bc425a57f3ab39f781213d665 100644 GIT binary patch literal 11782 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 Lj7q<`dGCJ!@yKp; diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_dark.png index e0c0818647c39248b5ba218416428ac77211ec8f..309349c4db6676841f1e5c7ef2bf161c3058c3c4 100644 GIT binary patch literal 3516 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 literal 3498 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 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_dark.png index 1271cafe5c0dabb61898ee0d1e3f9a22ad8193d4..898509b2f2abde473a213a9ec650e222f428ecd7 100644 GIT binary patch literal 4036 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 P=MC6eIa=17^}F#OU(C@G diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_light.png index b0a3fb329dc4958db8e17c82e41fa3cd186eddc9..c3f83045e5ab7a3ddc64e0be24054b716a035252 100644 GIT binary patch literal 4064 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 DXjKt4 literal 3991 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 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_end_vote_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_end_vote_dialog_light.png index 3a8a10da92ef6785734f51a943e5be9357c7b332..ed70476642fd1b4500ef3f8883016a7612ea04cc 100644 GIT binary patch delta 1916 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 JKYjV$e*r{~oksuw diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_dark.png index 31040b0822d59ad71fed591f067aea1cd9e20767..f4fb8c771cdd0a1e8f991865441ab0fe351bdd12 100644 GIT binary patch literal 952 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuk+^_TgqT2!ys&Fill;lJ^k9Z*PDy3gt*wjq&3yjy{EO9bbB$+N zdRvFD?`8IQ|77*_!n_LOx|_99`}bE_e*Wb>zeY;juU@QtpPhXD{FulSJ)fiUsu&hX z{rWsL>qiwb+s)653+o(ss|C6j zg>+tYn1LjmH@O4JWFrvSya{CJVj~cFc#|uTd~5_H8%%)86_h-IS}j7VfaH(qlNPH+ z9H^fnrF)R+Uw9`_`hmw%kjj27&8Q|;pAavgsu^CKK#7DbU!c(qGfgCcYSXTTfDD!#a_B-3~#+|;o z9XF~!X|(0Xo!|0rMaJBS6I&df_g1Y2NomiY-}zN@-^O1Tdd1H_zP|roPjPwPu}`}n zaEfg(SbQ&wN4sa5vf_q-{KZ>E!<8OAx9o3kV%52`;(Gn=%d?E5`dS=xS6Rq$i3QBA z1lhRuS?9C_#;w+QKsRL^DO>~;N>1wq3iZxX1qO&o-YsD41+-*>Bn;I+A+@MR2Ph%( zd_{)t+nBv(c_o`H*REM}Bs~4RiLIONyLpojuW8W|P&mgy*Rpj;I zxzk>!HY}2LJ8i9_(ENQm1DDu@Lo2R}>nQLaWV$4vqrgjm@~Gc?=H9(Hp0@9^unF>;^loSka28M{fhqq zFC?6f1>E7AYh3yA!mg$(#tMC2Z_qW6N?+)=LtEGRlv!7J)gWK=2*Jm$KM4K_3z*0iqzclZEF1z(`@4i6#SgG}e9$^prL%b#R$ihXDdTC5sz zzQP8(z>2$35?RKwSm45S=0w~S-{L(V7N4R?d`ty zcZD5D_}$wCf%eIscltYio}ON4GJCCQec+Z?f9Gc|Fi!hhC*!B~@xiyZH>7*7&8sgf z6579~Qn);Rf8WLZ_dfz%oefm-r{;B7>ct{emTj+Wq69xySlxY5r4e!9TBxXQxYGi$ z&=`JJ?iFX30X?}OY&OXEw_?qK7Mnb>0tp$ub^{8ztrZ3ah}8BhV1Q^G(gI0Hgo6TP zQH&T+qN_M?OWqrK86D}nInIwiTI}0bzW$|Y*2gC=FV8st+;=_WR!Lp4k4IOBKewMz zc8IC#>p#!apN$+Y{`+mxD=ZeUryOXYLTluH{RjuSCe|g25e`xWsEPj=?H5?j+0bCZ g!tLQqTk0R-t3=xfi+xbSqdzyDnTRNnF^=w`enG63@ZjSP}32pA2Uj7oRJB_C0$3^ABtO z?MeSUZ>IG2y!{*sd)L<4vt7Ub=+>|Eh2_P?FMe*G>o@1++^%=8o@Sgo+nahkQ1<7S z&FA-PRdXhkoc;MTV^6V>*l+$vAFqYk+`1{5_3z&0<%XL#3%~s>ZCL%Q+2T@8U+(q8 zLOLrZKKoN+a(`|978dTTWhXMWR_(3$y7l_;ZLc=~1y-!cn0w=gZq)K=TEe;qn`UXL zM4g`>t`*h9Y8tjZgH!BE%-lt)5eBTUgn+V|f$cycpNVfS3hB%+nz%H@0yQ64w+g6% z>08KBps5?yuX6F;(7?RX3FuCX4Vysn0jGe*GCFH(0}Yh%nt0J_*N-@pwDj+DXYMR~ z{jFQDOz-aB-usU~E#*#K&p7q_*Qu*NK8wy5|91}3-agO%_RAwP zCwFfw_?NWh)?3^8wW%$(j7jTm_X@|aJ0kx6`=i5;kGId;|MNp)&G*-PE4F;|&EaRO zw$qL{a6(NK=tM5VPM{M5W)!*uo#?c;=i1JtPY(fI=9b z=*a|~sJCS$VPTK|e0q5Z6aqJZmR3AIv=q#V_$#@#yA|ZujoDkpxhyj|#S8>pYvj1Z z3=9_o1GAx1N)_l|pF4>l3pDwF(Zb|qoC6FMjjIMg(-)Mm_X0y@YQY4MlO%t;0=0PE z1O-vZxx9;B|7WjHKfmqqZ)^K0dyl!)eER5qF~j6k9J5+lwLu4a`1&Ka{OynZnyl^@ z;ZXYb_Y$BLOaIz}G~YYz&A`g-vG8h~fQ|zHL8ePUikAT8QQs(UU^{0+g9!__hcj)d ae+-US*4@#M(#iv7Q3g*}KbLh*2~7ae+^=K+ literal 979 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAu-+@QUFW%X zXrySn379KYHaPtjVHB_I)H2!HQK};Cxm&6ya)tHoRUx+Sk=>n|~F) zdv>n1ZvTJ9hA(Wte}62gwywK%yIZ~4@!`*}dFK1}*V*pdU9P_@dhNtF7Hjm)&CTD3 z?`1LAGqcQEFLtlg-Rb&|&o5s57j5)3HAPUQhSs%gVRE?qT7U zN?CTd?yshs02z3mS?wjiZWBpEk6$u6}g}6kv%RbG5I( z|DK$iyY`jof^TKz<;j_uE5F>Aee?c!{_WczKi`Y9k>uezzrK9;#=56oHPz4kwph&- zp8q$g!+4+e>-K&4vp9VHql=rkLi()jxJn%y*vNb+e4p^gIqZ=qtvP}Ia|9f zB2p6+7(G6#FLz$uUG5F?sPffUB}q${c!Sib(qd-r6}LK<8yW-;uHO|LpaL z4l4KY2dO63C4{J#_7B*7_{7B~v?VZRa?q4Ic0a&n&qemPcaH-z OCWEJ|pUXO@geCyxDWdrR diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_dark.png index 64b49fed36bcbcc57cd5a9085937da0f8bb88712..43b196316fdf6a9c5ef50562b98c95a94a6c4c3b 100644 GIT binary patch delta 1013 zcmVOnO7z%AtY1&O7i*(~c zMcPudprUl)!kt;!Kj0rI7*cUBQV>CLp)TBXsi8CRr+rGUui#9>9poH>@*2Ly!TpBr8m}m(WlvHlfiYQF91Pe;6 zY|#=dD7i94OMkGS1C%9Nf(0F-4ABxS=pd;_OR%8Bq#P~5f)12wv;+$}REp6OEa+gV zMN6=t!=)50!2*(rmS6!9i9{=Nu-<+9L_V7Ug|NQ35bvM;JU+X8G3IKuhGx&z)}pVs zH(t5E9D^s{i=Kgj|2#kY#aEej%N(qC-g+bJD}aJodVlTZsGK?#pUlq2?8-_*v)?Z* zMsM%-c=Lzv;^>((@yzbs51wTW*3+4$fl?YC9gSB{pNBozIH9XJbymE zotld4%ged#C0M{i6){?Z1w2yGqP1=0#X}!ud4WrJD7XHhq1Zh>9+mm|Sg6(F*Y)*= z<}cQ2aese(J-X-S;==8FvDwx9)wy5+Pn1`*Mry0EI#6jkT8@N3UGg{{&aN!S=;dEx z+nqa2?I2h{-LgjOTx~5=v;+%iNIRn?SU|(t6)nL6nv!Rb_h<pIj?K*E7A?U7TB=g5 z#?imOwD$JxXn6kL(Go16<%ag`iDNS}@%r;GWQvwx0b8O{t;W@nu}sktEMUuQ^zFzL zEq}oRwp5mA2^O&BnvIrV0d3Jtv;+%in?|E0SU_7f5-q_3+OFPc2^LTY^+ZdsfWmlE zv;+$%l*dI&uz#+Px6K<2;C#FDxJhe?{wnU;$~^=-Vk+ zKsp2qNQPhm$q+0c8G;2QL$H8kWd7mk=_-#u&1aK>8yXsno}Qj|uK^t`bFdZ`m-5-9 z;C?#)bKJUhyWML*M{^_ulj{Q>lk5W)8D#!HtUp%Q^4X-|Htue;dj;rtf(0bQkr0zG j1T-BXSU@ra3rNPFiT_TJ delta 1001 zcmZqT{KYZBv0lZ~#WAE}&f7ct{pXa*9Qf$}P=M)+_=N*yxiS(y^(rB39nIaHx#Db( z--Ibo{>vUCX(f>L#{R*R2NxvPW{azuI!<<5C@UqL&FN*~(HFH~#|<}M&2pRbh3CJ& z`zrPR)6SY{)z2&6Rlc(<`u6ANU4}{5w{H~{p6XSzcbAlXe%`fu+yB=tE-w7`=o3dXsaaFS3-czo+KX8`Xw4+pMgUcdpjH_wGf?g zQFmFpfh_Lqtstd4!n&r_Cpb!HOa<{e!#aRc(w??aO{}?UPeDQpLl&z>Tv!&=1CsF8 z1xe^F1xift*}}rz;h_?>bdCInhgVns%wZBa6o2~k$AfF5KmKfH|Cqcq==z(vy}d8q zzU}?~`}gANEUjIAvcJ#&o_}}G%*^e|k@6G&Tt4KqjJ2WuQRSW;68GbFi_JfG{`j9$ zUUxqSFZVxQEv|p;skHf{8y`M&Uq2taV?yToXZHF`8gnLIyjb!4*Vi8zH8#im=dP;$ zce$E#nyjEIjrm#cq}DQ;EAMIoI8f7kA?XRBN4O4_eovo{eroSbY}@jlKb zD!Tjrs;j%6)kj8mr(dnlD$&(B0h>nqH`?nn_6Dv^+x7IIreeTk8$W(=t*J92 zqPwq`mGNz9PGB@WEw$EKT6*Rp)d+{!S(3U3nOg9|pAQ;k6GaGt6PG)-n# zbG;jox6Hx==&FoaRUlUdUlj&=Yu37JK-~cxTU~(ihi>QtRg0Wj4RX@MH=;m!u9vAG z>o)w8UmLVpoT*}}_{E|Y)+G-rfd+XTnjGZ0p`nCBYy!_grb&ts4n{!1wgkqLCu$zQ zICI9wZnj8Fe0+S#v^(ii+-Il!l-{v#-@Nl`tl!VRz5Vg|tE|n}8@4^0GTDH|RAJ)J z$_Vf8@1Jk>JQ!+jK6@|Imc3^VM#V&(N*8XZwNPc5%*Y}>IgW*IvOkNM*hlmBkk*YV SCZh8hfWXt$&t;ucLK6UBcjc1+ diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_light.png index 67159eb2af9806d34f2db9b5f96d6314b1a6af60..c062eaa49f0dc8c9b6c8aa7a8570b69eb3683dd6 100644 GIT binary patch delta 974 zcmcc4ahqd;V?C>yGuN8DIXh)lK=E>1@NFm!0mI z|Bc}Z)r!4cx}Amlmq%)ijh6qH{4GGX&%}$X{Ctl#PQ1A8?X0N@j`CVsQT%#;B(6SI z_Y&4U*kl*#u_bD4kgNBG1@--3qd{6??18)lhA-Yg4x5X;3y{;WL=LEyadHtzC}7n^ zAsvYTO*fFlQZbOk^dO*whgwtDN=xzumjx1-859H{I?#J!BO*I(~kq#EI%wil#*=2tDC=iYctytr%cmMa%~ z5*T-fg>1u@Xb$dNEeR=Y$3k%PDo*fTzU+2^^Yq`p=Ut@r7 zNH`y&u3ij`$_Cr1>LAITcY!h1Fz<#h$cHo6fSkE}6EJog=Djun%1^0xQU{5dlyw0; zymV76$hmXZg2F)at~N-)wf~EOoRxQFfnM`^|2|``xQ+tv)syYOsBceTJSm`~AlbyK z;=G|Dg+pvY&mHlV^Xeb3O)}Hmx%IyE#*H7-*I#dFoMs)7ytNY~ICJLA88c4Q=?VtO z>~C=}V&R^AkXdc=DP}H(o;%MIWvzc@7|xz@=fnw*_2CVT)9oXU%W0wn(cYs+ zEzGTMZC$%uHR6K%s>zcJ7xpg(GSjd;ueSH1(^~T*hB%G6z|5w&lR$5-)vT%?6L>qJS`svvW0e0{EdX8+3(yhzb znv`8{|M{kIS7H*5J zixz$T{3^>Gl@u&pP&E#YeMN&b)5yj`xbru`lqJG#B%1(e=jBjjY?m1G4J@Hv$H`? zKQMFVjCo+soeP-+?k#P#+L#*3X)B% zD$W}kQaHpW@El~CH1T(TNO)LSS7cBTJ3ITuyzSMt%xqEb5<<16CQX}i=hCGhA79_E zRct&a@tloNO_SAGFJ|7nma#!{21ro&}a_IG~cUO9Mo%6Steg# imYRH)Syl>U(MNSvtAp!X9>q*z00K`}KbLh*2~7a5K-D+^ diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_dark.png index c7b28fe98e6f7ce77574d158c7d1bf94b2323e6f..335129ec2d5d02d5132251817a4cdc053946ac3c 100644 GIT binary patch literal 953 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuzu+XCXpOkM;u zg~_)QsM*^@5h$TM$reOTwgiz=OhM#SLl8Ml7er3i1d>aD${7Vcfm#o2yaaT{f&Eit zbPqE9TYLp*=7;@WK&LROYk}0yS+xWxWDulzQAj62N7co9L&L_avOu+JLFrpqxMxJf z0wo^!tm+BN|N2^@WSaXrPx&?8@ilVx{|c7BGh9${zqa1G?&sIRsf>;CsTTzIX$X4LaEBi##C&F6}~Tr+=sEL}Xgv?qU!UCI9hd$~8Z-KVYl zlRn0N06KD}W4h%pQMc0*1!k<=e(_d^v|wTRsmBWw7>&(el-z%}Wm(TOWkmz=P#Jz! z?isT)K>-ruD-87Hvv+GiE)z=!h1b@ZCP2qt$(jTVkbvEVKvfQc$3PNCB}9R0yNaTK zF4Z{ac`@q7uFC9)*D1kKQBhs``mt-OdHf1LJdgkQ=4ag9?)JdeZQfB=UzOMMuY=bvtRgz1{)S`59bXHCIl$uzh8~o+uJX`{vY#Q o;(*MJM8-@Gu?cMnG^O@1-ivXuuleX#3e0{Cp00i_>zopr04Ii!+5i9m literal 948 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuvSikP=ySKVb z9`BF6%&e)akmz52xuUQprt)9+M~kxU+aI@|RPn3cyY}69Y0DfdibNGvu}T0#lju6(-Gfbi8O}fn zE0t;xsa6akHL^jZRx*gxi3X8+!9dbOSoa{4(j*t}4GqRi-GOAihGkR}>mT=(Kr`@7bGg+`reiURh}wIK(ploxB+6;&LZe z=h5$zDrtYaCr`19aM+yH9d=|X(9nd`*+AbjZoT0GvhD1y#i|hwYwg@#*IkhZIwI?P zok7RnlPd4rkDPpcz0hEG=q!8vsM&w#XD%>K`&;+MU+v@Bwb2`mr9$V`7nO*dzqhx0 zcmDljFV?@W;1t_nwz6y^9$c4$0fF*tkm`NRDl~ER_ofE zSaZ&-0=Z;ySSQdW(&blyKEBYg8Wa@ALVAHhy{mxX&Lp)x2k1nNLqpMShLJA1Rdk98vB z(O=&^Pk%OYxcKj%Nw2V2z@C1fi3+We`}HFn|-3lePc= diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_light.png index 1e25581c3d0d148d9554d4e52eb737894e068b4a..8ba4098351a4c098470940bcd7337f0fee133808 100644 GIT binary patch literal 987 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAu(AgW%rLyi`cSAxkhfK6 z-J#V6E;$dBI%X8G&XN%7Ep6-+Q)5ZHEZ}u{!@<^rKdxpjFHSpGdG1f$>(6s+R@dL# zTzUS?+S}!EEEDdPtr!10`*mUR2I@4o;^FZ>G6ubnm;F( z$4}YIVzBGjpBkCke8Xu~{Et3(ES2pY4z01oDH}95S`+K%w^|!+omoj>CuOAlD zSuqi)*yP^&{4FfpS<6mjnC`w?@%5|uv2Cw600ma8$e4TMkM6AWY1+cN2b*STsYIQh zAFdVE#A+J0J%dy1O3d6vsu2dPuY`cInt|;=A)kqFE(+<)Fq*j-DABsf&3i+FS8C6+ zgo7fd#XyRtYXWsI>716pDCh~)dmw(5obExUe+y3mbv>|OB?aPyivl$tn70b3fr)KZ z5YTBi!b3rd8$%RSdmTyf<$ zF}r@x-hce6_ViP6%v$eHXJ3E(w)~#%pS`#D#@X!qSbFDAs`9(MTwdGyeRuncyS+CS zd@M4FUfXznpV6Ut42IWV9_c(E{&+M0u8$W#K6XA||M^2=&F|NHE4KU#ee>lv^L$aA zgp|o$K##P}Z~;0|-faL`Akq#B$fc5Iz)+czH3MjRz^-OcsCZd;0CleD`3p43VJQ#Dl~Xr| zZ@KjU+3TB|=l*#2TmDpBGo# X*WLM6F8vsoK^Z(<{an^LB{Ts5EzYsd literal 978 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuux+UtMnq}e--zt6M2zkOf2#cKKI zdGBIgeg7@bm(M{Mt{6{=FE+g*{o1czZ|$6x;OIP6Xzlm+ z*`m5YUD;7vSh%Iuc>?v#VDbgZ9-NZl1Qc54@hyW>%xC5qkc3m@V$}$PrABVv8xp!w zyFrRhi|8I?y5!=$p`k+ssN})oUG6}3{fc6s-XHzDfGQjQhaLwSQLt*4E0DAB6-dLm zkm(>Hz0!_p35?IfN`Zb*ZU-PNO_db0hYbuipaHVi300PyL$LE|9w2KaU;_(gS*1ZBfs4XCRe!1*9TyF(}wN zcV__AtT^HdG{GUY3lv~pqQLNHoNAp9l4$)5QgzEh8|b_%r#66GW4+u}`|tf4S$X;6 z_wL1A%{Dl4>XcVbPEN>PHqO14R$cSuY&zb{+xNxC?=MSa{QC91H_(Kr-_;=F_U^Z1 z(ui>2`rO^!#QH=r!a=HubqOKrrTqhTAAWJM32h0CnH)5wj?J&xy656f%T8TjzGU!p L^>bP0l+XkK({-qC diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_dark.png index 45af8b790d105590794e53fbd92b2d62c52e3de3..ebc4effb460f0cf7ad60065097495df65d9a1640 100644 GIT binary patch literal 951 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuby}NM71GN0Znl0tyK>&Yo_(*bS}vZs zc|+~vX9f*l{NBGkcJyEKkKE^(fA(#+{`hNke68&C{Xfm*>gzS{&5fINvgdNtnremx zQtWr9R_xd&dA;p$N4mAJ`|Ee7#RUZmEf?L$;1n}C;aILJw>JOi)($r}?+ptQSM`L| z*J|IJXK6g!(cfXig2q){*QP!+kjstHQj2P07Kh+P zsu352d^>;=-6{P*@^nfckmOG71(M#WJs|PaZjg9t*R%x2OrUZHmq|da1xvmF$qy4J zEmn;$VX$o%NUh5&prMSytF?g= zb3CSAe6{wkK=ZjzCrn>9Z>@S5^QY+f^IgXq9^L)*vh2^#>-JOaHm}O~Yaw&&@Yk~w zFM7%AEQp)xs-2Xwg@t>@tvw*;s6G<}+N5Rt8fZtrO8$$t;w(freqM43#NFBa&g+ZW zwj^t%Z}b1i{xx5(9#tQ+#qVrN)Pk>UbDzG*%{lsY^Yi4~p8Pd-rQe@+@A&@b{*E6% z9CiMQ+Z<#{OS=%+SJ!&6NQEWsl|j_(LR+P}xt}UDA`YD4wYqzF?zJf(sb`D29xqH_ zEH=&sxoI^hhz{JDYXbD%l}9QUg>)8}O$NqLLzJ%&(3x50c|cVfhb%x65{p6Z58MX| zsjlLfEn?g9@5o%Ux;bUqv}uoaU;SL#AJ`qfyZU3v^T@l&2hQm1tCY>&``g{#=XN6F z(O)IYpH@jO$Z)^-iI4llgTtx~O{_}{UX-wMpK#vLV8X)fL5R8(ufKW!e)+xspUXO@geCxax0pQu literal 946 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAu@n;G=U+viDTc!$IH91h%bO6%ulV&m(os52wFQ zE0pCK7H(l);}dBmpe5?u5wPaS+TBxDuul4M^nBg-J>P%7J#KY5{=3(=uf2Eo?sa8& zSzA~pc3)2R=;N0radYN`%=@2b(|7mn+aIMyotxwGb*ZtyDs=~(*lr8i0nlvF)`hPO=8*6TUfZG*7;r((s|La%>}4X`IZ1s zg72gpknB4t17e?&0RdXnBM8RFL|0AznbsBD^?(5($~U?m!8zSv^1cqn^ncDanGM${@B5Tj%(-ttTX8N3k)Aar6j9fadq{n&*sa>ySp5@ zdsJzjpPJ$8_<2jd9Augm8ofnn9mr_y+aW+ZR~%Jaq#EIndrcN-Pu5q(sPBva0mC6+ z_xEPUH~wmc_DX*7`}>-2uDSHb_2R8J|9zO}8ovIXTyNCLzCHi=xr~s?ecz3tUb_MP?G~dB3?q|eSwNwTkf}hoT-cGi80bX7X`Mi|M|Wre zrA3}@0y%O{_oC9|^8EaZFVeK7`j3D7ySLhR{l$*y?d>1m{QSJ^dc#)9v(G=Coo)Wy zen#0Lrmn9aJx_l&a=7^Kw@I(CSil~BU~nt6M()>-aFAa+kf%TjX j4JIty9?rC-{xJruoINqt>%lW%zGLuo^>bP0l+XkKlA4|t diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_light.png index 5d1b41f480ba31766b7bf86f14adfed5bab03b73..2d797581828d3846207220aaac5f18c654da0c24 100644 GIT binary patch literal 986 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuvnN!+7?Jn`^uafVD5Qzx5i!;!PO?Y zUh5C7o{+@*)>TCN3zx`}1rq#P8Ml^hsTT6OEKn81zvNN4otgD+G6ub+CL|k z$A|1?G1ztOPmN6d^AeqJ?~gBj`?g}oZtE+5?yCDIrInj^RnIo8espumbX8FO#_(Y@t;dTZyj1V`toLTl5{ zXNl?_Y+}of0_j-ic~MAb29qyP_TZEZC!o+Wk8c^AVm>p^fFztE7pq1XEH!fT-jL9h z+6_{4T159C(g~V(R+RjGz2oC)w>vj)Nmc!eSuULJuYc@N ztM^5{uG;yvnJu=AN$YO+2G3uAEM5M~qs5ce+voj%cCh)!x9ht<7W`d(Lz3rPZPTntdzV%TuKj#kd#O9nZI{lL?!Fiq+YRJjv@T3~@pCW86A@dw zm8@207bZUS$prZ$=a#Ere$1X2P=HFTwqIPjatbgk49eanEu1nLXrgf7vF8hclyMeN z!HgAwATy50ngT5jd87fd*yu1QAiQ{mfdQdaegmjEfV&+SBaB-M1AtmqO#KVg;_&v3 z=-My)e^&h}QQ!CbU;C=-D_jEi$es3nAHJ8Z=j^!zf$!^Md%w=F>*+n-KX*gJuV3Fi zfu=_Nt_B&gSA04Hm)HcS-4Oyh3jDwb1X8>ND3AI^c>~)y8yZYlxILU{OZ{Uo5m|R9 UGK1+8Fn=<5y85}Sb4q9e04g%D&;S4c literal 979 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAu`PJ33~x5%E=>=gnl;2 z*?HmpcYBrz_Y&&u=jG)e_ph%0m|~z|v;X4TW8bf@KVJU*-O-TMrjumbzdn8T?AhN{ z(;3>#@8%s}x;lLE?@y_JDoaG__g05z{Oe!5xMO?%<4fJ*AHSZRU09fvm9l%@^aRId zpY68|FF(lO6f^Oed2!dB*GI!IUsk@oRpVe2o0fKz@%j13pI*Is%f)-cf`wk4*M5KB z+BFTR%Tzb2iIw;I5}-bxhGjt61SbaQ9C4U$=%2jaMtf;22& zFDZC{kOaM@82J})z)?QZg;CUJ3jo`n`dseE~Yd8{hiLR<;9OS$MbAd zcQ~V~ckI*K+l8-hZGCa}tmwS@FRwyvs=n#e)&4NJCnGcG$C?C2XX$W|^+zp0UdeQm z1v=mBt6|jMxR*dzFDNPQ?k-Hu*3SD{_0e~CY{kDFKvxXpFb~+0s67WRdRhhkUF~oq+(55Com|I%kKfr z3h4X{3W`%Ay+EOSU1f-pYut{ZjwAw4y@7+S)pF zePCy6YimSw^y(^JiJ9i?>>p1zvwwX2`1r@)udnOrEZAqaAEb9{y*to`Tfd(xH#D&> zF|fARk8qF!vJ@j6qzF(G|1sAccv6tan8_hFp$!<{G^GCUT4(IJn0WtkJuqW3c)I$z JtaD0e0sx}hpvC|I diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_dark.png index 1bfef3bf83dfdd2057ed1d034ec022da9c9edc30..d7e9fc6c474e350f624db777109873bfa2603b36 100644 GIT binary patch delta 793 zcmdnUzMXx7V|}8hi(^Q|oVR!O=81$$G(0?iLSpT8*31AGhNT;1MP_qxE`7qJ)3RbG zv(%{=r&A_7`HR@6>}+UAh^%vIkPzYIs#B>x8zi99noxG#dUx@@na^LIf3Z4luJJ5O z?&$D!e9Rv2U(CK?hdo9PX z;#gj}>bo_0N0vS`c=Yqzk&C;2zDjj*nbWUf7S+VcyXkgp=kDy;g_?^dUKG;Fn4z`! zYW(eJD=;1gYGx%oWIgI7>wLV3Sye z*A^D;s70J0iHUD6)&r@TXF!~VYe3}69uT=P2So1l0g?*7K=mCSLb?Z;zD<<_lK&Pz z$>0?GV87JOdqac1mLbq-GAp)#ghEw;_B2fN>YSFqn5?M?l;~Oe4k%$T(Q2`3#DOEP zx_}bxL8)7+R@)z2u-T@__g6ywT+6?)f4;reFYRYMy1VS}^NK&$FMG|84Bb*E#rOE! ztz#!Lmhy`QtUt9#)X)fMqEBud&`}G7K6e1knmV%-=(rVEmS^PZ%5>hS3(Ev??*K!w z>h?R#o(EK=amWHBA+Z>!)**18 z7*L|C*gIg0*tT^sve&F`PMJ1s+N0mb%U{VU_wL>Mz3~6T#k-C-Y}DCTExmfL{rCDA z+YU2zef{Zo`m2${#czwB%8E@mxZIn8mD?ln!b>i(3GI`4nUzG^5*Ra=?2k)JPgk${ w%MJ|HGmWy71)1e0OEHVWuq;RshuDN;>}k3#_Sa7c7%~8Xr>mdKI;Vst0FZNLL;wH) literal 945 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAu*i978JRyuG_IKRQ(8z{ATo*6Av0=ZWu1?=wizgK-c zo*;1l&6^`1lLYJa#HK#0x3%uRSR^^$^~n3fiGTKP-n=n(z4wL%uD9fL4>nC(X&j~B zcKFBY1sR-TTLNM){<2Z3)7FS;V$}_G-_q9V3RHRYmKaE7cJLM!ZmR{l7lm|QbeOpS zC7d_81Ic6~5ZS!R4M;9F0+EL|fwVm~0+J0TK;;Tbor_aIYPkP}cMBJwg&V!@dX92k ze6@aKzTmfS-yXHQ_s@!B?)rZBaC>1%NyzK;eX=}{3d+s*^>)ngd;Ifd=F*?(>gs}m zh2=YY?++T!Em5^8@A?Z13i2tNg8CE+3Y@`%eGdDul*fZ4|K$e zySEQ2@TpJUAupJ&AAjs(PFUu@MH#u@>z6g2oALE`p~cK2&9}EF=bNmu`TypLN?qk= zwRijKWEa=(e+=~Ju`|E^{`h%q?X5*my*P5NRBlmv^s!{uwXXpi8hTf2N3Cl)5O$@| zRzxQu`x+=fqPO}1t-P`8HON_RG3r2PnJmi!3T1>$1xCfj7%Mr%CbT6mW)h&>ezE^)cvo5_ns g0`EbZQa{+;SIwTtoKx@snC%!mUHx3vIVCg!0I4>fn*aa+ diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_light.png index f7b36287dd6c32c9e4e61d706f05ff2eaadad526..2279f4d996ffde01855095de015c94cd72c30707 100644 GIT binary patch literal 988 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAud(xjBI~%RfC zf8Tswe=3eiA~rcuG3~ykr1xI-j}_I{a&O=9nbyC5d3naoyS>-`o}FR+*HI?ZDARXb$GdRV38g~I@6TGe{0)>KAs<*IkFY|c@l32LrqL9vvAj!q5 z5e7#$xdIiPN(Jg>%v_`z;ovd}sN}=+Rqoy!8tPXR0d@W8U*!hm{0}_}l-aO+6;MM% zZKx*DRGAf8K$8*_LOX!EnYFEfLOe^)096@m*#tD}z(Ntpwc*q6b>G~%lQ}&t@6MjD zNiB1|%j-XX-%<0@>1MXW)7sjnS$lq7yWP6K92k_xukY)9y+7y3-L-2MK0m+hcHy%p zK|1sHOPmeMzMmd1ndsjz<9*4aBhy!ZJo@|Yj}JdSE_}Yf`iH^3|6k*5qW-Iu{rX!w zUsNX{WirS&tutJJj@LM|1L#eMg>i1L?|kxl2z2g(g3ojPwuE1Q1mu_W%Su<(tp~YS z>};6!t<~9ubx%tYL7vK)wKi-|;lm&>XU)H!Ye$_xUbEvet&%MYHGy)m&b2Zd^*C(y<%Pc ze4ynkw(JMR&#CH4&IJjKnkLcRO{`B8BOIifSeFo@Uh02fUe+!wHlYm|;~X@lj>+?Q Wth;0EWmgN#p$wj`elF{r5}E)kZ%J@l&($8QF)tXkhbvMn^l+UJ)fn$JG1xsx$kS=OP+gm zeCKTI>A(K|YiGD5EhBgA^4+^X9zIZ*$HUh8+`X@N%dd|<@7%fZZPb(mN9L)bYkxjJ|M=9es@z4Y5f=iM zy1f4TJId92!-9je#B>ifwPgnZ^(}J<2FeJH0of1aU&-hmWcs&w9f(tZ)evaJoK<-sj!$XV zv;@ZItGt1VCA?&TW*oS%st+jC8X^hQ!nIlps5Zu9=EbOp*xs8ze-@|fef|BHU-?bU z&bs~b($dnQ>lwFh-@jj8TU&eS|91~Q7}VXo+bhq{_vmCoKtfx|&QX@yK($xSWnT39 zZytaA`0j3PP;t*uK{4>Elc&{5z$$aIMS)%!*M1M{+WZf*}}U|h4%lzQy{pLNg0 UQx=uAz>LY@>FVdQ&MBb@08vV@+5i9m diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_unique_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_unique_dark.png index 31040b0822d59ad71fed591f067aea1cd9e20767..f4fb8c771cdd0a1e8f991865441ab0fe351bdd12 100644 GIT binary patch literal 952 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAuk+^_TgqT2!ys&Fill;lJ^k9Z*PDy3gt*wjq&3yjy{EO9bbB$+N zdRvFD?`8IQ|77*_!n_LOx|_99`}bE_e*Wb>zeY;juU@QtpPhXD{FulSJ)fiUsu&hX z{rWsL>qiwb+s)653+o(ss|C6j zg>+tYn1LjmH@O4JWFrvSya{CJVj~cFc#|uTd~5_H8%%)86_h-IS}j7VfaH(qlNPH+ z9H^fnrF)R+Uw9`_`hmw%kjj27&8Q|;pAavgsu^CKK#7DbU!c(qGfgCcYSXTTfDD!#a_B-3~#+|;o z9XF~!X|(0Xo!|0rMaJBS6I&df_g1Y2NomiY-}zN@-^O1Tdd1H_zP|roPjPwPu}`}n zaEfg(SbQ&wN4sa5vf_q-{KZ>E!<8OAx9o3kV%52`;(Gn=%d?E5`dS=xS6Rq$i3QBA z1lhRuS?9C_#;w+QKsRL^DO>~;N>1wq3iZxX1qO&o-YsD41+-*>Bn;I+A+@MR2Ph%( zd_{)t+nBv(c_o`H*REM}Bs~4RiLIONyLpojuW8W|P&mgy*Rpj;I zxzk>!HY}2LJ8i9_(ENQm1DDu@Lo2R}>nQLaWV$4vqrgjm@~Gc?=H9(Hp0@9^unF>;^loSka28M{fhqq zFC?6f1>E7AYh3yA!mg$(#tMC2Z_qW6N?+)=LtEGRlv!7J)gWK=2*Jm$KM4K_3z*0iqzclZEF1z(`@4i6#SgG}e9$^prL%b#R$ihXDdTC5sz zzQP8(z>2$35?RKwSm45S=0w~S-{L(V7N4R?d`ty zcZD5D_}$wCf%eIscltYio}ON4GJCCQec+Z?f9Gc|Fi!hhC*!B~@xiyZH>7*7&8sgf z6579~Qn);Rf8WLZ_dfz%oefm-r{;B7>ct{emTj+Wq69xySlxY5r4e!9TBxXQxYGi$ z&=`JJ?iFX30X?}OY&OXEw_?qK7Mnb>0tp$ub^{8ztrZ3ah}8BhV1Q^G(gI0Hgo6TP zQH&T+qN_M?OWqrK86D}nInIwiTI}0bzW$|Y*2gC=FV8st+;=_WR!Lp4k4IOBKewMz zc8IC#>p#!apN$+Y{`+mxD=ZeUryOXYLTluH{RjuSCe|g25e`xWsEPj=?H5?j+0bCZ g!tLQqTk0R-t3=xfi+xbSqdzyDnTRNnF^=w`enG63@ZjSP}32pA2Uj7oRJB_C0$3^ABtO z?MeSUZ>IG2y!{*sd)L<4vt7Ub=+>|Eh2_P?FMe*G>o@1++^%=8o@Sgo+nahkQ1<7S z&FA-PRdXhkoc;MTV^6V>*l+$vAFqYk+`1{5_3z&0<%XL#3%~s>ZCL%Q+2T@8U+(q8 zLOLrZKKoN+a(`|978dTTWhXMWR_(3$y7l_;ZLc=~1y-!cn0w=gZq)K=TEe;qn`UXL zM4g`>t`*h9Y8tjZgH!BE%-lt)5eBTUgn+V|f$cycpNVfS3hB%+nz%H@0yQ64w+g6% z>08KBps5?yuX6F;(7?RX3FuCX4Vysn0jGe*GCFH(0}Yh%nt0J_*N-@pwDj+DXYMR~ z{jFQDOz-aB-usU~E#*#K&p7q_*Qu*NK8wy5|91}3-agO%_RAwP zCwFfw_?NWh)?3^8wW%$(j7jTm_X@|aJ0kx6`=i5;kGId;|MNp)&G*-PE4F;|&EaRO zw$qL{a6(NK=tM5VPM{M5W)!*uo#?c;=i1JtPY(fI=9b z=*a|~sJCS$VPTK|e0q5Z6aqJZmR3AIv=q#V_$#@#yA|ZujoDkpxhyj|#S8>pYvj1Z z3=9_o1GAx1N)_l|pF4>l3pDwF(Zb|qoC6FMjjIMg(-)Mm_X0y@YQY4MlO%t;0=0PE z1O-vZxx9;B|7WjHKfmqqZ)^K0dyl!)eER5qF~j6k9J5+lwLu4a`1&Ka{OynZnyl^@ z;ZXYb_Y$BLOaIz}G~YYz&A`g-vG8h~fQ|zHL8ePUikAT8QQs(UU^{0+g9!__hcj)d ae+-US*4@#M(#iv7Q3g*}KbLh*2~7ae+^=K+ literal 979 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U*U#9OUlAu-+@QUFW%X zXrySn379KYHaPtjVHB_I)H2!HQK};Cxm&6ya)tHoRUx+Sk=>n|~F) zdv>n1ZvTJ9hA(Wte}62gwywK%yIZ~4@!`*}dFK1}*V*pdU9P_@dhNtF7Hjm)&CTD3 z?`1LAGqcQEFLtlg-Rb&|&o5s57j5)3HAPUQhSs%gVRE?qT7U zN?CTd?yshs02z3mS?wjiZWBpEk6$u6}g}6kv%RbG5I( z|DK$iyY`jof^TKz<;j_uE5F>Aee?c!{_WczKi`Y9k>uezzrK9;#=56oHPz4kwph&- zp8q$g!+4+e>-K&4vp9VHql=rkLi()jxJn%y*vNb+e4p^gIqZ=qtvP}Ia|9f zB2p6+7(G6#FLz$uUG5F?sPffUB}q${c!Sib(qd-r6}LK<8yW-;uHO|LpaL z4l4KY2dO63C4{J#_7B*7_{7B~v?VZRa?q4Ic0a&n&qemPcaH-z OCWEJ|pUXO@geCyxDWdrR diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_dark.png index b20fd3c286607073e2c5e11637e0fa38d89ea25c..c8dd458771e94ddb9334e8cc448f44d9b43705b8 100644 GIT binary patch literal 3522 zcmc&%X;@QN8omkpB8yOr0l}dyYam)J&_IksNl=6UDv)9zDPbgnY_i2bSfmtWcVtnP zfFNZnt3X&v5-NzOpaB(GBnk?IMMT0T+g!raAM(^fAuS2^XrX(vz!xOwthFUj-KQY{4e=n$)90nZCqmjY z0Zh7l+UoD;X?gRnN7C|^8QqHuYq!x??M>cO6`EASV;AozDcPwsmS^O;7wTc#-}zta zB|R4wo%J_}vq{Ox$a)@^4x=1_iG>nsh6bK|=(9z-Y6Py(*|Yp5iw(M4c&ByN>RU9& zYjUVh4#_?)3q*%|dN7QbzX@@h6V_S}{09d^w?1=F!DdXx$G5cEa4(A4(H33x?iWUA z0C+`e@|qeC)5Uk&TNfv!VTMCIw>;iow6d~LcN}@Rp8#;tEVTIn4(6&(B%JqXx96nt z?HeJ2cei1-cJsZ@+78zO(H`~Mv+F#)NKSB*$&IhUj-q~T!=kt}Nek`*?`lD>Q6eNYkW%ZuBk|J_1&g^B!p+woP#l|AHbNSxbAvU5c*K$u$bfe8)l+m$zVJQ;}Af#LBFde^^SEZ)W;{C&Gp=BwP=w_m#>b$*VewX&2S%f*8$ zyO4A0VB_V=9Fa&wsUWR7Up7_-UJ9bP)a=YDD_{~5`1ux$4P^y9xV{Wuv!lwU2Nb&% zS@ghm*1^Z-BW?68m;Bv2$b5CYZKsWgXA4#uP*OHOCN!Z z>cPy6&E@5dy7m`o9b^ak{#xsbio~8C!L7WU#Fq80Tlu+2v<$m{{$XN50jUk1ZDJ~} zwmi7t`(VSxxVy1(;Xx_OFN-OrT2Gs1n|*r4qs>i+QM|odg&J#lNSyOj+yN3iQ&WQU z4=*qCG4>jc7&&XF>%{ea{lO}4ZA@SmIez}UlM`Jb0v{IiC7u}JMs~y$^Yq5Tr>dIQ zCgY}8!%L=sZ@)zc9brby2x!9V6Ffn%&C{5X*4$Y?<+GRt(pB@Z=8xX;@%Q`BMZ;%( z{W{|Yx6zXK^UdfHO2Otb|L%vF*8xfC9=Kvhp^2%@Q^2*1)$(>93@d|36a=G; zqq$623XYN=-O&t!>Et&c!qRO)^n9fPVzB2=b=CU`AV*TONs%o=abRtK47NBQ6U7#_ zS<(>TpWva1_5_i9_%=vTr*uH*{xRI=uJ)@pfKhK2wTBeD$f9#^s=nNVEf&6Jmrdag;4d4LI^7V zRxT;Ir>A`FouXC}!u7t?S!$e^R0ZwLoiE2_;oeugQJS>rQyOLtAd>aP)lvop!Qdnp+l3wdZ_JoF%rHFEp?86*kic4xy#v1$XCNdL)YEy$-K+ZB%FE*u8!_gB9uSO zD>ZyvqRV{+ZXb)yhPT@-gx=Xl&sDFht8=DHCfkvDvX2XhY5Be^**iU^bLy+p41Gii+FEf^;bEuX4H1)xnu4lzARGAp8kGy1T^Y&sR;X=C;UA9)vr;;`P zxm%0YtXDOD`a?tCqh5Ot2E$0!6|GV^9E)Xo-FqgzKg7N-fjs zD44SH&70?V^LVQlRYe1VRJlJ+0!ZXdR$mx_aA~iqVkdnEtY)y5{wy{8FKOn#`_?WQ zakUPuFRu5itTg)6WNdAaP$AXRQJjV(e|J4Jq+c3QcEdVybG1Zw&IekFh{5JIgG&A< z$#6DH6WHX%*ZfALLnYiImMjG_C-=ule0ya+bE!nvA)R||B_K)ZKT=>~PEL+78bbZs zo-BX@d5#W!W?5~Np;N2(2&?o;Zm;S6<6;0ff?P|JLk_p7EI!S`eK#)cMC7kR@s;ml zu#WKyZG6WQ>E3>k9WrWNpa@(*g)|Ap3$dvMw0fbq5+P%?v+m|mPAvgcK4{RA+#+a} zctvxIe#4il*ke|U%PRZ?`X^(ZoW9^kZ6k{Y1Q|>yG>J~I2qxuiY%78i1D_L2MNZ#y zdHyrE$V8K|Nr(s&1PczH6f??49Z0jFH|%MwVQHU*idVtaF=b4EHONnSjLCHZxF;YI_bj0rHGvdLicMN{O+R=? z8S&pTsV1^vu^oj%jY1vpW}};0kgRg16m6Y0eB~O}*Us)~=Q*!}l!d$qgA=rcE5tVX z*M3!qY^H>2eJ#x_)glz3iTQl!N9_D}9Yu~W2c0Rt%g(#krN$RQ^%6$TPENMA_^x-) z&p&yp1v345|IIh4yO9^CCfz(CWoW*(`2R!5{(9;B_YsG7ptegFMhbgmN#K7Na2kuZ JspIst-*eyR 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 BI}`u_ diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_dark.png index bf66fa5245c2dcbab50ef893fba88893693619b0..672e71649461494d5f6a553478b543bd79148ad8 100644 GIT binary patch literal 4067 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 literal 3907 zcmc&%eK?bC8^4K%R3eOghfGmRDZ)}7!qgDUXXZ^sDIcLR%Xp)FG^>QZs7PweN0EFi zJYh*Jq)EnX`549{W0Y<0z4hPw$9ufT@w~_L?w@P-b^gxtyw2 zaL6m}0hi%IJk38r9UXyVNZT>qDDT)sW>(+bbRGXd{WR5VEBTb$7^UF>Z%PT9HNXeu)N2Q!h;f6QJVU99R^yT{`U1<9~;BCbZeE0JS-v%W9 zbZowGD4GVZT^L%R(WC*UdHhL>4A_MWZ5TS8J;q=didOSz4~Y}Gxh%QPPV=ctZl~EU zu`qPq#Uh?Oz?{*DZHOuvA)+ft1DZrOd4Ad1PBhqZ=tI|;`A+5e@kot6l64K4y0sEW zqLy=SibsRphSN)t8rhnTxy{l*Mn^^&Iz7$uoT{(%I>2PR;ft$#GtH7^0af~|cbj~G zgFC9Xy^w(b?phbp#nYb%tC_!TOQ!$j7>D3amp@qczqsCE* zw*^8);!W`6|1$SWyg&NHO1v%nbR^yc?^=o3^wTeI%~*+dH9|+?P4=`F=lqD+DnXM` z+a-_Z?%s?|*p)WFC)4 zB%mj?hSR1fwXYqLo!S%jiQCR?(GQ%7VUc@G_TBmg9(+w=Ed?o|xiPH7W2e@d0n86t z-l(C?ihUBhktEbI-uGtgaz*NIfYq8MEM<8#b=`bTPR=rKXy_(hsHbbI1afjNwpY9k zK#yr8P6!-mjgnNfDovFX{HJo3ruelmm9jQT#v6)Sl2Kk!MKY!xkQCHxzFH^=MCJYC zX1{5@Le^vu-fn4W>E!Oat#P(loESgsrbq;dlo42=&Ip8!Uwx~w{#r4#MGgynVZdsb zo}Pa{T+m!7Y-dNEFRP%AkDr<0&gK@ZQQd84r{~()8TF6TTd{Bv&I2|_DC>@<+1Z)G z6%M?Mu_h#7=Gy)FvvtR08;eLJp9b9ioq>%Ss4=Aa)ah{BELiw?d9$gIefQgb{J;)T zF57?^IQtJCUHmC{jT=J*`1o#v%O-XY#m(%np9%>MHXLq@H9fP3yAk)gCsegIeE9m8 z^AOY0(&C9`na?UQv8&BRBP+1l;z~)ibH@Mk(Et)VA$f2q~^j#FtDo|;Mcl8)fzC#DC&76Xk&Cp7d_a%u*eU%i-39NL;gXTgL?~0^8=8*kaT?>QX zCusS4Cf(cLF;}~>+x_00!INhX->hD|j*K+mMV$|=$hOU)*lDy*JWRBX-Kd>fE5Gf` zzWa5`YF29Oo_FhZWo+_M?c>Be0Fph;?|0!~TO2_;CY=H)qkk79y|Xb$s#||;iqgA= zX%vX%6!)qC%*!$m!X*$ZXEw8rd}YMDW9>}^OA)IsF%5#{1^nvUUe8doD94xanM(gVhW#hD zel~>zhqH5Jc|IEQq~~ehS+D+iSnE#Psyp=)W&Zv@yl^XbBMw8Y zqeLyGJ>(zece4<*!ekJ~SsQ6EZ1AM#%pT}yeVk1>X-X7WOD<^AMaM7k3;h>e-HJe% zix?)}SHhC38*>e7>ViQgTa&mE;g+PL>|-%F8C1bb*)!MsJ%rU3f)`zmT71>NKxcQN zm!H04IV&y+!u!sP-F0TDr*`jzvp>{VuilLtTVWb zx9vIe(syRo)&$Nz0z$utp$`1t%L6F%!QK)F$h8*>p`|<-D|3(++&OM*vUdZqzqr_q zy3S41{g^FY9&xwzK&C*z_(c=)pOFb~{Zok@D=Rh2z2;y6VXhA|(1Ia)AEpPF-C?DB zKH_$P)HWFidDs1;!3hgw4I=LQWHsf_50-^=od=T|^y3c+w1CT7E~s=_>gu#Ejr;3T z?8D^E{DQ6XTR)Fe2EJbQ!6L%o3!fs|>+1S%2gCX46>XIwhxb*XufUU3RTEEpSs^|l z)3(^xYW`XnxZ$)aZgw#9EOqL*V0k7R?P8!8gdm`df(~#-hF1K@qTa714k+mo;V^X)-Y$Jxjp`P-RVAf~2nPwhXY% zVRvuLLyo-$wyrf}x+@;GDTyAM=V+@xGD?=!em^W+dajKLp+VmzEh+mnKOSPlZ57obOM8XpW@=(MAajvmiQZ3+oXCW5Oy6ZH_!HdlZR~-;l?U@v*g^N((A0M z@xqSU;OS9rb#R?XA=DI1(7{h!CTkG*$e8Qi;R5}|a~cO3@@7oueR_?`c){BUou7$i z_c3^FJU;?|@6EbLNEt}vsoGhAk?{K*I>V`9+UZAKo@gS1Z6o4Q-)PE(!bcqCwL1l5 zZ#GRhzLE9CO?Vt9R6!HKt+3-YUFLS0BoBec- zF3>pLp$@V)@+oCr@IoX474R`04aV)}el3O`)J&G$dvUSNZaaMRh^dZG-cIz+9}{`T zm7yvT%F=)JdcqdV0dv@epRk;QgNHD4L)+j|&IXl_4i7I2!F$kTQnCcV<-fTN9T%~> zZNGhs4u5Qs?C3#BY~sm0N`2sOax}=pYozoDQ`M^0{a$n7v$~ZPuxmpu{=#Ltx)wu$ z9o3DE0l!qlv(!{sJ_2}t_3dL*A5~Cg%zhv16hkgXT_E#hlzeVuK)rS~I$A7Rc4;fJ z|9Fq!Y}T(dsp#Xhdg_VdymFedn&(j{HNB=pxOF~~vrWJ9*|n9GmDfvE#2m3Wq84D^ zQ@lT2Z7$rG3kyiAam_=}0L{tXvCgV**;hWLL90AWy~_g$EkQ~VL-lGezm)N`AB}^d zY~#6pWo6~L1=4m-K^``sbTijj&+7L^6F8@iVHMpyQMFq13N$f#f|gexJ=YgMyE1XY z_)%_qk;hO22KISwgeX?4itZ{XRNMQhb7f?5e3ov_m;$7xf11yp%64mStEm|n8b~8| zbqz2WJK*a~PK75P$j!?Wm&wD?_4iIFKnNE>t(Nffr}<`Lu&r*x3)vmVQ79gkGI^=N z+|pA0%4j9e$jSmH6?(fRa?)tsL2mq!HUAI!^7jj-f6FLTr#S9M+)&i@1V4lU7e}N+ JxqZ+-{{;soqE7$- diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_light.png index 354ccd6d92a26fa21e497b8150a99a96bba1b17d..e01dc8605a80aa99e18e8d1349749bd3578d30ce 100644 GIT binary patch literal 4019 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 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_dark.png index 974868b68320953961df2304911737e40f137169..525bccd016a3095b82d5c4d9e20d7dfe34977710 100644 GIT binary patch literal 6724 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 literal 6693 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 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_light.png index 8b25be5aaa50f0aab01cad58b55411c982d66bc4..6676c7dd05bcf9a22e49f7531a5922c982bbe627 100644 GIT binary patch literal 6369 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 YK`&*hrDQ4aHwEa1k-1@=fy*!d0dH7glmGw# literal 6792 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 hywm;*n$$?)XOTI*fwUDNM<-$WSd z-{ImE-~<4G3wrl93;@_tz}Nb*qoCyYR5CaC!R7_KqXiIKg=WDohrP6*@MGX3@Yur_ z0B|0F-o6QclCn4$;Ew9~Wq4(HsG-`AP3G8-=OtmHnh|n$vWBu;po#Jxr<(8EsQL=~ zjlDld@qV9B+}S&;l%W4rUp2w^?VH`shOU-R(D5$cl$VSB9u4g@QF{9A+|$|-7bW8_ zS{`PT@jVmuba0T#)^Slg#AIQ7!DeOe+lF`ML@2*VjRs#w!TcO;w%8N15olg2ChS5N1+4RvN$~Z@g*jG{IvCj`g-L&D6($Uy z^}=rU(z{psXE>!4T;G>mQUcnxtVdh66z`-c>wD2=_z%?%+q}O!({+%U#D7f_SKK zCwv5`mHJ?o2^O>FH;Zn+pac}?=95{inA95^9aQrqh_Mu?)H=OjRpV}7Vijw<*{^&c zzE`OOwxY@5)WE7WW4L&rTR1QEK=-E-y@N*B77uhg-zFUB;&QY*5MRlUWVNY~6W6Yc zl##O1K9D|$j%>9ZEog_4bj$q=`;_TIhP*xF+}Qn?S7FYV4@jj6Us;GiQpx>fCkZ?8%Nnhj7)Gb7pCEH?C0 z#h?!|@J1aQ0MEzHz^k%+zn>q*9!*?ZbPG0z7+_uK@*(dDcK-QuBXFnQ8UYh$^_@P- zocS=rn2^nOwy((A)iJtwhqTlhp zBg=ctx~bNz`(-f(i6rWWS|^{?iAG}sHV1PA2gE8*-cQ_hOm2US;xk)yA|HDc@D@t! z0stMbry(c7*|9zhYCn4uG~7Qbx=q~~6;j(pdD(Y}!#=Q70xIza9sRwgTtFL42G8~< z2JqjE>F=W4A)bcf=Nvp_G$&AycPpG55Bnu4$*FiTNNM-TArmg4hPY|}eC(IpHnJbM z1x}YULqO4ZSy5_esRIcP!^2-ArSOJd741@vv$kT09W7F4d~WF++-^i|cMQIk}M>`Rf-Ig_0Iasdld2iPb!gy>YG4RT*p3F%E04n~ozJl_bGw zlyK>tPcb+zTRFKaOH*s9YHJ^_&StHa55#*7?6+M4J81kt^XIHzf4#8S%lz%s3T;A} zeDzvpk*6buQyFuJ%y&#;x8N`2!#>|mOSex;?qe2ebLKTS)gmnE>l=FU?@1_Qe+*jTAl-RpBOpzUNv zds&#Gngr=*ISSHPRsk=ojY}uEJ5;TDnU?#S=!@ohR%b-I;$3#&9x_KR9e1U9YEJ7| z!ZuUcS7{HF<8nTl#|XY2j*;=NRwb)tC~|7RoP6I)l1i6Ug_?_sy(oi>ueLQ=sR0{~ z)}J07Idl_zay=f%OAT1+{uCRGQuSRoVK=|n0dr1%-I-~GX)3n=e*r$olIpPo^x856z0~BR8n*FUo?O`-I#HQplW7tAkx!cnJ9gE%``Z(ftoR;KuoRNloX0^^t6G? zi3Bm;_oC#Il6#^w{B=PM{4t-4Z8xjUbsiRWUb7Vx-iSPc)A79aai<4H?r8K* zvCot6$ogk7BC0UD2T4RV16G*hO7oLyry-khZ0WbQ9@6N+ZUoe1?t&obI zZ{vn`;7&}#%j#2GI40MWEh?Vq#~1t0Z>(R*1E ztK992hdFBd5mFd>zHWvJ~EaK>qG>cWCw5w~Ko|kI^LoVc7Zgs zc>-_t`u8D9iEMQv54bLDtRIhoEUswKw`LfB*z?|%A)xKF`(L=gyzHC^I>JFHu zbbC4iGZN+7c{+Ct=HDnX@7aH`^4AbRF2e(VO@FjzBxSCSxjZ{~LT(O&+}9FR9KzAa z>QCtUlkDRQ&g0cVgJn3%=2&xZZehfSrWX5ThMBV&thv?Bo6%)ZV!LU%ShX1vQ)Mz} zdCYHk|Cb}Ten~}x*G1pG%SlH=VvN2{%U?sZHU6&Qu-+so#t7r%63enS( z^c#5Yp=yMBF!Qo`=P{Am{88GN$j~$kLi_l=9A%{n#`o5Mb5BePpKMaY{je}kMr3@W zq-kRQ6J#m+)CmJIcZ(X>hil-uGOdtg%Jkp{7rj&4%!qeU1(xs%n!Uc;snHc<;pa%( zu&D6rv51Nxz@=2yHlS5c=X?;kfezE}ZiUai5dhBCJ%2$!_6WDqZB`!Bd0gNbr3Pvd zKHyQJ+j`IO5rcKK7qAHec^+IRK-e$+{WQq`m*#@6`zDmtm0cg+KN7m*SAv!TLbM;s z)!?J#f-UM%K7x%Ui}C$xR%l&;z&vUv01PzscB1Ldu}FpD%Sm0kqrU~tZFJ*U7hc3?5zR{awj;GIZD!Po)s zbN?Gw`a4(rpNQ(umHOS0emK$d`$!!NdIYB0-rdTDOXXvA^tMGyCev!o_M_O^O#g}} zI(j9G!rXwhBT?gggU5st(Zzl=e?S@om*Stq=t}XeN(c8O0Os+f{%5+a^BI0C+ zAGw;A-nkW|2VSh*+kUZs<&yxoKvkAzncmRF@mB0p%QxPzZPepN=jGs;lPs3MdH!ri zZS5;xmtd`kUU7e7=KA`J1(Xg>OW(5AxPBQqlw>4(Eqka}{7C7I+^8f=qw8s1A;FoE zMr%?WDal_#$?ES;Bw6+JZv8arwRS&%EAX-a(4PX**q4gpfK3P=)CFE&h=ImP|Kihp zhLe!(oQeMQJTj4;GYLiSJx)K$!N;>cgM9~4U<@7ScQJ_A5*K@XwkLC_HpB+mP;aAF zoI7gCOF~F}bKR z{{dmzxpu)&5lIEr&euH;{M==lJ5nn*oM;=Viuubd;;4&G22UIHRJFbLL+bPjsY%bO zq{AT!pFr#oBRe>(u^~`*>f<4HQAK0KrbIDQGORueeeue+jCrV*Fd!#>X}EL(c|{eiZv2Y=L&)PU*xV)pM9 zRIiCa=jLV+1{p|Nn4jZT>)@P7Z#vQnebeg=JadW%5N`3XXtC>HeDMn|C9W+z9Z5jb zxBR@fzFNtuf}BC9dS=^4UefsfAoS7|3+!3yd_#;xTFr_ecLHzb+my4^dOwQ8aur80 zG1!pj#`*)bo$+PDw^VLGrrATNh0?PhyRIuM*WiP*tL8OaEHmrc#r^sx@xnQByrOBU z!zT?QUZc)CqK;4vO>?Pa zF8lc-s%c17u+AT$g>xiQO7he!e&pnrt( zw}i4mOg8KutzJd0UrJK1Vew>Zp4YIR`@I`Dm2QrGqA^NkURcXlUs+Vbu+Omn? zE*6G*Ov?!&3ZVwCh>}Y9zMtqvZbkY*wjn(J8D zI=wbK+Mq!+`54f6hlb)kcG#zRq+{iQexHI=j)j(4DsdnSUYnf)_j|6kIh|ug)Wkf4*;Z!j?*4{SD z?EmHHGxqcZc@-tX0}G1Y*DND6b5_Kufmm7Wx+6PSK2OwcKuGbY`tM9ck|9doGlptL z>>=de*`ww^ek!+=83LV}Xx;S`;LllU=fWd|l*D3E}~Emv0vmslf@6N z;j**p8qCzV0H2wlH6DSYWdhh zZ}Wn!Z&3|W9Gge@iaK-e3AxhcfiB5c=n|@tW`e~z5d4#oVAc)8*f0xGsb78oJjWn{v#h1`j*c6K>n!egk(n81;DfO7Z#`@Jtf^dcYIf zZX(?km7CInFY(JudvlR@6t+7~RO~MO#83J7ZlT_*=^;!?&I?H&`89lUZTs|IU;8Ht zLIJ{RK>WuaB>SoP)ewzr*E9xKz3qc4uU!Qn*WR4len~n8n*_JzTbxQ{7=tiq?qVgLE37;!Vwxg_!ZJHOGTC(`QbMSqy zY^tG$p_h7b4iY&pA)&Tc_@}O}>a;q$Q!FaRy{uqMu{?Ms^`eDUvwVTmDTe#!>cfK{ z#6|N+RLtIl!lpW+-d3(>!0dywwwvAL!O%pA_U%j$uH7b$2g|~$h_^yUN_-D$efW=U zVK!-Vk=h7-2!BjH|MyDH&l#L9y*W1OBu$z3KC%0k_^Wr2x-G5pc0oQI4W7>g0w>bD zMYf6p)px?u=nK2A(Y`^t7zoplH+(-qCvA@%(NvF?I}U6C4IccJYq$DWn`?;fKd1Mh zj7Ohn{i>-M)brqqknxSv)ZWk!O%Qu(l~?R8kzjp3T~j8vD`1*RFEo(eX@%NZZAa+h zzSJOl_*2>#mBovl!|;O5R`Zy(Z5OV=>;!F`rGFpRtopiH7SPFalapQhj)-2ygWZRe#+b@b~hgaPLGxmBOCD*lyMzf z&y?$&`s-x&xtjgb+;cUyh77lTcw~5%!4QN?Xe%J}|L+a1X}{3Yh$clxiGK$l1T)^^-pic57<= zCg|puJ#P5DPJOmIUoTd0E{WOTCOgn4qpNX8xT#8`0lPtUQ>Rjr6j9NOj&=K!G^@!XctB&^Kl-< z1knp*gZ4=Xmk!=6XU^8$t>fjlL^|WHbu0(oVq{t+aWk8Kr!a@LXM=-0E?n18zWmfb zu9p=DNxve6iM;ye^_SpXwfZn$sbuM#BLBPXv@pKop?us&d{(xuh+TIxdi=<2^fqZX zCV$}TixjNoB&7ydxWD7qlm)v_i_Lp4R43))xJYtV_;!7_5c@a&IXrch3I z0^J!pu2)=56E7B)p~HL~MykUnmKS>%d$CPELeb}fbnu0GZByw$Dm{2aHR*KW^rrP6qXRJ?Prc(&SHxa{!Q+6x4csG2e#%Gi`pUq2D) zg8u%6s}~HN&V3vH@E=@s*xJTn0LZ&NXns#IO7Nxg+MbnRSum22{p=`#?-AnTx-DXA zeprT6bN*q67FL1Th7c7na*%@#ZzKPpe?c|B>2tfW0sH+4>1n=u zYd6%aODb=u=fdz6R$w?nOhNtAEDCh!y~AR*f8YSxO#3~dU?#!;f9|gTIj8=QOJ!4e z9gsmi!*ie~iQ}x-B4oEE9&0^?0*OiIu)W8>Am!1EwLY$WPL3PknoNK@f(b_;HC9aF zf10WJ2RP&(NCYY6V}aAtetRHd6*%!nhJvw>sPjs$O=3!#Eywf&Y{1F;=aWkZU9Q_W z?3(*^oXX~XHZ4n+0AT}W0{;a@{=c%ISRo-p!J2tDI$ublBp;Y+JLIJ4ZY-HJV$F3) ziNLGp^ar`TKVE)hhzTz823ELMYW)9;#bFFNFh`qKsLea7QLWT%cSGK!kvzx493|F& zT^#lKG${B#fyb=>0{nAX$iFR=9B5oaC%ego|K}IVAI~$$-v3>)_g_@;#XiqRoA#nZ S@xu=R@B!7)bnc?zwB-td+9&xA%VE{p@dl&$Hh*@w(b7bhNCr z007XbsXo*P0E%4jO}Ib}*8KGC6+QSx;is>n1Rw|4@nC_9k7J-=}XRK{tk)LKqtYMP}L$EQE?yfl@%*0?CXXJ2|J zuQabqdrf=oFL{By8{&745F2A!2CyW9DWBVs^**I8OSia{Yu)2rZ)lXNB}A(NH=bfQ zZ3_-IH@E-+eX8f3qWkN%+oaEjT#M^XPO#xfTz+d<6_3Crps<*lL#6#?&q|N2o)ZEi z(ti5;LnReC9qWFaQF8OH-At-~?PwwpJ%eOa4y`mEozpCXR$(Q$V$DNIu&cVg=z!~~ zLldq>ic`juvQH=h%h%ZA2i`zoqPvs-0LHZdi8=4rmrb55a3!AnsY?AC^dG=lCJw|I2vj~CMn3`v13dK;uIE)@ z2zTHa%xeK6m^BdBN95ko=7wKh@7Cc7Xyxv-`c{TYYJl)Ue(Fp2o!>~xHRXw@$xQ3B z``3%?+N#8GyC7oTVN*=xIgXD7J|vIKI^ycTj($T64Eg!)HJ|bqVB^x%ICkEOwC9tr zeo^;loz<5KNkf$V-XFe)u*UR>wNK+601xcveX|c8@j1bf64g`TUoRI7LE3hp+G3P9 zZ4tvZ8g#%=Mx|%fuk676QS>?3&T7Ty9%o9N7sr`jk#Pdh{Tt^~o^mZFufaRCxfmJ7 zA!e^6G9dN+N$0)L&CF!Com(tgwLyR!!KTr_g6$qtk+D+*s~-J>s>URG;(M01p;@T^ zPg7_IQ{%F%-#J#7v#d7>m!gpvZ}0av-M7@6KVH_6ErP@0p!Yy1y}2s@aD(gq?gD7= z<`dAz7gweJc-89#+(NE=M02YU{!(9GU!K(u0O5v){uo{v07AL`ypiXz1#xzhJ?VTh ztyJK0!VSt8m1UP)uB!N7 zp`v|~^Zu$X%FLxt>N0tUQB3({Xdl4aqck6It6*4QC?{v7A~!eBZ3*a(m$PV)USgA} zX&v=Ua&#>Xu1UR9x)@h^TQCYsCD zCF-#9jxl*2digg!8iNQE(~V=_OA)<-Y(eyPODtJxft>A8z49>}_W;++2AZ1G9_H}zRQpAaP?%N0OcM!qvV_pYt zH*S@_P$)cLkI)>gD$v8kkIgmcJm`_hppAf0T9X3XWA9!GYB{={O)-%?iau!ZaFW^% zw#aUi=Sf%NF%VE2>FrHW?|i+}l-t{I&xkU5hCgp}beOaSF%c1{UlqiC%P=xa2vg_X zuc+0}z};9b9jSm^S5B^MwiEF6=ro9t_WiDC*+_hIyu}LLDgiIkddYZdwxv&cx5=c) zmSk1T8GDA*h-@`1-(l~o6_=JQZI}tjdeq%Dmer56{B=R_RsSrZA!+{%c--J)sl!c4 zBXR4Lg3g}d6P-thkkLI)%~TOnB*MZ&F#ww>t79ajyJAw&vcGyJt8&6{O4m~>Ugxi! z>L%1IIbfNjI#XkG;J%>{d^Xw0H78pTwif<@J8rqzDs0wING!S2Ryz2w+P3E9`XiGon$1K@J}(@Q-iu_}+mYn@VVXTK=r*haN|{Pe~o@AZVYMX{?#)jCRxrYs4k9r*56};&z+GC16)Cc(SGs;-G^# zRAY4^iH4p(uV-Z_m0S8`6+x`N{0{l88L1Al=-Yj`oM17SE_sBEYU!3J#*3haYiibN znt~VJi_|pff$ZhRBFbMd*mn?-l$<0HW&*7Igv7y31{!2_1SO`2n8yQC+#VTpsFmuo za{i`wB^ES}`MxHqr3L4V1#6ljZ76_s?M(Kvy*2bIU1Wj^U9y{ho1?hI-uLg-H(Y#d z7SK+TUQATKGqXUdBCoKrx_%o1hAxAfQBY!NM;4~8Z9`e`p_95>LfZOH4s9}5qFP!) z=hsYYa|=_`yblMj?ui40r#F9Q^jj1eylkXF`=Ot*W@a&G*uwjZt&a$&d5y1#l-uwR z;Ei?R2W4&kDbGmrel$nF*z~CkA@GHpvB4H$lF6~(!leu20$jyZFfnOpNC&R#IT(at zaP~~inY6GUL(pOfv-GttBmRLNv}{vNBk^GY)T2S= zo8t)<8b_;X?@w(oJBc~j_li%F-G@-qJ(X>$t`a7s7%tZ=E_oK z@Q}8?R^T;taMx8*>f-Kh!fVx-2M=mDy2`xSRlr|hIq~Afes)$MRK3Y?j6g7zI~v)- zPp|uVJ+j-->`drHS!6?I(1r~#EN{WEpTc3p##B%hJ$vNYWOlE4*F9{PoX>~GBwX0H zurs4OkO72+>(+pQfw?Qj)d=F`gbH%kr0MFG2-&uMP$lF2y-;>=bp7*-3XJQWIO^zp zgUSq)6iD9~1uTKB%Gujq3IDN>F-0h?^62Xe$8S+3O-H+CR=JtN_&xj`Gx##3o5%KU zQkdQ8+srR)4FlmCiCHN9PhQ6WdbCWZAzVRIL*L+4K&AtJB`-*jGsP>|?UkDa7IV7o z<8b>oXrDu#OjzKkoRX+0P<^=(iSSNmSgQnqK;ruLWJ6|G#ZF_)v`}VRij|=xlPS4@ zr=>B)s8>PBT+$`MvXP{3d7ZX;Fk8J$4|*sh?B%*h&^D1({@DFLCs0ntXP)cHvbO0rDbEG?@cn65ifrM{O@WtfHx#msX6m4*t^n`Dm%QQTETU05 zEY@NFUrQYDzicZpxsCA7^T7>9L7oxQ1ebSWyXAepf;usJ<|?y}v%kMmQ2T}+o#Va` z!D5+3v`>JA(Xfx!F8TT#q*D-KVKS`i*#4D<>&qAnXY@wcWo)i&GF)x%WmsS1#|0IM zkUi!8&-n&03)iWz`C4aS#TUH@GR-Q-*5Pygm=ngPWLk|n*7_3%o;21^o1?nEn)p!7 zo_C|scgl+n%a3g-LkBGB*^BcPocm@-2UOSiH|wYzv|B5}%0mNno1U5O32`4G^<(S= zS!j2N8SZy0LwWRP&^NHgGc`;)46C0yXaW{?{8roDG}~UKZj=~R%}Q?$a5Laxs|`?d zEBC$==cAvyYlT6+!+QkHz=msX?K#xBK^`{tI@aAKc@&crfOp3h*wIh(idrue%8O28 zd?|axzSy_q+fSu!@I%b?XKEZm@+*uBKlw2>qpyR8Q33Pwq%@v>;XKGpjr|c@3LED= zVeH=Iu9aDck1+FS$A>tk#7@T8qS=?P4B#e)@cL$&m#Q~1RCy(2Z@*5J3(M%S7nisP zSMQv52nMRtoAS$`N>v{AF64w_s4HV9?FSM)8D!T~|7NxQJWDe;)%mvf%^7-vwAg)tfSL z@x4q<`FtL}TK9`VE+u46u8fcGja$6+UdSAuE;mNtQ5RV<264+LZJ?COkrM{i1^*@s zq(NC=Y)bBC=$!`70Cf#GFHjIj5Suj&3@YM^z#62r2>>*5Xe5sw?^)W!6znG@gDS#+ zfq_9IjhThnGt6<R2r#6Kz*}OvXLt!O1r)6*0#QaA=0JsbPdqL2$@3zRy zdIkHYbhZN}^f{+#xPWjlOmNPW5mJb74XjLd0LK&JyK8PPHB$_Bu z;$;|{&`RAS>H(%Ufx0MSnxo^uiltYW<_F5lX1$hQ=21Rq7<97s{pmH#jz;r8XZ&{? z&lC%xN{Ur^q-2XeBi=elK)3!(fMJlkGP3w^=%rHFUZ6y(olrif{`BC=`_FzkQagXS z1iz-7U;J_YrII;faT;Sj`H@sF`dPM2Nq!E!dX3iqoYoHOMPcr3i(H~X5PXWIrAd7o@9{v^Q~q4Qbo1pigEd2N+ zWu&+{M01^_C@0qUD2c604&jtfvh26GSLF+DmC@1ifEyuAw3G z)h~fub3Hq31od3+axF-|EqKmrEG)nZ56BhMOAjK1*t=8Lj(p{G@*6^(q6>`;Dvb?v z5mpMu#fzHG(o$wEA-Kb$2MOJaSg%=AVP+#iW`_y%*X>4qa0A80ElVZ$!qRy8_>4T} zzvWTU+!veJoL_$^G9y-`4_}#{sGF3Lt^l7B^+EprGd_BZE}N@Hmf3k8Qa8%9^IRQV zfFYyRz0k6(As>;vh3S=J%5i-G@cgB$SE652ex2blCE)G^1`QhXBxhL|f#|!a$iX#9 zA3K+%*^|ag++JG*eZbv_v0RpvQBgM-5X$3Rtlsp-LKOS`z`(Kv7Pvk-XShCOmuE#C z%}h0S=2T&Q8VJS~B+abMM#h%xAK10{YV;>LF-@JRmSs^CD(_!8<2Y#6w6^{bl#B13 zr&@L}5|x_(<0#I05wT~Z9dMC(A_7><{D-0A7;1@Yc^52R;{MY#Z zyp^|1YjjesY)I{>1^_H-=Sjo(6Qo;TpsQ~LEX%B6qUHf_nZIcOk#h|&B>i_9;M3n} zfUYk}U}TSGBDol3Df|N!3F0P=;R`46olTmI4Gp)=iP7fc$$OZA){?JdKQhtY!`!`x zkd7oa3ip{Ec$MiCcsgr=ah*_2;e1``sjAd&c{n%MN&WF{7t-M~9JJN0fcm5^N4`ac z`yk@}Ev(+A%-qQO-L{hVBX7x6@0Ty-L!QwrVN(z%Gyw=$e5YM z&{DuT#6BefT0z`ZF#N`G;6lX7!${px`eJ7TYW<||%H)_pWfD0oSk0jVZ;MQd`c}s( z8?3tAnQI%Vd27yK8IvXMjhljMe>A!Pv*#^dRaabCPGpq{tlA_lRaFpW$_!t%zQymG z)uBbC;^n%>f(T9-lLzuJkh0SZ8woFrMdga8kGv56d$0{@M&L0A-oM~c)ajP<%0L+7 z=YIZdRe^6I37z3a;VKiFW_!f6v~2m#aGe@Wvl^LwxG|hRv&Z?6?<}*z`iycplVz&5 zEi=Zh#V1M5Uq6hC_(r&|3GYRD5Uxpn4;Qz?gmg$UT2Z*WOc=LH&P%{|X5^ZHA66#d zJ1$bKCs?y@`E^=EOhTvajvNGKuOE?J@5nodsI7l<8kXF1AlqqotMj(YvQ>NedYl6C zYl^k;c2m3IFYaef0U8}@>#YzK`BR6^xXtDbsXkxvP~z^Y%<*UrvCGLYH=+po;Rj&$ z{hll|QRsNIAOZrO=}FtxnPFXS8s0f=sH6>;`1T=IGO0glpFK1ynfMjra4)hh?nmIw zhXBh;;m;^p9h(p}B+jERXSM=AzkV{*uIK*v^}=>girU;^_ek;9t04}CGlV0Eayp_|k~VR@NgfV(tiy{Ltqj3Sg~v zDYPcjX?w~)u-GxC4%gbwYns$bSh2z@5Nk8yH3svum5)G0_m9p+M14BiD}m0zCOT$Rc5 z2+21yfm{jH^Cq4?NGpjtiN{pdS_cnS+R@W#oVj?gZ4gZH1>yMq@#kO&8BP1-zE#tW zmS-ZjruGb55AA;RkpAGZTDuaen|Zl!Ri{miqut;b$CX-9L}(v)b4q$wNa$?mqbr%6 zesuA@ISv5aQ_N7WC)w(naog5<`K*`0aVJ~{_jLbhffxTBpOl2%sXSMV+M*+ah`DDAl_b)j!(ptp0vX&t=35O{+^Y zkmWSEo~kQ+S8Oi8e>tT<_gcf)Uzz&bATj^-_kIK9)~WNJW~o(HI3#ojin;J?Z_k?R znNjQZ`z^^S+d&MS2woqM`@yGbAxXC@VVv< zqO2|JJI{K{l$U4^bGT*!HSgw^6%yB96zWyNxPndc*IbX`e9%`-C7pK$T^FW>KvGVU zjjqJcn`mo#ot=nz;=f3yf%{CcDsnqgd3a-vy@R5f%>&|%^!eLa+YM6vBPz!gmGi_b zz&r(&T^hr!mi>TXZ9qq1;`<>#?cOTOme&fIV?jq|I`F(AGa}Ma+cKf2)+f!23kH)X zzt1%;Z&P6(>Xi%WoP}vA9Eq_-%65PUMKe=YU|n_Z*rP3Fe8EimLzABE;H^C^V!i&! zT+}Y*xTpeRx=CS~!X2pY^DsZB+fpta0C;CyPkfFK{5N!4-MQi2q*@cVyrXA_?#wNK(RmGsC!7KZW%y^Qg@2H3 z_}5h}1cp+~^d1nwBl&0)~Cpa-jefRdPVEH)S4ZbZu#elkpI-Rj>VrObr<)) z0@anmYI zXX-znce}u;6J0viC?^*!Qv0t(BMCEp2LON`@_zyTC=CA#fx|z#h^GoJ+zqM=JLqF@ PQh=JW_Cuu7<0tBS(u#8AY7f`GIj(glPN2!`Gx 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 OK>N17I!?_l;=ceXV&gji literal 8513 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 CCe2O& diff --git a/packages/stream_chat_flutter/test/src/scroll_view/draft_scroll_view/goldens/ci/stream_draft_list_tile_dark.png b/packages/stream_chat_flutter/test/src/scroll_view/draft_scroll_view/goldens/ci/stream_draft_list_tile_dark.png index eb47dc88e30ad8664e2a15da55596a46081a7c62..e96b66cffd0f134308339d4f4b9eedf2ccaf0b01 100644 GIT binary patch literal 1364 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 N;OXk;vd$@?2>?G5PecF! diff --git a/packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_dark.png b/packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_dark.png index c82908a3d8eff36568f536f6e6624ee0ac09edbb..7e8ce51ceec3ebf7e905380c90ebe47a8da11a57 100644 GIT binary patch literal 3856 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 diff --git a/packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_light.png b/packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_light.png index 153e5cf18fc5dd1b76fe1aa27ffa3d8627152630..ae1bb58c7c4fde69bfcb5f7bfdead2539beffa64 100644 GIT binary patch literal 3983 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 M&@s7A)^@u8A8kQB`~Uy| literal 4073 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 literal 2278 zcmcIl`#;ldAHRmOs2eMhbF-9&mqQ{`7L%=6G>3{16`4>(&Zax$keNbZlbF*Uqq(`| zlyZ8CxRpcHl$;4U7sm6Q`)_!zAHLt~{rOy}6EldHYLtzpEBL1cXTR3#W;MX1i08b|1PTK}$&F~y8AA2aZ&MP}u zh&FjXMXDXSq0M4a{$je_y3W%oq6f;eM$c;Pc1{%!=nL3OQt;_*oGm8xHoNy=9)6~< zOIoJ#nfQ!!veabbS>(x(Yax8mj|J0>hltCwQNm}#XDXhw-{||KhzS%yoD>0x z$M^Ch>guoL==y%`r45xu{Fut34_i@c>39i%0>^UkV1ax$}<}QpK zNrJ;*R9Qb=WPe+_*G5wu#MKaR$82$G-Mtjb=_oIxDHf>wp%91nC}3~j&z*6^!Qr5( z>qfjl+E89o>Yxfp2Dt~3A|e2R>Q@y=M5UbAh8mXyuwh4vjsRXp_6u}0n5U?3L$yoW zFgj&h_VT+KfvRtAJ_5f$y1$pe5DI2+<~|i*Q*LeBMM)W$k4U$nV{fhexD-C$tj?KdipKe!i#>Xrl2RWcl3eE*fw!lhRp2*b|8f?ww3l zW##dYjR1V_jHCVHgidSn{pPY`!cVmQ^G6<67i$bu;yw+=9Xp2O#o>5S_ZwYDM=Wh< z(f42gflkBF3o*%FeH?@Yz>|eBbZO_(VTcBM88rWVQd9&~wOUy*Cl(8&o}Ti_np|!) zM^UgoU#eUq8~~M#TU%QScFeSAZe@A6h=O>MjZ~bRWa-^| zj1#-yV0YsUtWXp+aQ2JmQNu1nDJiJ9ce$b9!t>f8wFd%K-PS0zfci^TL4rW>_U;*N zORor+wkI)+dRBg`hKCz@4nGWlLov3&rV5sUR!IdXdGl+S66pbQ?rLfOh4A~X4X}kyb z1exif##o2yJ4JzWgWl`6OK?!7Q;C+D$4PyqE`5*HZJ0Iu<_CDPw|B`|BJmJGT3Y&D zM@J?9m-}{G9XjqkkhifB=H1U7Wv$1o{ece%s7O*a(W15Ha=E$|?y?H>-~$I#m55N& z9TF20LlLsWSDp^($4V%tp-P6H;oSgfIT`_qRyg?%2Z8(sb15__(~Yo>#91 zfox`GX6Y{XZ?AuU6D^*S_fXzI&e?`cMiPu7H^bV;}K@YT58BG9we)nIVsHlm##Wc=K80cyu6*QZC-VCwa4o6 z>MEPdU0@~Wu~?Jy!>vi3ef|B*AG~u~&NyxGd@HtU<^;3koi&U=BH58h563zfYz{}u z&d$zrYm*=H^V{q4@sBx3gt*xb+@FHHs+^9gF|O$x|M=o+>tF8gGhF*xRFRE4a8{~s zLZKn0J9O(}b8~Zs&efPo->;mhDT+Cgj-xFrMEYo9BmsV3xryXxT6)>eGGQ1Mg(wY@ zmC{!kZl%#WQGhDdtfzE_x$Y7dh_$y*yZ8Fp=t1XN5gpKw5j1Pe<#L}Z?Omi+U1#qA z+8uc8^ZNVxP_PQdU;wpCwUd8dm~3l1(rpZ=sQJOrIg68OQ>{UbLuG#c{@py@%*agu z(ieh^LzW87m1rJK!_Q~2VW+ZtOI_v!EEzN!oggQ1pg#&v_V+Iz4AXOQa#D>f5&_9y z)GVJotFGQUqNk@f^&+Mo|0Fe)wXooK*j*S@eQH&{AR8Z>IEzK8BjP3)cOzJt2EGFf z3GmI7n5NNX@b$9x#$r{BFcOL|$>HUK4244B>ZyW;>kA7Dcb2F0fAb?6y)2!?(HM-Q zOGL24BQ+9NR~a-!Z$!N6$ol=x*7(|}Tm0hK`;QFF-HMz2y5&R|&?=|&9PQ~Hv~_l7 zPFAFGS~BVM9N$-UdBw$M8OFifR2u*gki#~j5}PEK$Z-1uR*}PBG;HRgcC$)KNTDk~ zx(c$D$f2P%3>z45Ylk|yHY~T&`*Z%%(jCWfu43}*4hE*crr_LE2ct$T+F_qqbaz+R zQ1>JZs0GzILr(wZmwG|V#-S#V5ucEth Date: Tue, 10 Jun 2025 05:34:13 +0200 Subject: [PATCH 03/34] refactor!(ui): add support for customising reaction picker (#2248) Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com> --- packages/stream_chat_flutter/CHANGELOG.md | 6 + .../src/platform_widget_builder.dart | 14 +- .../message_action/message_action_type.dart | 10 +- .../message_list_view/message_list_view.dart | 58 +-- .../message_modal/message_actions_modal.dart | 15 +- .../lib/src/message_modal/message_modal.dart | 2 +- .../message_reactions_modal.dart | 23 +- .../src/message_widget/message_widget.dart | 341 +++++++++--------- .../message_widget_content.dart | 32 +- .../message_widget_content_components.dart | 2 - .../reactions/reaction_indicator.dart | 73 ---- .../reactions/reactions_card.dart | 142 -------- .../lib/src/misc/reaction_icon.dart | 137 ++++++- .../reactions/desktop_reactions_builder.dart | 7 +- .../picker}/reaction_picker.dart | 27 +- .../picker}/reaction_picker_icon_list.dart | 119 ++++-- .../reactions/reaction_bubble.dart | 87 ++--- .../lib/src/reactions/reaction_indicator.dart | 73 ++++ .../reactions/reactions_align.dart | 0 .../lib/src/reactions/user_reactions.dart | 146 ++++++++ .../lib/src/stream_chat_configuration.dart | 89 +---- .../lib/stream_chat_flutter.dart | 6 +- .../platform_widget_builder_test.dart | 25 ++ .../stream_message_reactions_modal_dark.png | Bin 12166 -> 12163 bytes .../stream_message_reactions_modal_light.png | Bin 13555 -> 12993 bytes ..._message_reactions_modal_reversed_dark.png | Bin 11876 -> 12111 bytes ...message_reactions_modal_reversed_light.png | Bin 13404 -> 13017 bytes .../message_reactions_modal_test.dart | 5 +- .../ci/reaction_icon_button_selected_dark.png | Bin 670 -> 0 bytes .../reaction_icon_button_selected_light.png | Bin 646 -> 0 bytes .../reaction_icon_button_unselected_dark.png | Bin 615 -> 0 bytes .../reaction_icon_button_unselected_light.png | Bin 620 -> 0 bytes .../ci/reaction_picker_icon_list_dark.png | Bin 2741 -> 0 bytes .../ci/reaction_picker_icon_list_light.png | Bin 2918 -> 0 bytes ...eaction_picker_icon_list_selected_dark.png | Bin 2843 -> 0 bytes ...action_picker_icon_list_selected_light.png | Bin 2971 -> 0 bytes .../ci/stream_reaction_picker_dark.png | Bin 3460 -> 0 bytes .../ci/stream_reaction_picker_light.png | Bin 2918 -> 0 bytes .../stream_reaction_picker_selected_dark.png | Bin 3536 -> 0 bytes .../stream_reaction_picker_selected_light.png | Bin 2971 -> 0 bytes .../src/misc/goldens/ci/reaction_bubble_2.png | Bin 2678 -> 3206 bytes .../goldens/ci/reaction_bubble_3_dark.png | Bin 2178 -> 2626 bytes .../goldens/ci/reaction_bubble_3_light.png | Bin 1982 -> 2400 bytes .../goldens/ci/reaction_bubble_like_dark.png | Bin 1696 -> 2051 bytes .../goldens/ci/reaction_bubble_like_light.png | Bin 1474 -> 1800 bytes .../ci/reaction_icon_button_selected_dark.png | Bin 0 -> 649 bytes .../reaction_icon_button_selected_light.png | Bin 0 -> 613 bytes .../reaction_icon_button_unselected_dark.png | Bin 0 -> 564 bytes .../reaction_icon_button_unselected_light.png | Bin 0 -> 621 bytes .../ci/reaction_picker_icon_list_dark.png | Bin 0 -> 2324 bytes .../ci/reaction_picker_icon_list_light.png | Bin 0 -> 2580 bytes ...eaction_picker_icon_list_selected_dark.png | Bin 0 -> 2495 bytes ...action_picker_icon_list_selected_light.png | Bin 0 -> 2645 bytes .../ci/stream_reaction_picker_dark.png | Bin 0 -> 3635 bytes .../ci/stream_reaction_picker_light.png | Bin 0 -> 3817 bytes .../stream_reaction_picker_selected_dark.png | Bin 0 -> 3701 bytes .../stream_reaction_picker_selected_light.png | Bin 0 -> 3861 bytes .../reaction_picker_icon_list_test.dart | 37 +- .../reactions/reaction_picker_test.dart | 3 +- sample_app/lib/app.dart | 4 +- 60 files changed, 842 insertions(+), 641 deletions(-) delete mode 100644 packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_indicator.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_card.dart rename packages/stream_chat_flutter/lib/src/{message_widget => }/reactions/desktop_reactions_builder.dart (96%) rename packages/stream_chat_flutter/lib/src/{message_widget/reactions => reactions/picker}/reaction_picker.dart (83%) rename packages/stream_chat_flutter/lib/src/{message_widget/reactions => reactions/picker}/reaction_picker_icon_list.dart (61%) rename packages/stream_chat_flutter/lib/src/{message_widget => }/reactions/reaction_bubble.dart (76%) create mode 100644 packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart rename packages/stream_chat_flutter/lib/src/{message_widget => }/reactions/reactions_align.dart (100%) create mode 100644 packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_dark.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_dark.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_light.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_dark.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_light.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_dark.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_dark.png delete mode 100644 packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_light.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_unselected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_unselected_light.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_dark.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_light.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_selected_light.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_dark.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_light.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_dark.png create mode 100644 packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_light.png rename packages/stream_chat_flutter/test/src/{message_widget => }/reactions/reaction_picker_icon_list_test.dart (92%) rename packages/stream_chat_flutter/test/src/{message_widget => }/reactions/reaction_picker_test.dart (97%) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index c4b7b47881..c9d4190064 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -43,6 +43,12 @@ For more details, please refer to the [migration guide](Unpublished). - Updated `share_plus` dependency to `^11.0.0`. - Updated `desktop_drop` dependency to `">=0.5.0 <0.7.0"`. +✅ Added + +- Added `desktopOrWeb` parameter to `PlatformWidgetBuilder` to allow specifying a single builder for both desktop and web platforms. +- Added `reactionPickerBuilder` to `StreamMessageActionsModal`, `StreamMessageReactionsModal`, and `StreamMessageWidget` to enable custom reaction picker widgets. +- Added `StreamReactionIcon.defaultReactions` providing a predefined list of common reaction icons. + ## 9.9.0 ✅ Added diff --git a/packages/stream_chat_flutter/lib/platform_widget_builder/src/platform_widget_builder.dart b/packages/stream_chat_flutter/lib/platform_widget_builder/src/platform_widget_builder.dart index 13b0a13cda..b3950d2f0c 100644 --- a/packages/stream_chat_flutter/lib/platform_widget_builder/src/platform_widget_builder.dart +++ b/packages/stream_chat_flutter/lib/platform_widget_builder/src/platform_widget_builder.dart @@ -25,6 +25,7 @@ class PlatformWidgetBuilder extends StatelessWidget { this.mobile, this.desktop, this.web, + this.desktopOrWeb, }); /// The child widget. @@ -39,12 +40,21 @@ class PlatformWidgetBuilder extends StatelessWidget { /// The widget to build for web platforms. final PlatformTargetBuilder? web; + /// The widget to build for desktop or web platforms. + /// + /// Note: The widget will prefer the [desktop] or [web] widget if a + /// combination of desktop/web and desktopOrWeb is provided. + final PlatformTargetBuilder? desktopOrWeb; + @override Widget build(BuildContext context) { + final webWidget = web ?? desktopOrWeb; + final desktopWidget = desktop ?? desktopOrWeb; + return PlatformWidget( - desktop: (context) => desktop?.call(context, child), + desktop: (context) => desktopWidget?.call(context, child), mobile: (context) => mobile?.call(context, child), - web: (context) => web?.call(context, child), + web: (context) => webWidget?.call(context, child), ); } } diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart b/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart index e92ed7da6b..4f4ceb4cef 100644 --- a/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart +++ b/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart @@ -72,7 +72,10 @@ final class MarkUnread extends MessageAction { /// Action to mute a user to prevent notifications from their messages final class MuteUser extends MessageAction { /// Create a new mute user action - const MuteUser({required super.message, required this.user}); + const MuteUser({ + required super.message, + required this.user, + }); /// The user to be muted. final User user; @@ -81,7 +84,10 @@ final class MuteUser extends MessageAction { /// Action to unmute a user to receive notifications from their messages final class UnmuteUser extends MessageAction { /// Create a new unmute user action - const UnmuteUser({required super.message, required this.user}); + const UnmuteUser({ + required super.message, + required this.user, + }); /// The user to be unmuted. final User user; diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart index 5ed61a4f61..1c49dfe4b7 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart @@ -1474,31 +1474,41 @@ class _StreamMessageListViewState extends State { } void _getOnThreadTap() { - if (widget.onThreadTap != null) { - _onThreadTap = (Message message) { - final threadBuilder = widget.threadBuilder; - widget.onThreadTap!( - message, - threadBuilder != null ? threadBuilder(context, message) : null, - ); - }; - } else if (widget.threadBuilder != null) { - _onThreadTap = (Message message) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => BetterStreamBuilder( - stream: streamChannel!.channel.state!.messagesStream.map( - (messages) => messages.firstWhere((m) => m.id == message.id), - ), - initialData: message, - builder: (_, data) => StreamChannel( - channel: streamChannel!.channel, - child: widget.threadBuilder!(context, data), + _onThreadTap = switch ((widget.onThreadTap, widget.threadBuilder)) { + // Case 1: widget.onThreadTap is provided. + // The created callback will use widget.onThreadTap, passing the result + // of widget.threadBuilder (if provided) as the second argument. + (final onThreadTap?, final threadBuilder) => (Message message) { + onThreadTap( + message, + threadBuilder?.call(context, message), + ); + }, + // Case 2: widget.onThreadTap is null, but widget.threadBuilder is provided. + // The created callback will perform the default navigation action, + // using widget.threadBuilder to build the thread page. + (null, final threadBuilder?) => (Message message) { + final threadPage = StreamChatConfiguration( + // This is needed to provide the nearest reaction icons to the + // StreamMessageReactionsModal. + data: StreamChatConfiguration.of(context), + child: StreamChannel( + channel: streamChannel!.channel, + child: BetterStreamBuilder( + initialData: message, + stream: streamChannel!.channel.state?.messagesStream.map( + (it) => it.firstWhere((m) => m.id == message.id), + ), + builder: (_, data) => threadBuilder(context, data), ), ), - ), - ); - }; - } + ); + + Navigator.of(context).push( + MaterialPageRoute(builder: (_) => threadPage), + ); + }, + _ => null, + }; } } diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart index 5b45f9360f..5168626eda 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_align.dart'; +import 'package:stream_chat_flutter/src/reactions/reactions_align.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -21,6 +21,7 @@ class StreamMessageActionsModal extends StatelessWidget { required this.messageWidget, this.reverse = false, this.showReactionPicker = false, + this.reactionPickerBuilder = StreamReactionPicker.builder, this.onActionTap, }); @@ -58,6 +59,9 @@ class StreamMessageActionsModal extends StatelessWidget { /// Defaults to `false`. final bool showReactionPicker; + /// {@macro reactionPickerBuilder} + final ReactionPickerBuilder reactionPickerBuilder; + /// Callback triggered when a message action is tapped. /// /// Provides the tapped [MessageAction] object to the callback. @@ -91,16 +95,9 @@ class StreamMessageActionsModal extends StatelessWidget { }, }; - final config = StreamChatConfiguration.of(context); - final reactionIcons = config.reactionIcons; - return Align( alignment: alignment, - child: StreamReactionPicker( - message: message, - reactionIcons: reactionIcons, - onReactionPicked: onReactionPicked, - ), + child: reactionPickerBuilder(context, message, onReactionPicked), ); }, ), diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart index 377d162857..86bc303f77 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart @@ -141,7 +141,7 @@ class StreamMessageModal extends StatelessWidget { crossAxisAlignment: alignment.toColumnCrossAxisAlignment(), children: [ if (headerBuilder case final builder?) builder(context), - contentBuilder(context), + Flexible(child: contentBuilder(context)), ], ), ), diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart index ef230bc596..70278f3dcb 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_align.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_card.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; +import 'package:stream_chat_flutter/src/reactions/reactions_align.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamMessageReactionsModal} @@ -24,6 +23,7 @@ class StreamMessageReactionsModal extends StatelessWidget { required this.messageWidget, this.reverse = false, this.showReactionPicker = true, + this.reactionPickerBuilder = StreamReactionPicker.builder, this.onReactionPicked, this.onUserAvatarTap, }); @@ -49,6 +49,9 @@ class StreamMessageReactionsModal extends StatelessWidget { /// When `false`, the reaction picker is hidden. final bool showReactionPicker; + /// {@macro reactionPickerBuilder} + final ReactionPickerBuilder reactionPickerBuilder; + /// Callback triggered when a user adds or toggles a reaction. /// /// Provides the selected [Reaction] object to the callback. @@ -87,16 +90,9 @@ class StreamMessageReactionsModal extends StatelessWidget { }, }; - final config = StreamChatConfiguration.of(context); - final reactionIcons = config.reactionIcons; - return Align( alignment: alignment, - child: StreamReactionPicker( - message: message, - reactionIcons: reactionIcons, - onReactionPicked: onReactionPicked, - ), + child: reactionPickerBuilder(context, message, onReactionPicked), ); }, ), @@ -121,19 +117,14 @@ class StreamMessageReactionsModal extends StatelessWidget { ); }, contentBuilder: (context) { - final currentUser = StreamChat.of(context).currentUser; - if (currentUser == null) return const Empty(); - final reactions = message.latestReactions; final hasReactions = reactions != null && reactions.isNotEmpty; if (!hasReactions) return const Empty(); return FractionallySizedBox( widthFactor: 0.78, - child: ReactionsCard( + child: StreamUserReactions( message: message, - currentUser: currentUser, - messageTheme: messageTheme, onUserAvatarTap: onUserAvatarTap, ), ); diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index 87cba1c2e0..7cc3320187 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -4,7 +4,6 @@ import 'package:contextmenu/contextmenu.dart'; import 'package:flutter/material.dart' hide ButtonStyle; import 'package:flutter/services.dart'; import 'package:flutter_portal/flutter_portal.dart'; -import 'package:stream_chat_flutter/conditional_parent_builder/conditional_parent_builder.dart'; import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart'; import 'package:stream_chat_flutter/src/message_widget/message_widget_content.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -100,6 +99,7 @@ class StreamMessageWidget extends StatefulWidget { this.imageAttachmentThumbnailResizeType = 'clip', this.imageAttachmentThumbnailCropType = 'center', this.attachmentActionsModalBuilder, + this.reactionPickerBuilder = StreamReactionPicker.builder, }); /// {@template onMentionTap} @@ -384,6 +384,9 @@ class StreamMessageWidget extends StatefulWidget { /// {@macro attachmentActionsBuilder} final AttachmentActionsBuilder? attachmentActionsModalBuilder; + /// {@macro reactionPickerBuilder} + final ReactionPickerBuilder reactionPickerBuilder; + /// Size of the image attachment thumbnail. final Size imageAttachmentThumbnailSize; @@ -466,6 +469,7 @@ class StreamMessageWidget extends StatefulWidget { String? imageAttachmentThumbnailResizeType, String? imageAttachmentThumbnailCropType, AttachmentActionsBuilder? attachmentActionsModalBuilder, + ReactionPickerBuilder? reactionPickerBuilder, }) { return StreamMessageWidget( key: key ?? this.key, @@ -539,6 +543,8 @@ class StreamMessageWidget extends StatefulWidget { this.imageAttachmentThumbnailCropType, attachmentActionsModalBuilder: attachmentActionsModalBuilder ?? this.attachmentActionsModalBuilder, + reactionPickerBuilder: + reactionPickerBuilder ?? this.reactionPickerBuilder, ); } @@ -659,118 +665,115 @@ class _StreamMessageWidgetState extends State final bottomRowPadding = widget.showUserAvatar != DisplayWidget.gone ? avatarWidth + 8.5 : 0.5; - return ConditionalParentBuilder( - builder: (context, child) { - final message = widget.message; - - // If the message is deleted or not yet sent, we don't want to show any - // context menu actions. - if (message.state.isDeleted || message.state.isOutgoing) return child; - - return ContextMenuArea( - verticalPadding: 0, - builder: (_) => _buildDesktopOrWebActions(context, message), - child: child, - ); - }, + return Portal( child: Material( color: switch (isPinned && widget.showPinHighlight) { true => theme.colorTheme.highlight, false => Colors.transparent, }, - child: Portal( - child: PlatformWidgetBuilder( - mobile: (context, child) { - final message = widget.message; - return InkWell( - onTap: switch (widget.onMessageTap) { - final onTap? => () => onTap(message), - _ => null, - }, - onLongPress: switch (widget.onMessageLongPress) { - final onLongPress? => () => onLongPress(message), - // If the message is not yet sent or deleted, we don't want - // to handle long press events by default. - _ when message.state.isDeleted => null, - _ when message.state.isOutgoing => null, - _ => () => _onMessageLongPressed(context, message), - }, - child: child, - ); - }, - desktop: (_, child) => MouseRegion(child: child), - web: (_, child) => MouseRegion(child: child), - child: Padding( - padding: widget.padding ?? const EdgeInsets.all(8), - child: FractionallySizedBox( - alignment: switch (widget.reverse) { - true => Alignment.centerRight, - false => Alignment.centerLeft, - }, - widthFactor: widget.widthFactor, - child: Builder(builder: (context) { - return MessageWidgetContent( - streamChatTheme: theme, - showUsername: showUsername, - showTimeStamp: showTimeStamp, - showEditedLabel: showEditedLabel, - showThreadReplyIndicator: showThreadReplyIndicator, - showSendingIndicator: showSendingIndicator, - showInChannel: showInChannel, - isGiphy: isGiphy, - isOnlyEmoji: isOnlyEmoji, - hasUrlAttachments: hasUrlAttachments, - messageTheme: widget.messageTheme, - reverse: widget.reverse, - message: widget.message, - hasNonUrlAttachments: hasNonUrlAttachments, - hasPoll: hasPoll, - hasQuotedMessage: hasQuotedMessage, - textPadding: widget.textPadding, - attachmentBuilders: widget.attachmentBuilders, - attachmentPadding: widget.attachmentPadding, - attachmentShape: widget.attachmentShape, - onAttachmentTap: widget.onAttachmentTap, - onReplyTap: widget.onReplyTap, - onThreadTap: widget.onThreadTap, - onShowMessage: widget.onShowMessage, - attachmentActionsModalBuilder: - widget.attachmentActionsModalBuilder, - avatarWidth: avatarWidth, - bottomRowPadding: bottomRowPadding, - isFailedState: isFailedState, - isPinned: isPinned, - messageWidget: widget, - showBottomRow: showBottomRow, - showPinHighlight: widget.showPinHighlight, - showReactionPickerTail: widget.showReactionTail == true, - showReactions: shouldShowReactions, - onReactionsTap: () { - final message = widget.message; - return switch (widget.onReactionsTap) { - final onReactionsTap? => onReactionsTap(message), - _ => _showMessageReactionsModal(context, message), - }; - }, - onReactionsHover: widget.onReactionsHover, - showUserAvatar: widget.showUserAvatar, - streamChat: streamChat, - translateUserAvatar: widget.translateUserAvatar, - shape: widget.shape, - borderSide: widget.borderSide, - borderRadiusGeometry: widget.borderRadiusGeometry, - textBuilder: widget.textBuilder, - quotedMessageBuilder: widget.quotedMessageBuilder, - onLinkTap: widget.onLinkTap, - onMentionTap: widget.onMentionTap, - onQuotedMessageTap: widget.onQuotedMessageTap, - bottomRowBuilderWithDefaultWidget: - widget.bottomRowBuilderWithDefaultWidget, - onUserAvatarTap: widget.onUserAvatarTap, - userAvatarBuilder: widget.userAvatarBuilder, - ); - }), - ), + child: PlatformWidgetBuilder( + mobile: (context, child) { + final message = widget.message; + return InkWell( + onTap: switch (widget.onMessageTap) { + final onTap? => () => onTap(message), + _ => null, + }, + onLongPress: switch (widget.onMessageLongPress) { + final onLongPress? => () => onLongPress(message), + // If the message is not yet sent or deleted, we don't want + // to handle long press events by default. + _ when message.state.isDeleted => null, + _ when message.state.isOutgoing => null, + _ => () => _onMessageLongPressed(context, message), + }, + child: child, + ); + }, + desktopOrWeb: (context, child) { + final message = widget.message; + final messageState = message.state; + + // If the message is deleted or not yet sent, we don't want to + // show any context menu actions. + if (messageState.isDeleted || messageState.isOutgoing) return child; + + return ContextMenuArea( + verticalPadding: 0, + builder: (_) => _buildDesktopOrWebActions(context, message), + child: MouseRegion(child: child), + ); + }, + child: Padding( + padding: widget.padding ?? const EdgeInsets.all(8), + child: FractionallySizedBox( + alignment: switch (widget.reverse) { + true => Alignment.centerRight, + false => Alignment.centerLeft, + }, + widthFactor: widget.widthFactor, + child: Builder(builder: (context) { + return MessageWidgetContent( + streamChatTheme: theme, + showUsername: showUsername, + showTimeStamp: showTimeStamp, + showEditedLabel: showEditedLabel, + showThreadReplyIndicator: showThreadReplyIndicator, + showSendingIndicator: showSendingIndicator, + showInChannel: showInChannel, + isGiphy: isGiphy, + isOnlyEmoji: isOnlyEmoji, + hasUrlAttachments: hasUrlAttachments, + messageTheme: widget.messageTheme, + reverse: widget.reverse, + message: widget.message, + hasNonUrlAttachments: hasNonUrlAttachments, + hasPoll: hasPoll, + hasQuotedMessage: hasQuotedMessage, + textPadding: widget.textPadding, + attachmentBuilders: widget.attachmentBuilders, + attachmentPadding: widget.attachmentPadding, + attachmentShape: widget.attachmentShape, + onAttachmentTap: widget.onAttachmentTap, + onReplyTap: widget.onReplyTap, + onThreadTap: widget.onThreadTap, + onShowMessage: widget.onShowMessage, + attachmentActionsModalBuilder: + widget.attachmentActionsModalBuilder, + avatarWidth: avatarWidth, + bottomRowPadding: bottomRowPadding, + isFailedState: isFailedState, + isPinned: isPinned, + messageWidget: widget, + showBottomRow: showBottomRow, + showPinHighlight: widget.showPinHighlight, + showReactionPickerTail: widget.showReactionTail == true, + showReactions: shouldShowReactions, + onReactionsTap: () { + final message = widget.message; + return switch (widget.onReactionsTap) { + final onReactionsTap? => onReactionsTap(message), + _ => _showMessageReactionsModal(context, message), + }; + }, + onReactionsHover: widget.onReactionsHover, + showUserAvatar: widget.showUserAvatar, + streamChat: streamChat, + translateUserAvatar: widget.translateUserAvatar, + shape: widget.shape, + borderSide: widget.borderSide, + borderRadiusGeometry: widget.borderRadiusGeometry, + textBuilder: widget.textBuilder, + quotedMessageBuilder: widget.quotedMessageBuilder, + onLinkTap: widget.onLinkTap, + onMentionTap: widget.onMentionTap, + onQuotedMessageTap: widget.onQuotedMessageTap, + bottomRowBuilderWithDefaultWidget: + widget.bottomRowBuilderWithDefaultWidget, + onUserAvatarTap: widget.onUserAvatarTap, + userAvatarBuilder: widget.userAvatarBuilder, + ); + }), ), ), ), @@ -879,12 +882,10 @@ class _StreamMessageWidgetState extends State return [ if (showPicker) - StreamReactionPicker( - message: message, - scrollable: false, - borderRadius: BorderRadius.zero, - reactionIcons: StreamChatConfiguration.of(context).reactionIcons, - onReactionPicked: (reaction) => onActionTap( + widget.reactionPickerBuilder( + context, + message, + (reaction) => onActionTap( SelectReaction(message: message, reaction: reaction), ), ), @@ -904,35 +905,43 @@ class _StreamMessageWidgetState extends State final channel = StreamChannel.of(context).channel; final showPicker = widget.showReactionPicker && channel.canSendReaction; + void onReactionPicked(SelectReaction action) async { + final popped = await Navigator.of(context).maybePop(); + if (popped) return _onActionTap(context, channel, action).ignore(); + } + return showStreamMessageModal( context: context, useRootNavigator: false, - builder: (context) => StreamMessageReactionsModal( - message: message, - reverse: widget.reverse, - onUserAvatarTap: widget.onUserAvatarTap, - showReactionPicker: showPicker, - onReactionPicked: (action) async { - final popped = await Navigator.of(context).maybePop(); - if (popped) return _onActionTap(context, channel, action).ignore(); - }, - messageWidget: StreamChannel( - channel: channel, - child: widget.copyWith( - key: const Key('MessageWidget'), - message: message.trimmed, - showReactions: false, - showUsername: false, - showTimestamp: false, - translateUserAvatar: false, - showSendingIndicator: false, - padding: EdgeInsets.zero, - showPinHighlight: false, - showReactionTail: showPicker, - showUserAvatar: switch (widget.reverse) { - true => DisplayWidget.gone, - false => DisplayWidget.show, - }, + builder: (_) => StreamChatConfiguration( + // This is needed to provide the nearest reaction icons to the + // StreamMessageReactionsModal. + data: StreamChatConfiguration.of(context), + child: StreamMessageReactionsModal( + message: message, + reverse: widget.reverse, + onUserAvatarTap: widget.onUserAvatarTap, + showReactionPicker: showPicker, + reactionPickerBuilder: widget.reactionPickerBuilder, + onReactionPicked: onReactionPicked, + messageWidget: StreamChannel( + channel: channel, + child: widget.copyWith( + key: const Key('MessageWidget'), + message: message.trimmed, + showReactions: false, + showUsername: false, + showTimestamp: false, + translateUserAvatar: false, + showSendingIndicator: false, + padding: EdgeInsets.zero, + showPinHighlight: false, + showReactionTail: showPicker, + showUserAvatar: switch (widget.reverse) { + true => DisplayWidget.gone, + false => DisplayWidget.show, + }, + ), ), ), ), @@ -1023,29 +1032,35 @@ class _StreamMessageWidgetState extends State return showStreamMessageModal( context: context, useRootNavigator: false, - builder: (context) => StreamMessageActionsModal( - message: message, - reverse: widget.reverse, - messageActions: actions, - showReactionPicker: showPicker, - onActionTap: onActionTap, - messageWidget: StreamChannel( - channel: channel, - child: widget.copyWith( - key: const Key('MessageWidget'), - message: message.trimmed, - showReactions: false, - showUsername: false, - showTimestamp: false, - translateUserAvatar: false, - showSendingIndicator: false, - padding: EdgeInsets.zero, - showPinHighlight: false, - showReactionTail: showPicker, - showUserAvatar: switch (widget.reverse) { - true => DisplayWidget.gone, - false => DisplayWidget.show, - }, + builder: (_) => StreamChatConfiguration( + // This is needed to provide the nearest reaction icons to the + // StreamMessageActionsModal. + data: StreamChatConfiguration.of(context), + child: StreamMessageActionsModal( + message: message, + reverse: widget.reverse, + messageActions: actions, + showReactionPicker: showPicker, + reactionPickerBuilder: widget.reactionPickerBuilder, + onActionTap: onActionTap, + messageWidget: StreamChannel( + channel: channel, + child: widget.copyWith( + key: const Key('MessageWidget'), + message: message.trimmed, + showReactions: false, + showUsername: false, + showTimestamp: false, + translateUserAvatar: false, + showSendingIndicator: false, + padding: EdgeInsets.zero, + showPinHighlight: false, + showReactionTail: showPicker, + showUserAvatar: switch (widget.reverse) { + true => DisplayWidget.gone, + false => DisplayWidget.show, + }, + ), ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart index 7e3ae0bbc1..41a46982d7 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:meta/meta.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/desktop_reactions_builder.dart'; +import 'package:stream_chat_flutter/src/reactions/desktop_reactions_builder.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Signature for the builder function that will be called when the message @@ -285,31 +285,25 @@ class MessageWidgetContent extends StatelessWidget { Flexible( child: PortalTarget( visible: isMobileDevice && showReactions, - portalFollower: isMobileDevice && showReactions - ? ReactionIndicator( - message: message, - messageTheme: messageTheme, - ownId: streamChat.currentUser!.id, - reverse: reverse, - onTap: onReactionsTap, - ) - : null, + portalFollower: ReactionIndicator( + message: message, + messageTheme: messageTheme, + ownId: streamChat.currentUser!.id, + reverse: reverse, + onTap: onReactionsTap, + ), anchor: Aligned( - follower: Alignment( - reverse ? 1 : -1, - -1, - ), - target: Alignment( - reverse ? -1 : 1, - -1, - ), + target: Alignment(reverse ? -1 : 1, -1), + follower: Alignment(reverse ? 1 : -1, 1), + offset: Offset(reverse ? 12 : -12, 42), + shiftToWithinBound: const AxisFlag(x: true), ), child: Stack( clipBehavior: Clip.none, children: [ Padding( padding: showReactions - ? const EdgeInsets.only(top: 18) + ? const EdgeInsets.only(top: 28) : EdgeInsets.zero, child: (message.isDeleted && !isFailedState) ? Container( diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart index 33f8bc79ac..a3a6782630 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart @@ -3,6 +3,4 @@ export 'message_card.dart'; export 'parse_attachments.dart'; export 'pinned_message.dart'; export 'quoted_message.dart'; -export 'reactions/reaction_bubble.dart'; -export 'reactions/reaction_indicator.dart'; export 'user_avatar_transform.dart'; diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_indicator.dart b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_indicator.dart deleted file mode 100644 index 873d60f7a4..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_indicator.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template reactionIndicator} -/// Indicates the reaction a [StreamMessageWidget] has. -/// -/// Used in [MessageWidgetContent]. -/// {@endtemplate} -class ReactionIndicator extends StatelessWidget { - /// {@macro reactionIndicator} - const ReactionIndicator({ - super.key, - required this.ownId, - required this.message, - required this.onTap, - required this.reverse, - required this.messageTheme, - }); - - /// The id of the current user. - final String ownId; - - /// {@macro message} - final Message message; - - /// The callback to perform when the widget is tapped or clicked. - final VoidCallback onTap; - - /// {@macro reverse} - final bool reverse; - - /// {@macro messageTheme} - final StreamMessageThemeData messageTheme; - - @override - Widget build(BuildContext context) { - final reactionsMap = {}; - message.latestReactions?.forEach((element) { - if (!reactionsMap.containsKey(element.type) || - element.user!.id == ownId) { - reactionsMap[element.type] = element; - } - }); - final reactionsList = reactionsMap.values.toList() - ..sort((a, b) => a.user!.id == ownId ? 1 : -1); - - return Transform( - transform: Matrix4.translationValues(reverse ? 12 : -12, 0, 0), - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 22 * 6.0, - ), - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: GestureDetector( - onTap: onTap, - child: StreamReactionBubble( - key: ValueKey('${message.id}.reactions'), - reverse: reverse, - flipTail: reverse, - backgroundColor: - messageTheme.reactionsBackgroundColor ?? Colors.transparent, - borderColor: - messageTheme.reactionsBorderColor ?? Colors.transparent, - maskColor: messageTheme.reactionsMaskColor ?? Colors.transparent, - reactions: reactionsList, - ), - ), - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_card.dart b/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_card.dart deleted file mode 100644 index 727b44affc..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_card.dart +++ /dev/null @@ -1,142 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/avatars/user_avatar.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reaction_bubble.dart'; -import 'package:stream_chat_flutter/src/theme/message_theme.dart'; -import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; -import 'package:stream_chat_flutter/src/utils/extensions.dart'; -import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; - -/// {@template reactionsCard} -/// A card that displays the reactions to a message. -/// -/// Used in [StreamMessageReactionsModal] and [DesktopReactionsBuilder]. -/// {@endtemplate} -class ReactionsCard extends StatelessWidget { - /// {@macro reactionsCard} - const ReactionsCard({ - super.key, - required this.currentUser, - required this.message, - required this.messageTheme, - this.onUserAvatarTap, - }); - - /// Current logged in user. - final User currentUser; - - /// Message to display reactions of. - final Message message; - - /// [StreamMessageThemeData] to apply to [message]. - final StreamMessageThemeData messageTheme; - - /// {@macro onUserAvatarTap} - final void Function(User)? onUserAvatarTap; - - @override - Widget build(BuildContext context) { - final chatThemeData = StreamChatTheme.of(context); - return Card( - color: chatThemeData.colorTheme.barsBg, - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - margin: EdgeInsets.zero, - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - context.translations.messageReactionsLabel, - style: chatThemeData.textTheme.headlineBold, - ), - const SizedBox(height: 16), - Flexible( - child: SingleChildScrollView( - child: Wrap( - spacing: 16, - runSpacing: 16, - children: message.latestReactions! - .map((e) => _buildReaction( - e, - currentUser, - context, - )) - .toList(), - ), - ), - ), - ], - ), - ), - ); - } - - Widget _buildReaction( - Reaction reaction, - User currentUser, - BuildContext context, - ) { - final isCurrentUser = reaction.user?.id == currentUser.id; - final chatThemeData = StreamChatTheme.of(context); - final reverse = !isCurrentUser; - return ConstrainedBox( - constraints: BoxConstraints.loose( - const Size(64, 100), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Stack( - clipBehavior: Clip.none, - children: [ - StreamUserAvatar( - onTap: onUserAvatarTap, - user: reaction.user!, - constraints: const BoxConstraints.tightFor( - height: 64, - width: 64, - ), - onlineIndicatorConstraints: const BoxConstraints.tightFor( - height: 12, - width: 12, - ), - borderRadius: BorderRadius.circular(32), - ), - Positioned( - bottom: 6, - left: !reverse ? -3 : null, - right: reverse ? -3 : null, - child: Align( - alignment: - reverse ? Alignment.centerRight : Alignment.centerLeft, - child: StreamReactionBubble( - reactions: [reaction], - reverse: !reverse, - flipTail: !reverse, - borderColor: - messageTheme.reactionsBorderColor ?? Colors.transparent, - backgroundColor: messageTheme.reactionsBackgroundColor ?? - Colors.transparent, - maskColor: chatThemeData.colorTheme.barsBg, - tailCirclesSpacing: 1, - ), - ), - ), - ], - ), - const SizedBox(height: 8), - Text( - reaction.user!.name.split(' ')[0], - style: chatThemeData.textTheme.footnoteBold, - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ], - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart b/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart index 60ac8fe9c2..09dd2f097b 100644 --- a/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart +++ b/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart @@ -1,11 +1,14 @@ +// ignore_for_file: avoid_positional_boolean_parameters + import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/icons/stream_svg_icon.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; /// {@template reactionIconBuilder} /// Signature for a function that builds a reaction icon. /// {@endtemplate} typedef ReactionIconBuilder = Widget Function( BuildContext context, - // ignore: avoid_positional_boolean_parameters bool isHighlighted, double iconSize, ); @@ -20,9 +23,141 @@ class StreamReactionIcon { required this.builder, }); + /// Creates a reaction icon with a default unknown icon. + const StreamReactionIcon.unknown() + : type = 'unknown', + builder = _unknownReactionBuilder; + /// Type of reaction final String type; /// {@macro reactionIconBuilder} final ReactionIconBuilder builder; + + /// The default list of reaction icons provided by Stream Chat. + /// + /// This includes five reactions: + /// - love: Represented by a heart icon + /// - like: Represented by a thumbs up icon + /// - sad: Represented by a thumbs down icon + /// - haha: Represented by a laughing face icon + /// - wow: Represented by a surprised face icon + /// + /// These default reactions can be used directly or as a starting point for + /// custom reaction configurations. + static const List defaultReactions = [ + StreamReactionIcon(type: 'love', builder: _loveReactionBuilder), + StreamReactionIcon(type: 'like', builder: _likeReactionBuilder), + StreamReactionIcon(type: 'sad', builder: _sadReactionBuilder), + StreamReactionIcon(type: 'haha', builder: _hahaReactionBuilder), + StreamReactionIcon(type: 'wow', builder: _wowReactionBuilder), + ]; + + static Widget _loveReactionBuilder( + BuildContext context, + bool highlighted, + double size, + ) { + final theme = StreamChatTheme.of(context); + final iconColor = switch (highlighted) { + true => theme.colorTheme.accentPrimary, + false => theme.primaryIconTheme.color, + }; + + return StreamSvgIcon( + icon: StreamSvgIcons.loveReaction, + color: iconColor, + size: size, + ); + } + + static Widget _likeReactionBuilder( + BuildContext context, + bool highlighted, + double size, + ) { + final theme = StreamChatTheme.of(context); + final iconColor = switch (highlighted) { + true => theme.colorTheme.accentPrimary, + false => theme.primaryIconTheme.color, + }; + + return StreamSvgIcon( + icon: StreamSvgIcons.thumbsUpReaction, + color: iconColor, + size: size, + ); + } + + static Widget _sadReactionBuilder( + BuildContext context, + bool highlighted, + double size, + ) { + final theme = StreamChatTheme.of(context); + final iconColor = switch (highlighted) { + true => theme.colorTheme.accentPrimary, + false => theme.primaryIconTheme.color, + }; + + return StreamSvgIcon( + icon: StreamSvgIcons.thumbsDownReaction, + color: iconColor, + size: size, + ); + } + + static Widget _hahaReactionBuilder( + BuildContext context, + bool highlighted, + double size, + ) { + final theme = StreamChatTheme.of(context); + final iconColor = switch (highlighted) { + true => theme.colorTheme.accentPrimary, + false => theme.primaryIconTheme.color, + }; + + return StreamSvgIcon( + icon: StreamSvgIcons.lolReaction, + color: iconColor, + size: size, + ); + } + + static Widget _wowReactionBuilder( + BuildContext context, + bool highlighted, + double size, + ) { + final theme = StreamChatTheme.of(context); + final iconColor = switch (highlighted) { + true => theme.colorTheme.accentPrimary, + false => theme.primaryIconTheme.color, + }; + + return StreamSvgIcon( + icon: StreamSvgIcons.wutReaction, + color: iconColor, + size: size, + ); + } + + static Widget _unknownReactionBuilder( + BuildContext context, + bool highlighted, + double size, + ) { + final theme = StreamChatTheme.of(context); + final iconColor = switch (highlighted) { + true => theme.colorTheme.accentPrimary, + false => theme.primaryIconTheme.color, + }; + + return Icon( + Icons.help_outline_rounded, + color: iconColor, + size: size, + ); + } } diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/desktop_reactions_builder.dart b/packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart similarity index 96% rename from packages/stream_chat_flutter/lib/src/message_widget/reactions/desktop_reactions_builder.dart rename to packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart index 753341083b..390a05c11f 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/desktop_reactions_builder.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart @@ -4,7 +4,6 @@ import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_card.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template desktopReactionsBuilder} @@ -101,11 +100,7 @@ class _DesktopReactionsBuilderState extends State { maxWidth: 336, maxHeight: 342, ), - child: ReactionsCard( - currentUser: currentUser, - message: widget.message, - messageTheme: widget.messageTheme, - ), + child: StreamUserReactions(message: widget.message), ), ), child: MouseRegion( diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart similarity index 83% rename from packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart rename to packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart index 440843b447..75da2e4cc5 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart @@ -1,7 +1,23 @@ import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reaction_picker_icon_list.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +/// {@template reactionPickerBuilder} +/// Function signature for building a custom reaction picker widget. +/// +/// Use this to provide a custom reaction picker in [StreamMessageActionsModal] +/// or [StreamMessageReactionsModal]. +/// +/// Parameters: +/// - [context]: The build context. +/// - [message]: The message to show reactions for. +/// - [onReactionPicked]: Callback when a reaction is picked. +/// {@endtemplate} +typedef ReactionPickerBuilder = Widget Function( + BuildContext context, + Message message, + OnReactionPicked? onReactionPicked, +); + /// {@template streamReactionPicker} /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/packages/stream_chat_flutter/screenshots/reaction_picker.png) /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/packages/stream_chat_flutter/screenshots/reaction_picker_paint.png) @@ -92,11 +108,10 @@ class StreamReactionPicker extends StatelessWidget { onReactionPicked: onReactionPicked, ); - return DecoratedBox( - decoration: BoxDecoration( - color: theme.colorTheme.barsBg, - borderRadius: borderRadius, - ), + return Material( + borderRadius: borderRadius, + clipBehavior: Clip.antiAlias, + color: theme.colorTheme.barsBg, child: Padding( padding: padding, child: switch (scrollable) { diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart similarity index 61% rename from packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart rename to packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart index 98bbacaa59..17dc677648 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart @@ -9,6 +9,28 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// {@endtemplate} typedef OnReactionPicked = void Function(Reaction reaction); +/// {@template onReactionPickerIconPressed} +/// Callback called when a reaction picker icon is pressed. +/// {@endtemplate} +typedef OnReactionPickerIconPressed = ValueSetter; + +/// {@template reactionPickerIconBuilder} +/// Function signature for building a custom reaction icon widget. +/// +/// This is used to customize how each reaction icon is displayed in the +/// [ReactionPickerIconList]. +/// +/// Parameters: +/// - [context]: The build context. +/// - [icon]: The reaction icon data containing type and selection state. +/// - [onPressed]: Callback when the reaction icon is pressed. +/// {@endtemplate} +typedef ReactionPickerIconBuilder = Widget Function( + BuildContext context, + ReactionPickerIcon icon, + OnReactionPickerIconPressed? onPressed, +); + /// {@template reactionPickerIconList} /// A widget that displays a list of reactionIcons that can be picked by a user. /// @@ -18,6 +40,10 @@ typedef OnReactionPicked = void Function(Reaction reaction); /// /// The reactions displayed are configured via [reactionIcons] and the widget /// tracks which reactions the current user has already added to the [message]. +/// +/// also see: +/// - [StreamReactionPicker], which is a higher-level widget that uses this +/// widget to display a reaction picker in a modal or inline. /// {@endtemplate} class ReactionPickerIconList extends StatefulWidget { /// {@macro reactionPickerIconList} @@ -25,18 +51,33 @@ class ReactionPickerIconList extends StatefulWidget { super.key, required this.message, required this.reactionIcons, + this.iconBuilder = _defaultIconBuilder, this.onReactionPicked, }); /// The message to display reactions for. final Message message; - /// The list of available reaction icons. + /// The list of available reaction picker icons. final List reactionIcons; + /// The builder used to create the reaction picker icons. + final ReactionPickerIconBuilder iconBuilder; + /// {@macro onReactionPressed} final OnReactionPicked? onReactionPicked; + static Widget _defaultIconBuilder( + BuildContext context, + ReactionPickerIcon icon, + OnReactionPickerIconPressed? onPressed, + ) { + return ReactionIconButton( + icon: icon, + onPressed: onPressed, + ); + } + @override State createState() => _ReactionPickerIconListState(); } @@ -132,17 +173,24 @@ class _ReactionPickerIconListState extends State { scale: animation.value, child: child, ), - child: ReactionIconButton( - icon: icon, - // If the reaction is present, it is selected. - isSelected: reaction != null, - onPressed: switch (widget.onReactionPicked) { - final onPicked? => () { - final type = icon.type; - final pickedReaction = reaction ?? Reaction(type: type); - return onPicked(pickedReaction); - }, - _ => null, + child: Builder( + builder: (context) { + final pickerIcon = ReactionPickerIcon( + type: icon.type, + builder: icon.builder, + // If the reaction is present in ownReactions, it is selected. + isSelected: reaction != null, + ); + + final onPressed = switch (widget.onReactionPicked) { + final onPicked? => (type) { + final picked = reaction ?? Reaction(type: type); + return onPicked(picked); + }, + _ => null, + }; + + return widget.iconBuilder(context, pickerIcon, onPressed); }, ), ); @@ -162,6 +210,33 @@ class _ReactionPickerIconListState extends State { } } +/// {@template reactionPickerIcon} +/// A data class that represents a reaction icon within the reaction picker. +/// +/// This class holds information about a specific reaction, such as its type, +/// whether it's currently selected by the user, and a builder function +/// to construct its visual representation. +/// {@endtemplate} +class ReactionPickerIcon { + /// {@macro reactionPickerIcon} + const ReactionPickerIcon({ + required this.type, + this.isSelected = false, + required this.builder, + }); + + /// The unique identifier for the reaction type (e.g., "like", "love"). + final String type; + + /// A boolean indicating whether this reaction is currently selected by the + /// user. + final bool isSelected; + + /// A builder function responsible for creating the widget that visually + /// represents this reaction icon. + final ReactionIconBuilder builder; +} + /// {@template reactionIconButton} /// A button that displays a reaction icon. /// @@ -173,30 +248,32 @@ class ReactionIconButton extends StatelessWidget { const ReactionIconButton({ super.key, required this.icon, - required this.isSelected, this.onPressed, }); - /// Whether this reaction is currently selected by the user. - final bool isSelected; - /// The reaction icon to display. - final StreamReactionIcon icon; + final ReactionPickerIcon icon; - /// Callback triggered when the reaction icon is pressed. - final VoidCallback? onPressed; + /// Callback triggered when the reaction picker icon is pressed. + final OnReactionPickerIconPressed? onPressed; @override Widget build(BuildContext context) { return IconButton( iconSize: 24, - icon: icon.builder(context, isSelected, 24), + icon: icon.builder(context, icon.isSelected, 24), padding: const EdgeInsets.all(4), style: IconButton.styleFrom( tapTargetSize: MaterialTapTargetSize.shrinkWrap, minimumSize: const Size.square(24), ), - onPressed: onPressed, + onPressed: switch (onPressed) { + final onPressed? => () { + final type = icon.type; + return onPressed(type); + }, + _ => null, + }, ); } } diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_bubble.dart b/packages/stream_chat_flutter/lib/src/reactions/reaction_bubble.dart similarity index 76% rename from packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_bubble.dart rename to packages/stream_chat_flutter/lib/src/reactions/reaction_bubble.dart index 82e5b34d02..88386c9d09 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_bubble.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/reaction_bubble.dart @@ -1,6 +1,5 @@ import 'dart:math'; -import 'package:collection/collection.dart' show IterableExtension; import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -60,44 +59,33 @@ class StreamReactionBubble extends StatelessWidget { padding: const EdgeInsets.all(2), decoration: BoxDecoration( color: maskColor, - borderRadius: const BorderRadius.all(Radius.circular(16)), + borderRadius: const BorderRadius.all(Radius.circular(26)), ), child: Container( padding: EdgeInsets.symmetric( - vertical: 4, - horizontal: totalReactions > 1 ? 4.0 : 0, + vertical: 8, + horizontal: totalReactions > 1 ? 12.0 : 8.0, ), decoration: BoxDecoration( - border: Border.all( - color: borderColor, - ), color: backgroundColor, - borderRadius: const BorderRadius.all(Radius.circular(14)), + border: Border.all(color: borderColor), + borderRadius: const BorderRadius.all(Radius.circular(24)), ), - child: LayoutBuilder( - builder: (context, constraints) => Flex( - direction: Axis.horizontal, - mainAxisSize: MainAxisSize.min, - children: [ - if (constraints.maxWidth < double.infinity) - ...reactions - .take((constraints.maxWidth) ~/ 24) - .map((reaction) => _buildReaction( - reactionIcons, - reaction, - context, - )) - .toList(), - if (constraints.maxWidth == double.infinity) - ...reactions - .map((reaction) => _buildReaction( - reactionIcons, - reaction, - context, - )) - .toList(), - ], - ), + child: Wrap( + spacing: 8, + runSpacing: 4, + runAlignment: WrapAlignment.center, + alignment: WrapAlignment.spaceAround, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + ...reactions.map( + (reaction) => _buildReaction( + context, + reaction, + reactionIcons, + ), + ) + ], ), ), ), @@ -113,35 +101,20 @@ class StreamReactionBubble extends StatelessWidget { } Widget _buildReaction( - List reactionIcons, - Reaction reaction, BuildContext context, + Reaction reaction, + List reactionIcons, ) { - final reactionIcon = reactionIcons.firstWhereOrNull( - (r) => r.type == reaction.type, + final reactionIcon = reactionIcons.firstWhere( + (it) => it.type == reaction.type, + orElse: () => const StreamReactionIcon.unknown(), ); - final chatThemeData = StreamChatTheme.of(context); - final userId = StreamChat.of(context).currentUser?.id; - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: reactionIcon != null - ? ConstrainedBox( - constraints: BoxConstraints.tight(const Size.square(14)), - child: reactionIcon.builder( - context, - highlightOwnReactions && reaction.user?.id == userId, - 16, - ), - ) - : Icon( - Icons.help_outline_rounded, - size: 14, - color: (highlightOwnReactions && reaction.user?.id == userId) - ? chatThemeData.colorTheme.accentPrimary - : chatThemeData.colorTheme.textLowEmphasis, - ), - ); + final currentUser = StreamChat.of(context).currentUser; + final isMyReaction = reaction.userId == currentUser?.id; + final isHighlighted = highlightOwnReactions && isMyReaction; + + return reactionIcon.builder(context, isHighlighted, 16); } Widget _buildReactionsTail(BuildContext context) { diff --git a/packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart b/packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart new file mode 100644 index 0000000000..7bc904b95c --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart @@ -0,0 +1,73 @@ +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// {@template reactionIndicator} +/// Indicates the reaction a [StreamMessageWidget] has. +/// +/// Used in [MessageWidgetContent]. +/// {@endtemplate} +class ReactionIndicator extends StatelessWidget { + /// {@macro reactionIndicator} + const ReactionIndicator({ + super.key, + required this.ownId, + required this.message, + required this.onTap, + required this.reverse, + required this.messageTheme, + }); + + /// The id of the current user. + final String ownId; + + /// {@macro message} + final Message message; + + /// The callback to perform when the widget is tapped or clicked. + final VoidCallback onTap; + + /// {@macro reverse} + final bool reverse; + + /// {@macro messageTheme} + final StreamMessageThemeData messageTheme; + + @override + Widget build(BuildContext context) { + final reactionsMap = {}; + for (final reaction in [...?message.latestReactions]) { + final reactionType = reaction.type; + final userId = reaction.user?.id; + + if (reactionsMap.containsKey(reactionType) && userId != ownId) continue; + reactionsMap[reactionType] = reaction; + } + + final reactionsList = reactionsMap.values.sorted((prev, curr) { + final prevUserId = prev.user?.id; + final currUserId = curr.user?.id; + + if (prevUserId == null && currUserId == null) return 0; + if (prevUserId == null) return 1; + if (currUserId == null) return -1; + + if (prevUserId == ownId) return 1; + return -1; + }); + + return GestureDetector( + onTap: onTap, + child: StreamReactionBubble( + key: ValueKey('${message.id}.reactions'), + reverse: reverse, + flipTail: reverse, + backgroundColor: + messageTheme.reactionsBackgroundColor ?? Colors.transparent, + borderColor: messageTheme.reactionsBorderColor ?? Colors.transparent, + maskColor: messageTheme.reactionsMaskColor ?? Colors.transparent, + reactions: reactionsList, + ), + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart b/packages/stream_chat_flutter/lib/src/reactions/reactions_align.dart similarity index 100% rename from packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart rename to packages/stream_chat_flutter/lib/src/reactions/reactions_align.dart diff --git a/packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart b/packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart new file mode 100644 index 0000000000..6871b843ff --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/avatars/user_avatar.dart'; +import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; +import 'package:stream_chat_flutter/src/reactions/reaction_bubble.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_chat_flutter/src/utils/extensions.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// {@template streamUserReactions} +/// A widget that displays the reactions of a user to a message. +/// +/// This widget is typically used in a modal or a dedicated section +/// to show all reactions made by users on a specific message. +/// {@endtemplate} +class StreamUserReactions extends StatelessWidget { + /// {@macro streamUserReactions} + const StreamUserReactions({ + super.key, + required this.message, + this.onUserAvatarTap, + }); + + /// Message to display reactions of. + final Message message; + + /// {@macro onUserAvatarTap} + final ValueSetter? onUserAvatarTap; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final textTheme = theme.textTheme; + final colorTheme = theme.colorTheme; + + return Material( + color: colorTheme.barsBg, + clipBehavior: Clip.antiAlias, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + context.translations.messageReactionsLabel, + style: textTheme.headlineBold, + ), + const SizedBox(height: 16), + Flexible( + child: SingleChildScrollView( + child: Wrap( + spacing: 16, + runSpacing: 16, + alignment: WrapAlignment.center, + runAlignment: WrapAlignment.center, + children: [ + ...?message.latestReactions?.map((reaction) { + return _UserReactionItem( + key: Key('${reaction.userId}-${reaction.type}'), + reaction: reaction, + onTap: onUserAvatarTap, + ); + }), + ], + ), + ), + ), + ], + ), + ), + ); + } +} + +class _UserReactionItem extends StatelessWidget { + const _UserReactionItem({ + super.key, + required this.reaction, + this.onTap, + }); + + final Reaction reaction; + + /// {@macro onUserAvatarTap} + final ValueSetter? onTap; + + @override + Widget build(BuildContext context) { + final reactionUser = reaction.user; + if (reactionUser == null) return const Empty(); + + final currentUser = StreamChatCore.of(context).currentUser; + final isCurrentUserReaction = reactionUser.id == currentUser?.id; + + final theme = StreamChatTheme.of(context); + final messageTheme = theme.getMessageTheme(reverse: !isCurrentUserReaction); + + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + clipBehavior: Clip.none, + children: [ + StreamUserAvatar( + onTap: onTap, + user: reactionUser, + showOnlineStatus: false, + borderRadius: BorderRadius.circular(32), + constraints: const BoxConstraints.tightFor(height: 64, width: 64), + ), + PositionedDirectional( + bottom: 0, + start: isCurrentUserReaction ? 0 : null, + end: isCurrentUserReaction ? null : 0, + child: IgnorePointer( + child: StreamReactionBubble( + reactions: [reaction], + reverse: isCurrentUserReaction, + flipTail: isCurrentUserReaction, + backgroundColor: messageTheme.reactionsBackgroundColor ?? + Colors.transparent, + borderColor: + messageTheme.reactionsBorderColor ?? Colors.transparent, + maskColor: + messageTheme.reactionsMaskColor ?? Colors.transparent, + tailCirclesSpacing: 1, + ), + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + reactionUser.name.split(' ')[0], + style: theme.textTheme.footnoteBold, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ], + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart index e13d607fa2..d680344059 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart @@ -120,13 +120,13 @@ class StreamChatConfigurationData { loadingIndicator: loadingIndicator, defaultUserImage: defaultUserImage ?? _defaultUserImage, placeholderUserImage: placeholderUserImage, - reactionIcons: reactionIcons ?? _defaultReactionIcons, + reactionIcons: reactionIcons ?? StreamReactionIcon.defaultReactions, enforceUniqueReactions: enforceUniqueReactions ?? true, draftMessagesEnabled: draftMessagesEnabled, ); } - StreamChatConfigurationData._({ + const StreamChatConfigurationData._({ required this.loadingIndicator, required this.defaultUserImage, required this.placeholderUserImage, @@ -176,78 +176,15 @@ class StreamChatConfigurationData { /// Whether a new reaction should replace the existing one. final bool enforceUniqueReactions; - static final _defaultReactionIcons = [ - StreamReactionIcon( - type: 'love', - builder: (context, highlighted, size) { - final theme = StreamChatTheme.of(context); - return StreamSvgIcon( - icon: StreamSvgIcons.loveReaction, - color: highlighted - ? theme.colorTheme.accentPrimary - : theme.primaryIconTheme.color, - size: size, - ); - }, - ), - StreamReactionIcon( - type: 'like', - builder: (context, highlighted, size) { - final theme = StreamChatTheme.of(context); - return StreamSvgIcon( - icon: StreamSvgIcons.thumbsUpReaction, - color: highlighted - ? theme.colorTheme.accentPrimary - : theme.primaryIconTheme.color, - size: size, - ); - }, - ), - StreamReactionIcon( - type: 'sad', - builder: (context, highlighted, size) { - final theme = StreamChatTheme.of(context); - return StreamSvgIcon( - icon: StreamSvgIcons.thumbsDownReaction, - color: highlighted - ? theme.colorTheme.accentPrimary - : theme.primaryIconTheme.color, - size: size, - ); - }, - ), - StreamReactionIcon( - type: 'haha', - builder: (context, highlighted, size) { - final theme = StreamChatTheme.of(context); - return StreamSvgIcon( - icon: StreamSvgIcons.lolReaction, - color: highlighted - ? theme.colorTheme.accentPrimary - : theme.primaryIconTheme.color, - size: size, - ); - }, - ), - StreamReactionIcon( - type: 'wow', - builder: (context, highlighted, size) { - final theme = StreamChatTheme.of(context); - return StreamSvgIcon( - icon: StreamSvgIcons.wutReaction, - color: highlighted - ? theme.colorTheme.accentPrimary - : theme.primaryIconTheme.color, - size: size, - ); - }, - ), - ]; - - static Widget _defaultUserImage(BuildContext context, User user) => Center( - child: StreamGradientAvatar( - name: user.name, - userId: user.id, - ), - ); + static Widget _defaultUserImage( + BuildContext context, + User user, + ) { + return Center( + child: StreamGradientAvatar( + name: user.name, + userId: user.id, + ), + ); + } } diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index a8887c459c..2b36105d19 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -80,7 +80,6 @@ export 'src/message_widget/message_widget.dart'; export 'src/message_widget/message_widget_content_components.dart'; export 'src/message_widget/moderated_message.dart'; export 'src/message_widget/poll_message.dart'; -export 'src/message_widget/reactions/reaction_picker.dart'; export 'src/message_widget/system_message.dart'; export 'src/message_widget/text_bubble.dart'; export 'src/misc/adaptive_dialog_action.dart'; @@ -104,6 +103,11 @@ export 'src/poll/stream_poll_option_votes_dialog.dart'; export 'src/poll/stream_poll_options_dialog.dart'; export 'src/poll/stream_poll_results_dialog.dart'; export 'src/poll/stream_poll_text_field.dart'; +export 'src/reactions/picker/reaction_picker.dart'; +export 'src/reactions/picker/reaction_picker_icon_list.dart'; +export 'src/reactions/reaction_bubble.dart'; +export 'src/reactions/reaction_indicator.dart'; +export 'src/reactions/user_reactions.dart'; export 'src/scroll_view/channel_scroll_view/stream_channel_grid_tile.dart'; export 'src/scroll_view/channel_scroll_view/stream_channel_grid_view.dart'; export 'src/scroll_view/channel_scroll_view/stream_channel_list_tile.dart'; diff --git a/packages/stream_chat_flutter/test/platform_widget_builder/platform_widget_builder_test.dart b/packages/stream_chat_flutter/test/platform_widget_builder/platform_widget_builder_test.dart index 08425ebc9b..cfb7e774f5 100644 --- a/packages/stream_chat_flutter/test/platform_widget_builder/platform_widget_builder_test.dart +++ b/packages/stream_chat_flutter/test/platform_widget_builder/platform_widget_builder_test.dart @@ -71,4 +71,29 @@ void main() { }, variant: const TargetPlatformVariant({TargetPlatform.fuchsia}), // hacky :/ ); + + testWidgets( + 'PlatformWidgetBuilder builds the correct widget for desktopOrWeb', + (tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: PlatformWidgetBuilder( + desktopOrWeb: (context, child) => const Text('DesktopOrWeb'), + ), + ), + ), + ), + ); + + expect(find.text('DesktopOrWeb'), findsOneWidget); + }, + variant: const TargetPlatformVariant({ + TargetPlatform.macOS, + TargetPlatform.windows, + TargetPlatform.linux, + TargetPlatform.fuchsia, // Quick hack for web variant. + }), + ); } diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png index 6817993469ac1c0a83973c61bf261129cd50066b..f8e44836ab5202f5d4e30ecf67d73313436e6d23 100644 GIT binary patch literal 12163 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 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png index 003142a4a995677192ffb5d4e553c496dcd35a48..b497e93903d6cae7ed79a50b49cbfd6460986170 100644 GIT binary patch literal 12993 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 P;G?HytXZx8==uKwg!*yp literal 13555 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 Y*){yFLI0z85b)C1G1jiV?fmrr0Ny5lS^xk5 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png index c44f070718a2a76889bc1571e3db3eb8d1e13a6d..29d2e83ccf0c23a541b1653713aee4080a001d27 100644 GIT binary patch literal 12111 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

H>*Sz5UI+nH5x&Bk#`vX+HqWPx!pMvtN zJG}{>yzwf7gU*nr9@YsSUIv@~XkX>Xw58v3BZJ;qHd0vO2X6ph#%k-!zI_UalCQ zl>lMWy{7h4Zqv<%;N`tt+JiXwhFPt6fevQoQwD9|*OkA6j6FqMU`1}X+C?Q3J2Y)z zaTTK=1yTdEHcY@>Su3oX*fkL{l5He>W2f{=v53tjbr9v;v=iS^ zoo|(@)wKALwbS8_sPl~w;{EdWO&LCOAg7?R`BrVc6x(+1-fuGlqIt}YAj1eOntObu zH+f_=;BrQRaj`zaaB1iL_>sOzl3J#r1mb(LB(^@kQ>h0ib-KJ@M37GI=zi`OvVe6a{iSbu@0LNO0XKTY(9im%XUe#L@Vz3^xEuPVXoIB4~=kZ4|+#8?yI;x{RTXbHgs#LoF@z5}TS(1u^NTKZPteTvx z6%mA$eTknnecwr`e+2Y>mN{=27LVL?v3Y(P*qP6QtkoxoRTMOkLM)a{e0L1|6ZV3A z;IwJc{cDVlueufh2OY>M0Z3#q_N?u%LIcGaGOUaz6zVx(+yEzY_iP*Pt*)pOL0|e8 zxy(jpFv6Fmrg0=YIr--=`n^)@m+@5zbx*O+Q34B68N#a}3h{iq4V2;2Ab?5dU_R)k z9Ic!0+8%FU_YR|u=D~E&sN)0h3iV)Jb&czNz{&rI#h4V`&6@=YOf2WIY@mtD1h0EX zeg-dpa1?G<6dcI`FxC^LWLF8$y6)JEr!N6Y8dLor40VSCz(fPIbQ!`J zn*_R>gR<`bn;Q`X;pGl5G2A_m&H(c*K~lBwj*S$_DRdaomN~sgCsbr~B|%YWa7$*fI70 z4<&DRUjbGajjjmN)XIe9D7*fZ1c%6*QO zJ;p}xf94`0aW6Ygy}rm}E^#jPDiHN0FZT)Pl!6X2F;IejZJLb$!CES-rB<)+>6yR9 zvK$pm|EF2K|DvMs-%bAy!T#?m=Kmjxx3`ZO^h*b+#>q2PAmB36Gt;fSeK+>M0XMV) AhX4Qo literal 11876 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 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png index 14371b96e56687aa472fb0ec42f5ef41e8896f65..99265680388ad7695cab725d12f416c85f29625e 100644 GIT binary patch literal 13017 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 diff --git a/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart index c153889075..ab4362c81f 100644 --- a/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart +++ b/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart @@ -2,7 +2,6 @@ import 'package:alchemist/alchemist.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reactions_card.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import '../mocks.dart'; @@ -68,7 +67,7 @@ void main() { // Check for reaction picker expect(find.byType(StreamReactionPicker), findsOneWidget); // Check for reaction details - expect(find.byType(ReactionsCard), findsOneWidget); + expect(find.byType(StreamUserReactions), findsOneWidget); }, ); @@ -94,7 +93,7 @@ void main() { await tester.pumpAndSettle(); final avatar = find.descendant( - of: find.byType(ReactionsCard), + of: find.byType(StreamUserReactions), matching: find.byType(StreamUserAvatar), ); diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_dark.png deleted file mode 100644 index ec2744779b8a227e57483b6ae583e2cf284c7656..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 670 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq}`x)5S3)qw(#Gz5c?5636#HUFUME=!(|?wFPQC6RtUaROR6_`f0SH@Un%q zgqq=-f6RSqDtyO|9QE`pxpZWqp&^S4uhT`BiPIOcM)hYmE>E33=bByt@wSN^^aT2PUS;)1QXwN7?iuruvR)FEBLIBqu3oRd@+>u z`!SxFUUOwhK1IRIhNl)gKC3n#yqT|IF`J=bLRkCj+_gI@4fvd|8|1A`x}){TQLQ^9 z&((8%L)Y;wf7>7JxO*|~vg5@x!ms=n-hxbNHF+vj3(I&-zT8O-^%2yOkvyR*PQ zSUK_5s6xJ}H@XD^P9tKYJrW#7s38t)!ly05!#{_&Z$f##(~FZWr@EAW4t x`{nCq#vS`=5C7*j{oVnIA#4#BTztr$k;D5+u5Q_GF<=^F@O1TaS?83{1OQd&Il=${ diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.png deleted file mode 100644 index 255333867e444239d13ca9c0f15137f96227f6a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq}`u)5S3)qw(#mgWe*E636DhpDmf5?r2mHo4;|JikhxyiH6V`XGI||g?qbL z94E0XEa~=Z6<^5`?R4nXrgo)WB`+^1a+nwhd3Q|t*R&`qv3TxZs~1bAyq&i9KG*ww z`(N+*eCBiW%>JKkfyX48rJVB18?%%T-4RTD*I`iZGQ(QwjI7|ZK8|AdmYopc9ow1? z&&*t7Q{8px5tEm^_<~1;6@SwoeEr6_F`@KDHRDlr{=hSL+apgoFTZqQ<=ukaeg{v= zY`Nrp^M_CLnY)KS9r>~Bc**NHmc@}X3|ta37?ytjJp0^L-k7HHUGsNI?JfB6jh9RO z{M5OH)_n(`eCCMXuVpRXbGJ1wd-)po|2*q$PKC~^{J3Y44ugn%__<%09NLGpCbrZ+ zwOX)U;Cl^pwUQIJ;`Utez>TZ|9?*qGZR&A9J>r_eFuJ%CYU+vej z{`oEipZP)#pUVo_SnvJc%i^oh>B*5RtmN|B}ifq$k# WgZ;brety8T#Ng@b=d#Wzp$PzDfitK8 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_dark.png deleted file mode 100644 index 7dfc978dc2ca7f30a62802e2b19e33d89724e0c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 615 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq_ZT)5S3)qw(#Gz2`p$NE}=59*~qNJnM%Sk626N-48q-e|9TfTsXVsV3L9( zi*RV-g=GsX+RSV1h1Ng+yQ5#-@?3t-`?$Sz&XV^ zzN1NkjSdXI|H=W;<(DF_zs~YpZ!UIx%hDjusa{Xt*UmZPuNYGi{pO$rPdY@85s;{Xgeqo!$I}nNmE5 z6GA)J8Zc;dHC65HE3o)eaBf>}iIuDjAN#b@8{EteDngEH!X#qE5+U%Idj7PAZviE0suK%90GoSCdCR6^q+kfl!KW^Pn zTh6%p;h{B$TO-@KH}i?7$?Bc4ikVTm!{Bv6;x&lGaX;;d(9ko_i(l;Gi@pBvV?}`0 z)Bp{U2Sqy>7_Pq--F%a$Yte%mJLgF%9+O&P^x9pN9G6~~?#+&J4K$GJm!H>qIC0DE z+&g*ZU#e_#w%=|qp6bPVG-+aq>8C@pmMy&f)^4un^2-K1%&S(}&3#>B)#0L~@_OR` zw&j;!wi|aJedK)ed|IvOBcNKr)3Tp}kIQ#AEk7c`M&!!1CDO_0LmcG>_a{YA)zV;n4dh=(M@4h=BRq|rS zlrYs@hZr{8etY5l_d*-F`R6#B7$T<$a&(0-V)`5?pZzyBUq8c4XTzS?yE z{qoqOQi*?V&2n2TIPLUP`SZpzd0u_Bn&Y=z)O3xoS>)QV89r(S7BU*sPha_0{lD$$ oq5Ee~$9{x|KbDB8w0u||b8h~$>yv}t0#giwr>mdKI;Vst0Pn;W^#A|> diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_dark.png deleted file mode 100644 index 78280c1832e95af234fb2ab678ca9d45abaee96e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2741 zcmdUxiC0s{9>;G$fdbN&TCuFQvKd(v6Ila@%B~$FEv zT@iwyJuc3tydVg64}6Cx$bokqGb|Z&ummqB2Z%DP$pb&T5*%E76u^_F5ON!W6oXw( zo$$ez3E%(Y;VseWU-3(=dkt&#vJZSd6Ef)d7^#kV##2?p^%P7k5^gXhb{tmB``P!u zw<|n7!wCH;*YhaO+n(f~34g2D((;c6AwKYfQd&3av|ufcrITG@UR1{3_`2>4SAa62 zSC+|AEFT+DPS;Pd(G!`90Sbjft# z$h>4J733+ zGB+1?6^ZwxDcn;>cUj}!wMG`_f#He@?XC4U9;*cUCg_Ap_t8PJRi4gtI=wTF`)kZp z=WIkd4u=C}Kdm%JAleDt@lJV~oFg`6X||QaWtP>;Jv-fSoF$9J;=OIUY=!^)2eu1e zm6-_}8XDrL;i&BL>4hz+M6fVgEnZ8sB4=goMj{Y~`;}b_#KOti?d|J~OGi`aSR@k3 z={HdQ#*g32%!KOC35CMQ-oE&^_;t~-PgGQ*coBVG@2cDcgdK+84DV3U|9@o}7 z&0NF3;ZCPZrWAc!yJh87ifnFduGf?154T0KDbZRxqfR;lPmS38L&={%oB(DCZ4RJK zHqmH7SSq{qgQ4Os88NqKXFDj%;Y5Lt;oc&5eW65MLxZhp>XMLjCI*c#6{&tjx}$11=cTjve!&n zylk}dZMVO0kr-{@FsFQNVrW1_bTn}6=-61n$CdWTW6fi{^=GsuPz^(HRw^TOL=_+`E$cxDNM!PvW5Gi-45Gp)efx<({dIgnrxU z4Lc`^ukfIK#Q6GpB17h{yXY6vkJjR)T8gT2q4Ko54ZXfnBomm&4s2b#w%{xw!>mu@vX%jWjGs6*@e;cDUTy zfc(tFB)GdV(Fzl91Y0FkDUlo*+!e5oHEMNQR*A2cR5%T;7-jYk`TaPlSQx$KUelX` z8b0zRSYTa-i3N_h?|dqJq=Ll`z9Ag^E4yu)z_eYiaVwspRx>v7X z?}pFJtl+`nu@lbhU6wGHC6Q54?w2oLrm%07J1Koa-gm88@B7wn;eAJfSRX$d79Nh{ zjn&}foe%S7`m)7$DuzPLN*WS_Es4wai*sk&1WiV60HOTlWxoU8y%q`Btf?t-)N#`2 z=xBp{gKoJ+TyMqKYoA_yk7>X5Vj5kuur^``W&$`=>g($xEG+y*R_8FgUPbDbpB41$ z+!*J*sbx35Xit?;C|G*u+@BwQ1>B@iC}-p)#l^)U5H!DZd_;GD%$=K`XH8C$ z03K+^4TT{A=z-z3K&{)_nwn{cl3FnS{+=El`9{pKg@rnO0|U2d)4hs-cl^c0@xj60 zC>YvHTYoAnU-vi(mh>PrU~}$aY|&5{5(F(L=NmoMoQ5o`3pXJcRuv!&P&>;0wx8U; z*P~tp7RvZuW*2nf76gO#|7;IIjtbxXj}Lw7(U+WPO%^G<0#{GS<@DK86o(5p{|i{) BAJYH; diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png deleted file mode 100644 index 2fd8bf6deb8685d0382bde4a2c5eb18212359b36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2918 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 Ee<-YNj{pDw diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png deleted file mode 100644 index 45484fa7732df3cd19ac506aa4392c5d77a02953..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2843 zcmdT`i96KW8~<9m`O&0EqAZo9E1>XTPvV>;v5}Zh$5`)T*bhK6bpI`0OG@THkPhQ<&61- z7#E(x2n&@~{!`(fzu09OI-QV$+SdlW5OICq^FU4AH4yVUjKB?_yFqS<&loUZgv<6) z$+h+ss%;Vpx>0l9ZZFTPXT#6jT@eyfMi)H%b7e}!FLHz%jn1mbK_6_=ERy=0BdZD# zeJabmQ6~Mh3RV;tP$$mx0KhnJ0xsfq;kq2d*ziJe-}Y_xAP( zS|Zx#C%t6>C_F3-2dgl`4h~upIy=?=fUdB=M|b-?u&^jDE>_pp_5kB)k%56$)wiJv z3JRF=@(*FYlON~j8wLBk2qf|jZ)X9qZ8khSJV!*-sjI86?DB)WO5QHF_Vo6WsnoLH zcDRhs=YSlKb%c-@DL^O(ja) zg`e%_LW!I_eAC`)S0+-?p~B_RW!=>#Bbn_fJ5se$I}vbIZLHnZ*S87W_WSqmB}%RZS9y*T6(`fXaoXbZ@Xhs&&UYVF;|IgY`leDVHxuLub(-le&*Qw)!1O< z4sSpH%YaaEY3bGhf0w)7LgHecJb6+}{4%&Ve1c-cWpOjV6T6+6C8aoGXpM473D z-N(NvgPH2)*X@&Cf}P}%@JnQm29?Q+s4=YRjk6rT7q_awu#$VJv0vQ?&DqVZSdc#S z2$H{~yHIJGS^`1EB_}5vrLaR`;og7ISQ}pkvr-NPy!f>ba>YeOQ1n85@501^M{`pX zd6AUL*uUlE6cHK_kD19W#W>R!XuhC^+lyR)SZ}DOB2i z+L685u$(8Rii}+u&D2F^B6(wTrKtH)-8sA~9*=(?3Ls38g!nCrOqGwPXMK}TcX(3L z>=foB@s5^)al$Pb85wl#%a<39WLc*1S4$Iy`dSkUu8fb5bGIrh6@6ddx5T;HYn3|0 z^b5KKq=tqDmynP;q?!NCE0ZoU5UQe?cba!%^VT`W$_7}j^MG=Po_IAtp5ysluPPX~y zM!#v6T3hdaWqrfoLW-OXq4T$N6P2tve+_iATPP187fkv zhD(fu&yY@O4ip{})1qjGtRH`VEg~q$24p&zfU~9LgRiXD&3A||dlQ*+>vcT%nLh8s zAIN^S@gyvcdl4zv+->bu)3}WSe1ojhzcI6|mV*KJr`Ev@LMAK6Qxwpj$YktLj%3Sb zgu5=QPl}!=_R+ttCDdL;N>1V!IOW-Z#5(otrc7S&m@VIO z^9;Y~>1nxjDP?WhN39f`xunU&9AUytesqqYf~&3`R6Op5i`0MQK;PM+Fg|yCaP;Yr z;4W;=U?PJFRZ4Nd!twR>f3s*KKWM~QBpGkTGiKX{`k1o*$Tl^TJ6fd%(et7Glbk!J zV^NBK8N~<3+8@fx&EVP{m$r-!lT4bomgzF(#8}m5&!^8y^z+xw%A7u}g~@nqb76C5 z#~sAov`9}^w~*tzG&UYw+roW6HZ~?!6si~AucfK^DOdXPHcxfeXi~?V31(7LR#tXn zgya|VuAi3tnSk29XhCU1G1;4~{m}Fw-}f~vFTo}(hO%X^RFdph3;&tW)wRi{Ps?!} zVK97C(>QBiTUMDqAn7wSChBj#XfU47!Ld;jYIa3tBRtw z54ZU)(n}-?*mqyHx9gsV*C}%aO}+SIjV&sU|8H=GaUzVtVB|NZV_JSAE;^>f z&_@gBO@xm|n@r{mSSu88 z!PV8(=Q$h>HT9h47~IY-_vX!ZW64f9jYhLqEsX75FiQI8h3V6TEy|U!=on~3M8idE zcZoERMdG5uV`h~>;A@SFin^XrB1buHT2MN`Z?jYArC@JwQ=feZ(0iri%ZSx9=?vIT zzZAXrhVFUA!OO6JdF3Jh4co$zX4)LP`-7vGo2!$P{K$ZV+5P%!4F-b&YvB(7K{3-%L^Y5|rt1&X?T#Kl*D7ni zP3^Ej28aOM}|j6x;izcg{uE-6kiAbo!43&xlr932hF>g4qCy5m}k*I51;|$7U>d|j-jr{V?`?w?~u)k zT>82%k2BJDei-rTw(W(J3w>!mA|fJ~va&x$XkMKeUnosJ;ZafJ{4AMuP#MWHGh53; zIr)zEbsd@-w9#(N^T*L)VaZyRq5CVN(osu&z9qpp63LfDDr?w<HrWRiI(5p@GzVdjk$ugW zFc>5gvK6uor;dG_)EEqn^L>7J{)gweez@=JzJB`L*ZsM#_mf*ln3#x+2mkLfnM zZdi`BKD~BC=hUFI@)I-fb_>O{gbb)VOub$440QGJII`|C6y_u9`Vv_K89%OaA@!5w zWwLmSSx38`2ofQ7Ny{VSRJZV`_qkVY@#cy~8L7kHQx&_sbNLTF*SLX^>_* zA~%-5=$if@Yv6I4CXiZSTZCL3M!VP}k;%t291H5}>oa(q&7Dy0g7xt5a7jxGwg{Cg zE_YHlAiL1=W&XEs?(ATe+{KDAQ^T;80Xlx-O6+a~JA67OZG*5jslUo*pf@%){Cs_% ze_6Ko^DA9r?!`hNkS_1q#PN}#q2k6yM^MD(Bq8OP`fXQ?v$WIx4_fo4TY=l9VX8s- zS08l#J_b#)nY@62=Ma4t#oz&~|H2$QT~U z?d*iYNvwZr%2QS+-j=<2W7FoU#0#n9A;G&Q{cEHE-&h0 z=_ckerI9tX-R%ylJwNb0ab{C(bgHsaY+_9wb2oz>8jTC z{@Jqel0KC~vuyhC4+CTQ6h9o!VgirHr){1HU?t1NJc8+^u&ANSBkv0ery3g@xoZrL z-`Dm;N4h`eZi1BX{?meI^nQ~aO9kThtLKcMDe@I7EB;AxhB`xYf49Y#mX?x~w}~co zbo!%Yt1O*fQlr)t3B`Bhy&DycI!%M~>#g&ekq#Q^KHF*{MC)lEMy0N*RI#bM^U+t*32-8;9+*3Uq@Q>@Nw}D_cYpdo+4^rt5{|4$jX{8ICgE zAmovykV^hvyangZuKI0w)R|;?wiP z-vo|R!z;BY6iU?3UR@=g6~#c?{W?m$gT*?$W%#v>mhbicPsn&vWUaV@Kxa3;El);9 zMj4L5U?kDpgbXf^n#Q4?CAXvP>S(m$+FDx@IXhccQraZ9|5KE5NnV~=I6E{Q znXUKg<44N|C(Y(xya_)%-kwNo%8BLs_GW6U4Ve(hq?a#!;a1WH!l`cEIq3>@K(J+h zN_S*?^Upp*Nn5n>_{4-g1{2vU;Paz;9L##NbWvG4c$tCl{1_!;BE){{;lrHS>ZP0` zA}+2Hf^y4<>UwqnJETYB)$?~rA$qczm%RR5T3Q0za0;HO<@WH{1#CH)OnyxNy3rY> zdZdOWHKL`RKU1?nDO-46OhK@1Pet=qP7H*D7p6K|)Q{Er;QF%lf8!%L&p#(E;Z6jg z(dcVg-^13|*Clo9Qe^e>wQ(bN$KH7H7pN)uj=7ELTppL<*+s&&D@ltk?QZ{kg%8L( z9QVxZ(Rmm$NA|K$7c-EPM42xlc;@n{#ltG+xgT52xRV8S-Ix1~s6XfXVUuyUHfe*| z`h0uEP(jr+ARK<|p72)LFtkYmT7TsF0$ zLgO3fV!&j5@t6Cr5`hz)*-zuDlK13ns@W@N>NU1?^y7XpioZYvd1JTSYRBvx913T9 z(qWeGp2-NrSFP0gFn zjWcndesc8e=>Ug2ud5_KtiGL==TDA~o=fjhfoB>;zF7%l$cq2ruai}1l~wrZlT8J- z*-=GBC9OPmsibBeL!N5qunUTcV9jx&#$Z$RSt*Ag%#b95p7fiPU(8Ail0OxCK6cn~ ztO!%P1foLh?zS%$o8#S=?F-jvW=GCbRL`9oXp2AadhL8ctxvzBKv32qFuru@(oB%v z%;wId$YS?7EI;}v({ytxIcGomI? zMcsot1?nnI>*1lAJ4r%CNG#LJf&LBs%bq@AQyFdK7(yU~{@wb3GpwVpk9lzxMW^LV zy{WBLqI;~5lfEl>RedQlj^-7YmfoE2quBcTmWaz4C>MP$`9mRAZ|;FA{0`lJaE;A) zy_Sxu#5VIY!_z998f*gI-T?uws;)lNo_NRud)ECa(C}o`<}-vD7H?G6Jv*(?V1VnG zbk}zgP-kcYKVI7b1v?N+%)nMFOUt1{7n)qhEJ9-7H*eZFIHV;jm}+K!xOggDi^_6i&TRYLjrGmFgTrjH^#)J!y>^YcH8SC?%IlecTZ2x z0ful#GJfVpQpO!+SXi=-@>Pt(^4mmfsibOi1FDs7N`MFITZy@+|w9sf*G#qJn zZx{_y($WeuGi5+58gmCMGB0{SJAxVPN^2^#q_Pqj92^|A)-WG&c*Lsp7>(~`0Ptrw zqU^y>m5{I>A|0u_79yMXg#z z)r=stX6;cVzIp%f{U1K}xzD}l-sjwN&+|IZJ?C{(@4<}OSp-=C002AG1o8j?pvk1l za3%)oSU&JDj5^VTJTL|WYKDc^s0+FfFw}~P+9H|YDbzzCD8#@DnYTq)vlRMG!?5EW zhQNUImz06E>?bL_vlS$Xk7Zj2W@Y0S6&DZ6#wCnZ#wB6Gp8oL}Q+3=7v$0xqc-yf@ zI8ng0;Hg!#&6vzcV2_Hn&5S@M(VJ+=1K@=~AZjQ_XMnhP{S5{tZf<7xST61?uKzL7 zxQbQ(XD0j#tc;fgYS9v)wAIy8DEdncX#;FJ`%;(ytnIuEV{5lQ(ctlr zs`)ZjxX~%cV2lPRrrxt4)-uD6assht8+bUfam}I%Psu?Mtsg;5S+%V>hS&2Ss=+PU zxP(xWSDw2uag;So7+tH(b&(TC-wi4xBx$BkCSAIg#E9TX9#7R*{ITwl31CPWDyIO1 zIjFmrlgF7SM12rS<#(tyf+Jdm_X}TjkKo9P`u^Y?uM?}7sx$-m&4Tr0xdw-NR!WI~ z=Z2-0^=l6P^gD_=I#hG236jtqWYk9xg9z_y+1c1?X%S*0XCk=ya5mS@*|GOW+ghoD za<&(9);p%~2#J&f2p0?ez(~mh->(`Zq?Ul8cE0bUPq*P7=WN6I`4DAv=f-59+^q~E zW@&jxv3Qi}ypqK}C#(NqUG0uwNS)n8T|6xEeKIp5N50lKkDQO9n z1GRUY_S~V3LA^JJArj4yO#`1@%G%e~;vU3?E#3x^(`j0VurMd#pG2ToQV6 z-gEfGhz?M6kBi#73=NS7%Qrph{^Dbjj_>o)N3}(*oPlt&WBXegO1GooNUJBB!p-4_ zmXU{t8s;}`rHt+eQReJl<_Ra2t|%b_1ykWXJWaBQD!hh89`NgQf9f9D36y+SofS8m z{spGVc5qBOs8Aa0{&j6Yxpltn=ibZ={`)f#m@TcTg^g!yqn6SALMA8Y(6BHOrVP`? zAfPSCHEw*ZoF#({a?#8f8Z!3}2$*n6BCT(1B+6}D$M(Pm%I(APEw7@gM>dQs!Zg&E zg3Si3peRYFmQx|fdu~8%<*A~U)~goF@s)*I8U3D-JP^^v!J((^jMMGyucO4?p^eqG zKMVjiPIh;YI;ZuaHQLM1Y%`?c?304p-v)i`qF8ut2>xqLk41st*@99$Eji_mxTwyb zA5+Q1s;gZ$U{(Z+lJT5(fqLHQY03(&r_B{AiFaTD8M>=@mzsNL;bGv(rBwcC1m^7E zZ`y0cp{;b;yW`dP@*SkktzO$Odnwcs;a+h;)T65mCb_)M!SjR(Lap-CutcFF7e-(Kwcey*>cD@(MAifDK*%)xki7CvxnJK5A*eNJinauaRZ2mg9QM7Yc`%OQ=y*{ z)VZeTqYdVeh1^V4uW_P$Sg%V@|Ak=R8bh@GnoIzv6T?YAw{Q2}5OsyP1~#tm{;Aml zH6bG#WSn$eES|A_mC@6SaG{W2zRIHur36f3oaH$)KRY}03~oxexyJfS@u($-NZB_9 zcmUKGB-)2k8B9QB2G&9<1-EktL`dZ`Ca44pj8j~t&4?mvqM_z3EgJhAZjNLzD9?*- z@ynMl%jf=!9&dbWSpV+Du5{7D(T~M%vVosn<%yGf&#ZnW$_*%n9f8&4q&Wd{nCbBMGe(+%Mk@R|)%h?({j7KjxGqD);Y+;!}^>$a&H2 zIbE)+C`mNqIE~o9l^A;PR)&10x;HTCyXrhLl2=xCyON>Yh>Dk+UsWCJZ-@+T0y~kE zn|91bdI1IBq8;PwdnFOP_+>u;S0%$VjujrP||bnkr)I2_T4l+!mW>KC%=9bjkL&=5*|6U{{g8+Pdq;J6tKxvVcV7M zrzWC`h~q?tNcOHTgbH7uGyF|KgGM7StjGP{_+%C93<78CkAePf&%Eeq$+Lb6 zd`1R}Kp&*We6UpZO<)qUeNNDB=ij}T)qibgJ=HS`bh;17t>3Md9dz@e5_~L1vIwb; zj?6j{6jt%9tJUgmJx(go*DE<4#U9t#^-YqmR{8mz9G!_~j>Md_shW4;h{Ps29Wg~Q z%2IcpmzUNcrFKSdVu}U*%wal|i9UXXB|<~T#%A7~>JK2ZAO7~is3|HTmY8u@y(REX zOvdb1QZK1zZcfK#xSK<_^m6*iW;S-}l5fbYrG^=pa2t*4m!upM9?vx&UAgqUE6l`P z5_Pg$R**R&DlGQ+!vywl@8vtr(Z<#i_s}=wv@7URIiK08f4uB_rdF9?`GWDT)=Da8 zKyp;nO8!5tt^NUpm%bPa43mCLN!KoaNg6I4Dm%G&|N9`wL#j_MBNeke1i_ru)1f>4lpM*F;rX8!iY34fZA z4pP$-8bdkbW1;^_%3Yne-^dEwL+?;-4*!SSnI2{Ohw`RC`BV;JJ%Fc5pTVaq}4XKMO}lp?XrKI}mvm%1jLj-KA)FgVtP(V*Dq&YF~bA zsqdQ@Y%CUwSl)l8$;YVkuI>3dxN_pux$Ip%WQtX#8j(4xA5P^u31Qnd@v=FIVZ z+xG!w{yC^{28yV*et&(hB074)n=#w#N(_0RplCxo=e2EZV{2SkRn_Njrd9)9SwpH} z#t(VA0Cmhz6xW|uI}xL|?4eM5T4tbD@T~AWws08|lj|!pF7OsL?60 zWDeNZ7wJ+oH7Rpw7%N!sQu=?UITPp!E+&2R(}Iur+8C;L1M0MJy{r?i#A5kko4ya0 zeSYZ|O=kbqM#g)5^j9%~-Yt(|`z1#?ld3+S*l;py0JcmH@d0I>+x!8zQZFMTNEVpgX`nmCQr73*7Z5)1;U8zaxf)Hz90X t;^I7=zO4|5WC9Hs0s#ZX{`bV?i>XUy5np4cdZ|At0MrNusR6si{U81rQ``Um diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png deleted file mode 100644 index 2fd8bf6deb8685d0382bde4a2c5eb18212359b36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2918 zcmdUxi$Bx*AII0_bX0B~sgqn=DuhEsh+H~IHn%3$+*3`%FdX+%xiyy+av8>ooep<1@#z+Ur03-b$*n4OKt68*2u2)rjq26+Gn#cs|#O z#Qo^bj-C9C23gBLeiuCkihFeH&HOyrcggoFgl+!rM}onFRdB7nh; zJbqfk$<3{xyQc@k8*=Wfp_MI;*Ezb!?$b}HyAljn8V4AmsR|~v>ydmCuqQe?T1H03 z0S3#;(sZX)RcT+773Yp*Wu4O1)$N*Do6Cax_wDkyD9Z6GDWIfa;8?xAy$j3Bu&}UN z2S>*{_V(}YP+%(8uDRfJ^z}&!v3vGnVqyki%lY>-vVkW{9bU?%HE3MG#0ZvZj~zaU zM4^V>nJ0vN6w_-XAgm3dw%;R>$dDg$2;s^rcBrDAhyGS;T}L;Uv5xVFj{ zFOCci4c%NcjO3RuEG*OnOd6vm8ePC(a0GA?s#L~#3yh6=4DKKh)b^Cq zem*`HxN?)?rD6BjA-%~cZ`1={UsW|Vn?r{VEi5f%o?n`5cE@6|z>=e)q+M)mGbYN^ z^ocsgGgR@$^y^`++-dnK0|NsmIGnQaon`r~^X^z}fHMS=N@Ma}^Hej%<&8*FQ=Wd2 z%j0zny6%aJ;mE#D{?=9xm#36#fvbha2I}7qWa`F6k;59YbSXDd+R-#C&rGSy8NEbto)2O)T7Rr?9PD!y+>iJyC(aauZ-l= z04S*bopy6yrDc_-5O!Ofu)-nR*+Bhs8mbVyf$nm+bx_?s20I}K(5P(w-W}-d>eNSj z0WGOX(DLLEJ2WV$3INpy9w}vQ^=6{t3G4gW(-D1=B8LYD2MMXEsfqjQ>gqUxrTkwO z5+-}^F^iSnosT8bDYW|Th|rkkn8w>Re=2(hWNA{ zmjt8;iNUz)qC z!01tAoYCeN^INvIfS40ZxXixL&e72u`{Z?27P+d*K}Je(baYfpSZncE>&S0J?JHMi zH+G8nh`v*zM|e{S3aOOJ>S{+Gk0&E5JJ?rjscU3ZUQ?q(y<6GJ$Z$my)ZFZ@ zqN4H>VIbLj)v`M*xO)%>uF|?LSyRg?k-v| zHa12_jWI~WO4bzT3O2DY#(>JQs7|r-_O*Wwy(D6rF!V6nZu@ZjDqVZ(!}P{Z2#|8{ zFmWNw%d2R8eSMJ4F3ruAvF^ty+iZ>pvs8fWnjTq=@a9M-jT9eOgQ&YV86hX7mwrJu zgsre?h=x*LPEAb>i7n~ho-FNJ7c^UAEJY0z&v`7f{O`XWZCX>EB?N+nC{oBD3y4@@ zZf#DdXf6m=n$wWcGWhwC}mJ`gwm zT5t_|rUT76+2^r7g6)F1_Px%{C0{Iz()OCn09&3rLRr!tmHQ{t+3gW?d2z9Zz4Yzd zw@XS&rb$UjLHe?)moC}ezhA=e=a7?=kHLLSo+Cx6H_xa=E&2k!YagIcEfJ=OroDZ8 zgJmLYG~WIC5phHwev z?YDqkB&VdHDt^5Jh-h;IsBCT#^U4TxyR@TxUPi_{XScuF8LR0Z;g0-Szq!Gq)QeIhEIjDitKbIMExz!u+VkVQ>-QAt5v-p$sR~Mn= z#>RWIv$KrhXE~j6|0qxA`qBC*6-{J-Uf$;B?eI_2?J4v}1End)a$}20B&*1+WhTiR z42ZCat-=H}*K>3-QVXU}5xw$XQBum!-hZb2aI>s#Ye8#giunoZkg zCVQ*#I=ib~RCsM_r0-~6K$8mK$EBqgGPAOfA76-RRY+CdjJszBSOgESR0@L;I=)yw z=HFn;Wm8kS;zftcU5eRkwu4Oj!?Q^<)#Jb`eY z6Tzjr)`yf0DX(n~Kq)|E08F&Xl)zwf3XJLi$dC^q?!`3!*!ix&jn3{V8KO9Ia~>4r zRJK0^YLjztaP_TQx18+lJq4@_k|Lyc@07eI8~@sHLLjcI!9rMhdQiZlfm&ZLSZ=^< z^y*nQ7N)1a?a^qsjY6S-t^M^FZn!vGx#dKSz|#O!s-vSrAd^)~N=v(!Lb;`R{tjp~ z`qN5N+`QtAIF}-zMr&lJd})b2^0Sj`EfN3k^>phdFxBFj2&vy%fnFJ8eG_6qGxK=* Ee<-YNj{pDw diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_dark.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_dark.png deleted file mode 100644 index 757ebb5a0ce36b762089a757501ee8c736ef2913..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3536 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 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png b/packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png deleted file mode 100644 index 3e0b6e8cf39e2597acbb2446d62b4a63f78d5fa2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2971 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 H9F|Xw|%SO_L2+Jg*TwcP)wn}rG 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 OQ3(O{aHAi+cU`{l~;C=#XKg@5)-+E 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 literal 2178 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 literal 1982 zcmd5-i#r?dwyZ1* zR_akyBoVQZWM&l_(W>cVo}o!dlx6?L?)&b3-|z0b@4ox)?z>VyA1{rM3_bz?02;_E z9svsc?mtyiRoKo^H<$vHG6THa0i9gPI|Tt|x+4SC6q2hJa~l8vB_KWA0>5co7jQ5p zSVOjm=K{|*bkA<3}Z;~<8Z6e=7+`& z)j2{Hzg{R*ZMc$O)oXX zG}k?Q25eC(8yPDIcg%yf?{zgQ-vAnqY|wuXPKDOFBddUfB{k-KlCior+rG-wM%+A{ zN}*ihXMu|~d6|AYF6|U$*2IP|_LvuP|8e7?o5p+-(6}-hxmaSO0L(0NhcX+;KqpKu=yjRhbJhY`!<&9{p2(lIW<_ zTdIH^+Fvp&vkd1e0a}+b)^6x)T~^Yyk}oUVJ*h^5yEZ>Q^yd=w^nhn2T2AvS@n*P} z)=YBT(o7<23MK_18p+~cd-CKpq$7ZnV4-MfPd)wg{?YFgmREtwflr^)w&< zy>^_F>qUf=8Z5h2K9wZUZ>Vtc@fjK|l2a*Vpz6(t2NuO}vZ9^x)H7^**zQV~=p~kB z=farmlOK@aqZnAWpCXehNT!ZT&2KLcY~$(~bc;P35K}vme9ZIvCR=#Ua5+8gc0S%O zi&zgk} zj92_9BHOn4Kti8#h6`$QabMA7TQl{KuEtvr3cFu>?=*J}zM}svH;b4#&f1CCk>nYb zlr+`l)2`8uplV1C2C_L^#@3&kpBq>e^@Y72PSYwb%L=pF}1PnQ@(uDu=}7hwh^^$8V;5w?FTDr0z+jih!J#&T~*7{vhts zGhqGlBn^U--10slrG;9LoqJoT_)5`9znfvLH%mW<%{{@zs{y7t(KJBtMu zS5}Bo5Xc#mGRs`d57uQLLmrd<_&So%nKb|COV%d2sEgU^FWC#?AbR}S)gKT*dTzY; zq_vv++D7kmGWA~2WM#phFBM0zP-COue@%xh>3G{t=bjShiX(JA-$LR+Ib>{<_P~8a z({e`qapIL3-P+jNbI(y-Iq+WeTy3ei_jOH0xY`TLu&Q^47tC2){g@k+GLB$gxt%Gox3uQ}^jlxo&%=veoJH^p{;!W@ a0E8Um|8}u*kYLwyBIMI zQldqyrMA)vMWd8js-cz?C6>v1|H6CsoO{3Ld+s^+-1GV2-Y3`XVWJ}PA^-qD)Y{6z zk*ogyNg)AleXx-0#1$U2Bg_my8Btv28h*5ywUZDxFhc$*0D#~#Ym2K+(M9Wp?q~&T zIa3FRQMgLFrhDYtr*t&9lTWhAy-Cy3>xbxO_eRyd)6rET(t46>+36B<{ks4n~>C)-Tu50F5zkGH!RZrxXwx}NE5h6G34%n8tNExw-Ddnu#v zNlndpNNN#8tlm!Hb!Y=h#vFq+;tfbzjJbyAcR~oq`qw$ui$ocJH71FdOiKKI9)} zpLO?a_$-McoFE*NM~yw6c+U*7$Z@G}{ z6}iu87iqMO2HiG6QxHyuParqY(+UI+BnXVM8k)FsjazaR5D2xLt(5r@Ew9OHqPioBnW!jnBKH|s|*3okMRpR ziHAPXNIiVd)J!dc!lzoX0Mnwx=GkRJGZy@KIpT1Sb=i6Hi1JHwV( zOJVg6E(F-28248zks#mwo)Y7j!BOni(B97yN&1DOGo|~N%A~;g4gs#YvVGg&!@%PH zIhgV7OgBATn3w*|0MT|OFkAN<`Fu#Yisn$uZozj-%J{z1v@&@fEn_kBBtvUT|dohJB&8y+@7JsQhr9FEjrb+_qkES#~q*KxFS zE!2eum$d&czo*pTA+YiPL0f~Y?GFG~gcZwtE5crhQ5C6KRtmS%dQaOus_g{djbgRLg3BV zgr;V8S)Le%Ml21}@GTj)j zG2-6RO2tjF+Zc1KA1eW!>LdH(I6e;BIV5wkynvxaj_qIq_V&&{Z_eKrnT58MBIWHE zzJBPSsyE`#-@NxUu7gS18yFgKcTWU;k1ZS=G|i>c^Ih`Zl$!X<mX zRMnB-LP|n@m`iJ(M?ub2l5Gx;0bu^FaN5-3o?s$F*wQtVsP6Cj7}fgY;}x^4q^gLr zqRgnQ6}hhPr>INcWBG!6?@Y1G48e{BeuhqAkJ90BaQ75cl-owSamk?mjIM>~iu)9g zSI?icp7(wi@n|@tPi;`x=lG3Jwndr}m;_x7Z?TD!cyS-kq88*k#tG@4pfDch_zb|W q7CMcf-nV9w=BIA}|5x+$gy-cSp9k)xu93Nq9AIr}Z$UBhe*7=f>f~Ag literal 1696 zcmchY{WsGK9LK+1WmEEy+^A`EhgQORl7~b#Oh(440oIFpk_!jn#11A93&Jyx*Vq`TY7huXEl7CxiSpZ`{5S0D#SC zeH75#*AS;>uj!l4z>YH2gAUf6??FD>5* zm+i_b(xwH+tInMbR~LU;4$Zh%XH)Gtv{zM{$3%>{o{T3_OO68b*WL1+{|BjKjsM1k z;m~;VzpkU?hufPsJUbW|D1O1Vir{mT-t%|PhRX}B(-ED*c1f!PNwS8T?uMH{IH*RImKk82PdTZR&f2(;VYLBe>5Nk`>EGgGx%M zbOf*x-D!TKu#@$$s|n3815*6HLm-~^1x^Ci@H_&j*fl_hDa{wOldkUF!GJ%*Y?hue zGxo8z(;DsO3r8J!7jwQ{l$IG3DNB4>*VRfb77dTe?IFnBjs8P|+~V|d%pZhJ*_$B6|>#SVOfAfXA`6<_wnmF!2GnI~TJV zvbnKTS^dZ<9J&%?IS>8Gc>r6n#f99OZ=ic+%Z10}yvrROh1bl)2Q~8xSt9#-tx8H3 z(G7Yo=aA&>wvT zIZ4~tbXYunLMF7NiS(v^)jQ0w=AYIcVkAQYh=a) zUp;8?(|zREapE1hR644M>K-T_c}0cZqFN7tQDrf5;a3qtYP?h=T1%gZWs^fEHFfMo z>dWHS>?zZsgS|@q(2z-&C zO8uzwM~Y{bJ#o0Cq%3wycaJp^&Kqc3%_R>Tf*L>;D{=Y5K0sHNagMnBmrPEF`onTs zCQl(ywjdyU-a@kLQO~p5+tJ*H4-O&T5goZ?*D#VmAvp0ZCb{jvE-@1fGPUOuLQk8s zNfR46XxlwtFO%OaDBd1_PO7v!D1$RCb}{mle46R>d4>*JN{q>RF357xu3!@}+{il- zc=n06S4TY<*t!T=W;a+kCfMVU*PS$e_W`MKv3s_$c#pu#rW3M@=%Ax{D4&OFZRM9@Uc%KrWKK^*t6bq{=GB_z?AkwR;LgexV9 zB^Wz7Q@Qd%8bNq3IR#+?5&Z9iJsO$mO)J%!KgiVgKhRY8n_iz-nX8|nu4Mo;DhSzn HJo?tZMTQv1 diff --git a/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.png b/packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.png index e1d90e5977f0a7d79a3003fb45320505d58d98c6..8097b576069ef017acceace9baf90e02e27b20ca 100644 GIT binary patch literal 1800 zcmb_di8tGc6Ay|nQldrTsE8k}s>D$=cKy~0Dp|)?4lPZziMW<6K^0}Sktz|S+0+@W zqL%DKpJ@Hu=h~=WsiGuXXG5!6+ugWYjsDWVVSn@9TyN&hn>TMhGkIqMeGh7zXoEnY zgE*`=Ua9F{7|>A4gyq{rrBX@4`(i*%V`ghg=Rgt$M+B6V0nl?nAdMEBw>849e25EYtsNNny^6a>hF-xxabSyd}(jF%Q#>Pp=#aaKUUY1 zba6b$f&O7SxF&_kcGMV4vm9tSvbpDV?vYvmi8~%Ej&veuiQ)iegV~JS!Mwr&X)5G- z-6ylEW!FN6x=I`2q@(UP4#n>|>((dy9S zh>}rNP{zVBZXlJ8u9UOGM^q>PgwPg=|!|jO;9tUId-yFQ$=z` zM++e@n}Bnk!Z{BJ&7P#&C);~tB+-vL>iGxxY>jWx1U%HqKHR~5AR(DGH|*+ECVCg2 zdZ*|Y%^&$}b%T8MYxVpo%^b$b2#M~;Y(&bHu`mq~-N`BCO521fm>RN;nd4(g*cXjk z?(iqUnqO}r=`#6xUKHI}X*&NwNxjqS@U#~51_P>^bMv0Cv7$`Ly@L`Rw9}G1x^KYh zxuMRCl-WmWGx9SiV`%V|c6uL!j4t#;`QZ&!L5d|{I&p2P;g+bW6My`k2Mjrcxjtn{ zx2E2FDQL34KLW!Gru>z zvA8|g{qXV0;VN6V(z;4A!NL&nSIJ#}yVufmjQRdP3}n&kJwuu#`uoQs>RNH6+?O5V z2+;{;ivNqAt9qb>wPzbrhAc4z-PD=#L2faC)TViw;&xY?iJ z+}Y$sn!dj=*v|J~B8+f}EUQ>EDlm4|@7emoLf?G%-pE!#MO(tl)kfLJH=XfI^6_uN z-h`2tN38y3h-lc}fvE+T;W{#-^gQ-AGJj>}39+MWEY)}f zDmYYw;+_kOnmT?x23QxbV8dnfSi@b(ybzh$YXO7_OH#~h%MtBlqr#U+%0{bh-`>o8 ze?@#(&!)m`CLs9Gg*9+qZ&#D812T3k@hqyBvHTepzWY9VCzu^hlRkC6{ACpPOANEp zNTjDfz)_S9>2zCA1F^52b>XM(?Cu5gz81UJ)zH~?;q^9cA+81p%d$RsMe9(YCy3M znf@*YVWeGaYsI#ti;U~p%%$iI>Setg-!m@iWgNlVgj$SnZhqHuN@xxC^-Y*txk_GN zMx##qhEEAszU)*7*M{Ba=9~E|`cuQv1_;iWJ$dk5_0;+vg(AqzBca=shh6;GftK #&IB&jV6 zf{l^##z6dwpVhTZS7@tkywFG4%G%BEE;T<4J9PK}LU&KifB2|L0kU31LDEjF@&5ZK z4a@{_aDMR*?nHG+(m7#Stga>{qODsRB2R;lBTBz6TuhtPgtqM*(?6|05dORV(K_`2 zLS5&)Xna*T#9+DP=}F!9<#2NQr%xjTz573@l7bdLe8aRTJu3UpUcPOvOGc$(d=GCRUd;f;M=X}4P^ZB0d=bZ2Pp7Z^rxVjKE)px4{0H8@a zz-R-B8s8v9nFe zfud;4Ia=i{Jne1dG{|d|HW#cg_cex&iug-AB=_er_HZ;j(Dgh^Dbe2nx@%t|41rC8 zg1E#?5ZeI<{gUBFzF~Wda%|ih^OGWl!oxVO?gF^z&h57FqPT8U1N;Ghj+;DhrtU^L zs;%9=d~>8%!tv^0A;JwV%ACiq+a?Ub$T|u@gfoXR8%E!QAGpmo6UGt;JLpxFl0!0QVq2hW;-3r2rL9fgT>#K$6&4YowUw$sxOnAB=%w<+ zhZ@oF*J9~vc-2@3p{v<`fMp;%D(8sTm#8{zFv@(d;fS5l&t4`xU+SJNEeH-qEKT=U zSJBA%v}04kE(@r_qR411MSFILqh3tzlcJy?-5$8{!mSKgKZE2%k@8 zq*ouK#^|A}ux<%KK;N(d<%jsIX~gDj2oOEB*pogdJgd|f^btF}euPIV_LF9zZ`Cm} zu0)B}Hw%|)wqCJ0b`veFB>+&zoLc$ImfjE+T#!48LQU(Hd;9d)kBxDb&R0Hvgqc4d zd8D~}M|x)M+GSBvn4u=UeJ!rmt60d&c03u3D#xVNWVJr`evIH=D1anLLp}%toes@4 zMJ)-MtTh!qA8m{*#14s}q*%d4ee>n59Djp%1YT9lv%uYu#io_j;mregodzQrQfiuf z$g;YQ{#)QFYJNV2qH7fY(Uvwq-Fz`rK6Uqwomb(dlo<)8n+Cnsf6w&Y(|H>md`l-) zRi(>;Szl8Z(m4A2;EFHRIAhTuw4#1(?L>laQY+h-i?&B59p-&L3^4_zCptp(CfBE7 z9MwMs8x>5Nk4yOQ-1uS-7(p+!)92;an3p(m(YF}0fp4P1`{zK|IU?;C2*VW#8w2}; z#jNj71_vZLLT5-gV9-QV?%^06GmM2-WQeR0%9aKtwPZmy+04d?Wr;iLUshrBQjqP0 zxi<}6%c;ifhv6b(BzZ1MvZc3-U)17CkGC!NS$gKC5SaR+ZCU(`YZSr@%###ZIeYKc zZT`Bf|2}4A@sCe8ZBMjJ#4F{pgbHW5%4D4n1PF2<6WrG%~y@Z?z&%M zS-|P1qilcrmS?5ZgHd2SdAu8s7N*dkR1O1)5xE%e(;~mIz6zpAJ9X%)@^2GFYUL5# z@dKUxsROrZ6<{hD7IVlaqJ+8X!^z6xYJi>yMTy13CbfpVnku+r^P=k#Zu`!+b*29u aZ_4Nt2`4tYJ(Ml?VSt2paj3-lCj1M*B93qX diff --git a/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_dark.png b/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..25d222bed1fac863365f8954a9928c85cdf9ceca GIT binary patch literal 649 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq}``)5S3)qw(zw@9ZlHB5n8YSb17Y9_J2XZ9k_|^4RIssl1q7x*nn{7wGM2 zP-yzU;K4Qf2VT1bMa_nokrjN_$5HIwvQzoc9l^wR9R}qP;o#5@Q?4HT za)MvR_*&r=j)&=1@7Bv7sM*1P_s#d(vMnN;m*($C+x{?1Gi;KOovN8!d#KLwWUpVB zLUJz0ZNI(a@s=vNYI*A!U)2*BW|Z%LwBzF2$Z~UuZ)f>3K7) z6)!mbX3pJLY8=P>KB;|^?XU75MVX}uXJ<~_+PI0KAX7Thx;5s<63Gdva}BEP-|cRU z*|ADJC32nH^r_BzcYN0VH_~p8`4MX4HSOyx0}wNC$8??7o)N02PbrGm3HLv8ee%xg zd1c7K_LgsxSwinFJ{)Azwz@9&^ZrWf5+hmhy_~Aup?#M!GYz#K&k1+8mbF>DC5Rj7?tIZxi#k3Q zsBSF0mi?eO=+>rZ$w|poYwLMMThAOmd*x8&`o8J5VegkqR~H;yoopIxw(_5&VL0Q1 zRJObyrgOH{+$oFVFqZwki+$?Zz0rX)3eGu&9CHfM`?YB{&t0*8Y_S85wDcD(^^6AJ Xrt4o{xx5yboESV^{an^LB{Ts5FvTPb literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_light.png b/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_light.png new file mode 100644 index 0000000000000000000000000000000000000000..670bc5de2f56af1ba8d3aaf68d52739f507f7c81 GIT binary patch literal 613 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq{wN)5S3)qw(zwUyqPPk+%6W^Q@T9S|n!*vaRg6(DFr{mv3Fx?JzEr6J?1i zI||;q72b}z}`{iK(o+W{=hblmbQaAXIzrJVq+)HI641Zd9(5JoA*BN{caQU zu6%#7v+wn`Z7UQG{omcVz%cRcj16Tz5!PyJWQDKwab_QH*_wRl7DU)4{9xv^od<<< z*IYa#^}3?x@)_lGn+^&xDE)b+HvgrncaKu{kqDJ@!crAy3)O2|WBx4L>phMA%=A6q z=CPD}Jl=Rz;_{LR-AMCOmTDPO@_hes#y^RUjBNNUB9S;vV*jaAOgx_^Zda*vciLkA zv3$pD|LSWo>c>N;xo+a?+VO!k?8v5D8Xc)WJGj*~x>Ap_Y_2)dTI_OU(>?*w)1L&z z>y&?3&RiI#bJ{)Thhh4WP4g}(Ona)VXX8Cde9oWebDqz6#B8c$`}Ww$i$ya;?ps#9 z_{zFULQ(bB(Z2svdtmgagT1d;q6*g6Gc|T|N_rq3ldzZ}3 z3A6KCzEtzoi-pbWL*7TuR(CR&eCDw$=j7jt9S(D%Q%)4E$vJCNxa-BA>|T+^Glwk~ zeVOnuwe#+8$>lqJ*|kGhFLv#&{NZ2spm4r+$)x4|taU=q6xW`6cCUyZv6wl&8)7 zc&GE8XkLfARlKW)CUhYki#A$6K~0 zAG&3j_;$vIGM@-*wKcL}VfDA#6-7LsgbmC%7B^q$SWv*GE`FgW#&?x`+VTWD_Lm}8 zm{za{=s2!?mmU+>@_he+OV^J-XA63Fr$nsoPm^6jE~C+5e$$zXuLEIdX=~+ZglfuGgvs#pUXg zuh|)EyTw#Ed{FdU{$x|qk=Et_gV%m~K(QSK%)FVdQ&MBb@0FdekFaQ7m literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_unselected_light.png b/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_unselected_light.png new file mode 100644 index 0000000000000000000000000000000000000000..c089b20c3bf0030fb215d028d38bd27405c466e3 GIT binary patch literal 621 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8jKx9jP7LeL$-D$|Sc;uILpXq- zh9jkefq_Zf)5S3)qw(#`(|NZXMB3`5lbP9sI~sNbYOB6lwA;>Qz7GEkftAyJl|xru z5p(WpJ~(6J#=BDm7y2&v!ZWq)^IG@+bNs)>^sSBExBFC~%ZvZJ8=MaxT7?HCpWw<1 zRr>Nqpv3m;eC4c!ZFQUV{@(oH_C01r50|Od zO^#ij$hF5(_TYuh?we-s$?G)~6>GYow6?#7cfNVk+GMM(mQhoWe$z>>zINY9@6MKO z-EX=+pON06|Kw1rt@3Fjj?G*rTE#Ov^|C$pFQ3Hi&(SY@Y7JA-L;1~Yk<-L)r9`qm zIn=n}gYl}r#pnL+Y18~TktH(x^!dkT({BE|=oxlsZoOAjaHB}#M5!Mo_mA4u-})SL z_;?_DQ^DtG_o&Yg^tCGN->iLicK3udtGxE~AhXp>EALL)zhaSnf#CZOTU??J^*&b; z`0~0;_T}5e88dcB?wFzeRQ>pwB;o7L;^+GoK2rF*!GrgU?f3rO-wn20{2rq+>Dn8$ zOTQlaPMg`szgX|qRSt1q`N(w-Pdj@@-Ty7ZF03cv9@?|`)xzbmg(dSVA|gt0p+3JK Z;&oYz`ENM?TntPy44$rjF6*2UngIFD9##MV literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_dark.png b/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f0b4c634f87ee44fa05f8a38d632b79e04379cea GIT binary patch literal 2324 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 BrGx+g literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png b/packages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..068b97997fbc725467889948d76d8fd6bbf66082 GIT binary patch literal 2495 zcmdUx`9BkmAIIm4@HqY=Im zIdZNjM{>+HKFr!?e0~3n&-;hh`}KPN^nO1c?;oDeZ#h~Eosm8R004w+Z7d)F09WRT z_ZB#HqP3rWADlEUG{o8*fFF^io&;XBxh+)Sq+$fT{{sM=_P4b#gFY3g8lfYR(g2caIl(72!mYei!$86Py zl*^=99)Mzf5@Qejn5hT>xIa(TaO;~Y5V(I7MB({4eq7~sED(x zbEtAo5>H4l~3eJWQn(@}IGAMM~5`Xv9*__9fHy?gk}VG5}C+b->z;dh+Yk zz295|7+fr81<=_d`#D(2_NhL#2b&8DJdShEU~0Epv)1yVE@>fwhSbrbehVxayTp%M z`YXGYN}rRbP8JesoZD|uyW&uw!B;Y~-Y;b&BNe#D`{KU0R#y1Ti=~7!Cp-RCGwN89(Bpelqq) z&6V=*<2YMOKvB~}flLjIF?>c$-mF>CneMh-&O$b;0(ICv!Bz$2QarR({cRM2%_liXkaHDcXEBksb%UJ>BEQMG`q?ckKi z`i#ofr4^8&27eOhA=GFf0J~weW(A81{KSX2RWV$=lR2~mS!i|yqc#q*>$1O)|9`_p z_?fL%HwUW+=cG3C4)|xB-5e0<`ljo0j$c>*UP(0!#Q&8hV#`BXp;(_9T1sP&5Az?j zG0S)QTfVKg9|L6slCS{?XBiy?tXp5C*>?uH=EiGNARR&eVys5PGT>&m&e1;anM6I; zn=-(Ze7NzG^tl2@J3rx~JP$LTG@Y@kYs3a!*DrnP22O*8iN_FcXYGBX~Uj=(KUn``k1(m;2E~mQ)YqG7F z%h~437xCi}Un4ZPpL|;N5ptLsYETMbg0(3hoyww^xAq1bgs8Zp3v+?BVAcX+tv6HA zLEXk(Z}Jiv@}*G)?G(Bc*OL`0y8=VIg!IV1vMo0-=;QBQI3(JR%>OOl@ItDaSk zc^cjgcutad{(G!v9TI;viGn*uM`;m8vvD_X#u?&}dH37zXM-^4x4jtdZXO@0((@*~ z4Wj-2b0ZCW%ES%dmz=|E)CNs^>u0@k71H+6N_V0T8Ldr=i#CJ2oduU9Y$#RSRLF6| z%D$OWa|o^+PupYIb>X8Hbq<4sgKxWocLoS>TLS6I73ZO;X%76@!)>>CR_As&4_9_* z2~RbIUg0+}z9D`zsM+rU8ScsI7&h;j!#VL zRrZ7ZacSy?IYP`$qdzdV&NQ2l&PiZr-kTzubVS4QyY2wbzim|~3e*2V%_>v|V6M;A zF`H;cO`xUwuO~fU+%(Y2fa0+f^WN5!^G=eFZrM|7`of~l2Vky*@8|ryH*BT#I2b*f z=EUEm1v8?~{8*u!3g5lEH-?gIc&u|fex$1~)W46=w2l#v6G`z^nl!=Nzg>M<^lM(q zi)e{i;yt=+zXIS_OW!hhEYwgo93r$ z#R56M*trsRuUOC7ZoXfQpcga~;$f`)vSlws?N&^uma9E=_Op0aVv-Jhdp7KmMtxRb z2-=1I@kh8|t_ZU+UTaPugY@LI{=nT@N$ZDt=_JNf&Xtsisy-e4F1j#z&5`$$;Lm52 zst|SXT0Vt!P)i}pBd-FZO02VjFe-y_78$S={gpMRhTH38Ok0@iJBl>G&A{$xt$#`AR2vc zf}-0r!urfgh=WP956{zX7bCP9$|BqOVb#}EM5ipn)fukZ=s%vO1sJuthMjBk;1Adn zTTS$#hB&`e=*`*Z8&QSWs^;Byqb?f^OC}!lg_cNcc3Q;k6WwVC7tU5-NURN30zO(_ z4xFovwBL|aS2%w8Gd(8=x<~ho3&!y}{^?7S;1wonMU9 z{-A-Dqn4}=*|m`R$A`S`MEw^T%T-pH$Oq&>VW_<&uUMCE?7Y8Vn&8KK%oHovZS3Lx fmm$Il%^Zo`-L#Ry^e1a)?k$a+%~lvLfuT$lQzp{=6ccj>WXRd_wPMo;`DQb|)Ew{sL*87HrV#xE`SDVM) z%->nx3v^zX(B}g{CtO2G88~mB0RRPuPXfT{y&#|y^nVcQgx?lWf5rsMt4NtCH#e%Z z09P+70ka1KN4CEb!PDt5y6y#8k-ZcZaA&YC%e z`4gsxYC3o0nu{1?>OinH_Sj;#j=FB>=<8aud$^s2KGjYc1s9b=uR|(k`nIrs^4<;? zJyK+(p`RFnhZt=X4aHJU9!G!YwHb;a!)gcEN%sRTQp+Usly_OS6NB!2=xzeNx?H15 zAkeB>k(%iG)=Kb3xZHX|d#5OIEC8O6F|2FX;|-&bUJVxfawkolMaiv^rPv|WRG|c( z<<8YT>BVDpHkPe*DhHMf&!AEpBUqVDiWKjmbVm-oQdxtZ70T0K5&d3Le9B#1^|-ZP z18gBVw)VqoVaQnv4F_r7Y8SZg4}Susxn2i3&~0q^N8bC~+OaJkQRs|EnZ!4=`je_( z2^WVp_BG4&2{)grtK3>u?m8Gm4!0ocwtsx#O&=vq$Fx0a7k^uKzSiPG7^^?a_Ozx& zzp9A4Sn=xC_^dK~^qG?k85*A{$hSPIS-L%z}G;$V1w_4@NnxnqgTiv=EGAFP%Grr_fXVl?&3q#OJ zNcn5(C%-nIeld&PXYhHSBh~WN`>qb4MdYk3HlJDUG_~m|A#zPOiB|gl*_J~vQK zl*au0WAuuZMoW+zD`csACP9draHPb*bkD1RDZ>KR2kstcJe_-EUhKYV|N zDEK;4U@JU;(5wxLYX3fUEWLC8FGPqH936~TB63;mY zN*Zsdn1z}v#@zp<hxpqJHb~DCXqhw-!E0ynLU*vD*A0c5nk9?h zdJnEM^;o^68;`MJI|m`ys26y1Niq{t9G8l3R~@Ln>!}&1)kZX3?Em`uz2u*~mwNAN z2a==1oz!kL<_Mg#AD*J8^brWjPMk$7n<6>n9q}z-UB)n>J^!?M==wQgvjPTk1;5tw zUu=GqCD^s@xA}<{f}%aTd3kujR&B?6RqI@=$ykwWJYwDf-F<7;@$llt6MzPcDD=(-Y6F=`$}prlJegv!&zdU#rF(r z*Ru}Y$4=P+fHUYYkfE-; i7YND*l>WyRZ~Xs#U}cf@;y4t(vuW%?L4Sr>a%8S8bv-sznfce9<3{Ki=brcOJ@3Bv?)lt%&i%YZV?$jgFfSMY05Iw6X+Hu0sNPU?M-Uxl zt{8F-rYuzck91*x>hJs;6obYerf&+Oj4+U60_D)0zP6?*B6oYv#h-5?oQ~*%FA9zX z_+dbL~nxc{NWc_7}zYQ{4Iv5Yc0x;Sa6kQ2@PXAHnf0q*+u4x zmf6JQhX7UEnd@^m0+bG|99^aFxxIf^JtfJn2?~Z_e5lczzb!*XpFrN2bd0|IF~a!c z(@j(pAL$m<%<0YwEa`ujYQ!xVu*uy^GdLigCl$@x1K1Ej z1~DLmup>^ak70NzExc4uDP=OpL6iclZo>CMtS|cjIw$zGKjO|Jg5FW zaw|8VfQ}?rEPgANmAVDXpPoMNAR<^Z6^w8Nad13K&?!c=e|iz>&%&#mo^KuZii0VX z8dyT_T4@1Tg;(@AJWNVX5@sb{T_kCZ$h9JIktfT1>!tP5;L|XC3Ys=3pTYNcQN>YHBZjmt58JA}R%cb(kxf(@s zc?A3N3c~vgZ;UletNqIfrUrOo+^6n1mz7J)s?zE_bZA=|U^^1-Em8r;kba>!yj56#`i?dRraE8kJUOnEBI zwvuTt{$#W_lvcZAFw4WejNC$eI)%nPzi~<>!)_9j&`KdyY~x^-YWPI( zs$gPaBC}25OhGLluc;(ABgyP<2gKeEHFX6HAj{cn^!Fu0YLW;WY$2`F>hu||ZU z_)sYzfL(wi4J9lDEmph$uWrLbsdBr`Rhf0;ji*90FGF3xq1bK~af&cVb{)F6Xthq5+ZO zMg>b#HTaunbbqL-4uIIFZTr(L3pG*aGa=Ey^E47)PAJM;ZNYwVy*YW#nyg8`mh$gX z<(afbbKYtuBEC3~h3Iw&#@Q(3Fx{<=u&MV7Z9z50F}prlVVMHc8MSSTZ_O-3MB~+4 z&`}qb-;VVVyIfYHDIXXtGG@#+fOUg4cw5s8)V03;$n)KqZL7OC1y*-0%=cU`?)Zvn z1U;&Z>&EgDq65^AqXLvh-kkkANMIx)RRe#M-LPS8$vEC(32|1sueWuw;4+oDc_D^l_u#D zc(^`Z{nFeJcX_&^+*K$Y^yqp|(Zi?h$2_y%cjX>*uax6!Tf-E4W=+QK>6d1EXlB9- zEAgpEf6+g_;R&sq`vlOp{BffR`Ade5o-WxdSeZXFD_^-mb^1zg#05#n%7z}$v*P2s zeb5(|q%gc^^LjIxusI<}S|S-w1g@Vh{oyX&3=D+!Y#qHfy;1no``gM(rtY2~Q3_}f z+qnz&NgwN3Tqp|}wyocGs$fyyC^|*G5#Aa*w#|w4`8n*jbxlyJ-D8{P3nja`dE7qh zvcLSWrShg$Pi*>fO8ds`_7Satzs=gS0hQC$=HGUWIZMm%#i!#rSaky7_+!pVf5b_s z0i9Y>E>AT-$wz%bl}iv^WU4$uC7fq3)aTaErI%r1Dt^Cs@8*EEXyTVIN7>BoJXIbZ zlT&WnJxW=rGkt4t0}n;_i#?O3Id8}zX~Oe1C))Cf4P1gd#(f5wm2uBWvfT?m2*4l_ zRQ4ug*&5f=4ALe98~JP(+RQ>~+&&6{QPR)|C#Qc(A8kw)K=YEbg}*8&Whcx2Y!L#M z3|;S{u6ot4KvKRt?Gf|C5d<+zH)nGmWpY=Wc>R<6(tI0$G@zPkf0nM|h3v8S*NK zlL}`mMSl08+}EkpVz%;;BAj6JYaG|u^)t&Dx~1*2uPHP(5M3`AE)EHoomCTz=>hvf zrie#dWk{KI?`pDq_ar5qo|GEzWdr!#94=Uxo$kW7e_bBRu^mM%t2OnbhSQwunVn@O zJW$VoJ`1?UlJw$+hQ>Nd(H3^%uvah`QC4E(9|arS@CF3Z9m5K)wrMlvN%?Z(T!UX5 z7;(vLv3Fl;{%#1y+qP=UO~=3DO3F0hk5WD^GNg3&p~{`LQ|Vgu zfvq#42w2_8#=~2&Fsg-1ME@sZq;~vCmBqI8{F$qzfPlMa?54^`Zzv5gYLMYfSY>>C zoDvWnU~+EG%K#yPrf$c_&pqAIyL%~8KEjYOlo%VU(`u6t;adRzyzEl&q4#f9{Z^9* zsu@LEjty_fUF^m~Pd3Lhh-d1pZN@j!`WC{;w7tuF%){o>le3tlb@Dq{p{rXa>c5`@ zNtjyi(iyFIaVHU)?}kY$v)FoK2o524NfQkOrlq~J#d%*I$W%XVi}806k39c(_3|*I z-8|h)iFoGI_F`hIx93FB+}!*QG}!hOfu0)*tVL2-2R+C_{m}0quZSEbs6LC0=9{Py z$cf(DIR^`>Wvd50s_lY>u>sG|YiHCiRxG44_7<0}8tf1v?pK<^L{qdKBdT@lM(4>O z-FQVGPw(Z0i*xnqC*2P(Fiukf%=G-sx(_asSc}R^*GOkM%K4juo|^}wf|!W))Apcd z(5a$5X-AzAN9L%s=SEzH(?X%wDSdv`FJv}?2x8nr%ovVRQt{F!y%vj&b*Ka7xJM5K zPTFT1y0F@YMPun%QU*Q;TYmtyw6t&w2y~vF#yRB;kC~c%d`u3iiQ{)BtYzo_oC8yM zOk8~2d(2#nZMIe{3_K z!s$g&5;_V&Gl&pxU;Z)rA;(lzYGwczM#3gYvOI>@VjvDx#`5(k^KV>w_eD1Uq-?ZPXbzLvyo z)wwlo(@CL*m|*UP4o87d_9HAYs6D6A^sF}4S=pLS zK7nf3{~eC)M#GMk5n3;YOa+RQVi%smq1GVzD5~KV(*?yCS@5lT0E(n)#~T=i zuF&G7#RStRT#9kF9C;+AeBl-@k8~h)36dcVi*lb2J=UihA?%w{Xz*W}y~xj*h9@iD zqBtcKHQTY+MyZC;!tXF#Z3Gv8298Jo;UT-15Ux*eMc;#$+AN2 z5L*VY_Bzf5j2|f8QNY9&W@~B)s`xJP6A+Gt8JgQ22fjzgy-*;Kzzg$h26oY}S0<1) z*{l}swe1a(3%k4n8}fV+YL3$=!G?0vQe?*W*8F(byR7C2URmu0hs&oF3O>GInJNwc zqH1|cJU~F(lV^Ek^SdhEx-OF0g5V9o+?>bQovvlL)l^k&r;i8Z!T$4jJ7$ZU=yufk zX?aa$$eg$vC=S%LF1MMC&BcI3Yrru^#cj2;n*|B*b&?ziYW38p$RnSbG!~ zEf=ZlA^O8;WE|9ujngyq=5}wY?5CCXi3|1 z&3YoE{Zq2!6I$BuSovW_i=X&V1*(mMFX6R|Kqieb>L79y%~^QzfTIaZ{H~lL_YL%l zJz?;1^seB!%(_cbO7a(#x+1`fV0Bl=> zS)8e%T()kT1>|u(5}8(-0pdbo*Ecr4x^0)8QPymul|syAlr@i;9&K<($E=6X1@2s& z_n!QIz1`?0)F;nCt~@0#ac1SC9k9L%XwUR{gEAd8iM-o4m|b`2%|uOLGTY2qcIxAi z!|Q3EDAHNfiWSAZXeermpTP zKNx%l4u{}wSDJ)|s)+C=#n5YNR76glGQv?kXf^joTH**d0s?4|^pY5PXWvCGG3mf5 z>$|r}14frpb;y6Oe&K>~SlH!!EOvT!_UYiDot(V9LHPlr#qsIWr|Pj==hM>Cdg*jQ zj0p$Ealb@5Dy26Izj}&$MSta`l0vY8=j0HPhcbL?d%c{4j$pi zdwY8sg@x%G8=+o4KAv7)$6$}vp6p&b2Et%4zW)B#{QMOA`}?aNA3h`?QwV*(SRX!o zfCoiIMNvj4eUp-sgp*U`iLU9grqA8!EpYVtH=?x|`WPQeXXMbPz@@3)T;$ksz zaW)XM&~|@11-90H%I#%66>)`~gQIU^0y8w^0Qy>LkrzDQEiR{^Kyrr{m6VX0k#=_3 zHUvsula<*(n>yFbjA(MVVRWY@HXVn@OA1TnF8%tIiN&HxDS~&C$i50zuk~GA3VK$? z-qzHdAdyJ(D}DoIUBD%4YinOj)&nZb4olrtp&^UCXCCdZ)c5{k_5KW3kK0pq7m_Hc z6nMA68g|1Xt<226w#4mc6ck{HvD-2#D*Xq}fDJ(U?+2WyHSVqK#gQZL1S?D*9#(JyzYvE(F2UjP6f+M>N1>|ruF+{U#n^c5!_9%U^<9Rp{lbqz?$u^kXlQ7+r!)@_ zkD0YKw+W}2qvK1LqufsoQf-V7$V59Q?;izQ92Ia+)?kqXPCiD`!lXn9_IPLdCG<2D zYGY#)-`Z;6Oo#*neqLj-j6FQw`d|LU&d%DgM$MELL!m4 zuW&K`njsEQNJxldQ@G;N(h@{elnd{GPS^V*CMhXtQ*LKwVL|%W9@o8p*R?b;DTzjn zESgGD_+QI|GderXy4c%7tL&5tLQoKJn8$zZ%ZtWCgEsKIbWZUb8@8;Jvk)o5l!bU_clxdcn}%{v==! z5Qw?(gZx}l3j%?-*H+#qZbcfWwQP5Vj3hB;HlHS&FJBp2qT=Ln21}d>z>eg`umyk3 zj^W|k{m}FBXU}@{A|xb)!eAt~Z?#;Q znVFGuQ&&*IQB=*&<>Bwv&&>B=9cBd^1_C~N_do}Shp~j*gM)*QO#$!VeU8cZ;}=;E zaRGW?-1Lg0!o#P&KH-=T$P6iny%bR`FDK_%8_+*75x|P=F3=jT*cxp-F~I=UitrDEI~i1!=PeZ<$$HJD%k(d>^78VUZm-K!-#ciP ze8$L);NYr>6&iC=fjo5*g&uHid=7r_HYq(lE$!QbN@6mAV%B?Yc-!)|j?+Qz)8CT5 ztxRGJi>v(h{46c`rQ$YkIw8aZ)@RyLXfz1`%Xlppv!0%w8u}69?U%nL#@gDNUr=zi zEme44-08t^1?TEVa93w%MkxjHd7%*br(#=?kB^U3b^}{PMFjWUdp* zU%TYD{xWJT*YQnuN^)}W>bS=8Xf5CGmi>y|fo9wCHsDbiIXUvNIwb%APY;&g>ZDLe z-wU+xT+ADj$fG!*s?YWo8>v6s{NS=ey%I5n7{Hh>n}2UpKCc!$4ZEGl-G8B+iukLv zv9Zz9+XwGh%|2Ea5Y~y|2Ur8(qqNwH;B6MG9euIopD~%n)ScbkGcq#lw=104;>}$e zX%rQG6YCJy8ZRE*y+v8tg9a>6y_r9VMB?JgO6?tY1YGQ+sL-DS=8wqQsIqq*6|-HJ zv^l=PV#jF4y%SWm2Cyf>}rFpJ~*RS&e(IsEL?Fs-~ zMs{}M;-W85S&b@(XNT~2=NGO(!N8mXkP6!LcDo9XfPe{5usl3HGxPJ6_UV{bcm10; zGpU{i1_qto-JfHP>qQb05^NkCxBw19h9M;c^$x12Oera;2Ee2Msp153$A7Hu#*VJz zo&iT>^S;`+RPZ?XocXiAv^FNF%qVN8UhnKWPWOFPaq$^1FR!m;GB*IMsPuGGOUq}Z z$`vJc5Gr4c>Vy*Nq__h=U3%N#PL5))!Uc9d))j7uMKeqk81xpBp{X>uLkv@jUhwD$hwbc_!%5cd?q{5Sa)TFFCH14|puh;a z$u8sUqqt(|$tznEr_s*B9Em7YVz8*_e_wO;|9ZV$q|XV0{_cIFF`!)qnHyVOt1xs= F_#c>+Bm@8e literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_dark.png b/packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..845ea2d8d9e310b611d61062d9b01730476c80e0 GIT binary patch literal 3701 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 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_light.png b/packages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_light.png new file mode 100644 index 0000000000000000000000000000000000000000..1a134c74f97e0c0c278d1926aacbe74bfd4af87b GIT binary patch literal 3861 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 VpdRWgz||IHr1$9FXC23={{me3Ay5DS literal 0 HcmV?d00001 diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_icon_list_test.dart b/packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart similarity index 92% rename from packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_icon_list_test.dart rename to packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart index 511fc1b858..4dbb51949a 100644 --- a/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_icon_list_test.dart +++ b/packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart @@ -1,7 +1,6 @@ import 'package:alchemist/alchemist.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reaction_picker_icon_list.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; void main() { @@ -55,9 +54,12 @@ void main() { await tester.pumpWidget( _wrapWithMaterialApp( ReactionIconButton( - icon: reactionIcons.first, - isSelected: true, - onPressed: () {}, + icon: ReactionPickerIcon( + isSelected: true, + type: reactionIcons.first.type, + builder: reactionIcons.first.builder, + ), + onPressed: (type) {}, ), ), ); @@ -75,9 +77,11 @@ void main() { await tester.pumpWidget( _wrapWithMaterialApp( ReactionIconButton( - icon: reactionIcons.first, - isSelected: false, - onPressed: () { + icon: ReactionPickerIcon( + type: reactionIcons.first.type, + builder: reactionIcons.first.builder, + ), + onPressed: (type) { callbackTriggered = true; }, ), @@ -102,9 +106,11 @@ void main() { builder: () => _wrapWithMaterialApp( brightness: brightness, ReactionIconButton( - icon: reactionIcons.first, - isSelected: false, - onPressed: () {}, + icon: ReactionPickerIcon( + type: reactionIcons.first.type, + builder: reactionIcons.first.builder, + ), + onPressed: (type) {}, ), ), ); @@ -116,9 +122,12 @@ void main() { builder: () => _wrapWithMaterialApp( brightness: brightness, ReactionIconButton( - icon: reactionIcons.first, - isSelected: true, - onPressed: () {}, + icon: ReactionPickerIcon( + isSelected: true, + type: reactionIcons.first.type, + builder: reactionIcons.first.builder, + ), + onPressed: (type) {}, ), ), ); @@ -373,7 +382,7 @@ Widget _wrapWithMaterialApp( child: Builder(builder: (context) { final theme = StreamChatTheme.of(context); return Scaffold( - backgroundColor: theme.colorTheme.appBg, + backgroundColor: theme.colorTheme.overlay, body: Center( child: Padding( padding: const EdgeInsets.all(8), diff --git a/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_test.dart b/packages/stream_chat_flutter/test/src/reactions/reaction_picker_test.dart similarity index 97% rename from packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_test.dart rename to packages/stream_chat_flutter/test/src/reactions/reaction_picker_test.dart index 8447b10396..3b80f884e4 100644 --- a/packages/stream_chat_flutter/test/src/message_widget/reactions/reaction_picker_test.dart +++ b/packages/stream_chat_flutter/test/src/reactions/reaction_picker_test.dart @@ -1,7 +1,6 @@ import 'package:alchemist/alchemist.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:stream_chat_flutter/src/message_widget/reactions/reaction_picker_icon_list.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; void main() { @@ -184,7 +183,7 @@ Widget _wrapWithMaterialApp( child: Builder(builder: (context) { final theme = StreamChatTheme.of(context); return Scaffold( - backgroundColor: theme.colorTheme.appBg, + backgroundColor: theme.colorTheme.overlay, body: Center( child: Padding( padding: const EdgeInsets.all(8), diff --git a/sample_app/lib/app.dart b/sample_app/lib/app.dart index 5e72b30825..731d3b4d9b 100644 --- a/sample_app/lib/app.dart +++ b/sample_app/lib/app.dart @@ -434,6 +434,8 @@ class _StreamChatSampleAppState extends State final GlobalKey _navigatorKey = GlobalKey(); LocalNotificationObserver? localNotificationObserver; + GoRouter? router; + /// Conditionally sets up the router and adding an observer for the /// current chat client. GoRouter _setupRouter() { @@ -443,7 +445,7 @@ class _StreamChatSampleAppState extends State localNotificationObserver = LocalNotificationObserver( _initNotifier.initData!.client, _navigatorKey); - return GoRouter( + return router ??= GoRouter( refreshListenable: _initNotifier, initialLocation: Routes.CHANNEL_LIST_PAGE.path, navigatorKey: _navigatorKey, From eb9d91c262b5fae0f71fbc5e1eba64d0373fc188 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Tue, 17 Jun 2025 16:01:15 +0200 Subject: [PATCH 04/34] refactor(ui)!: improve reaction bubble implementation (#2277) Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com> --- .../lib/src/core/models/reaction_group.dart | 23 ++ packages/stream_chat_flutter/CHANGELOG.md | 1 + .../message_modal/message_actions_modal.dart | 62 +-- .../message_reactions_modal.dart | 66 +--- .../lib/src/message_widget/message_card.dart | 6 +- .../src/message_widget/message_widget.dart | 149 ++++--- .../message_widget_content.dart | 225 +++++------ .../misc/flexible_fractionally_sized_box.dart | 91 +++++ .../lib/src/misc/size_change_listener.dart | 42 ++ .../indicator/reaction_indicator.dart | 107 +++++ .../reaction_indicator_bubble_overlay.dart | 74 ++++ .../reaction_indicator_icon_list.dart | 91 +++++ .../src/reactions/picker/reaction_picker.dart | 12 +- .../reaction_picker_bubble_overlay.dart | 75 ++++ .../picker/reaction_picker_icon_list.dart | 42 +- .../reactions/reaction_bubble_overlay.dart | 373 ++++++++++++++++++ .../lib/src/reactions/reaction_indicator.dart | 73 ---- .../lib/src/reactions/reactions_align.dart | 64 --- .../lib/src/reactions/user_reactions.dart | 53 ++- .../lib/src/theme/stream_chat_theme.dart | 4 +- .../lib/stream_chat_flutter.dart | 1 - .../ci/stream_message_actions_modal_dark.png | Bin 5029 -> 4965 bytes .../ci/stream_message_actions_modal_light.png | Bin 5199 -> 5220 bytes ...am_message_actions_modal_reversed_dark.png | Bin 5109 -> 5159 bytes ...m_message_actions_modal_reversed_light.png | Bin 5363 -> 5344 bytes ...ons_modal_reversed_with_reactions_dark.png | Bin 8389 -> 8601 bytes ...ns_modal_reversed_with_reactions_light.png | Bin 8934 -> 9431 bytes ...sage_actions_modal_with_reactions_dark.png | Bin 8276 -> 8330 bytes ...age_actions_modal_with_reactions_light.png | Bin 8771 -> 9171 bytes .../stream_message_reactions_modal_dark.png | Bin 12163 -> 12157 bytes .../stream_message_reactions_modal_light.png | Bin 12993 -> 13384 bytes ..._message_reactions_modal_reversed_dark.png | Bin 12111 -> 12239 bytes ...message_reactions_modal_reversed_light.png | Bin 13017 -> 13372 bytes .../message_actions_modal_test.dart | 66 ++-- .../message_reactions_modal_test.dart | 74 ++-- .../reaction_picker_icon_list_test.dart | 8 +- 36 files changed, 1227 insertions(+), 555 deletions(-) create mode 100644 packages/stream_chat_flutter/lib/src/misc/flexible_fractionally_sized_box.dart create mode 100644 packages/stream_chat_flutter/lib/src/misc/size_change_listener.dart create mode 100644 packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator.dart create mode 100644 packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_bubble_overlay.dart create mode 100644 packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_icon_list.dart create mode 100644 packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart create mode 100644 packages/stream_chat_flutter/lib/src/reactions/reaction_bubble_overlay.dart delete mode 100644 packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart delete mode 100644 packages/stream_chat_flutter/lib/src/reactions/reactions_align.dart diff --git a/packages/stream_chat/lib/src/core/models/reaction_group.dart b/packages/stream_chat/lib/src/core/models/reaction_group.dart index 4410500acf..480156de42 100644 --- a/packages/stream_chat/lib/src/core/models/reaction_group.dart +++ b/packages/stream_chat/lib/src/core/models/reaction_group.dart @@ -57,3 +57,26 @@ class ReactionGroup extends Equatable { lastReactionAt, ]; } + +/// A group of comparators for sorting [ReactionGroup]s. +final class ReactionSorting { + /// Sorts [ReactionGroup]s by the sum of their scores. + static int byScore(ReactionGroup a, ReactionGroup b) { + return a.sumScores.compareTo(b.sumScores); + } + + /// Sorts [ReactionGroup]s by the count of reactions. + static int byCount(ReactionGroup a, ReactionGroup b) { + return a.count.compareTo(b.count); + } + + /// Sorts [ReactionGroup]s by the date of their first reaction. + static int byFirstReactionAt(ReactionGroup a, ReactionGroup b) { + return a.firstReactionAt.compareTo(b.firstReactionAt); + } + + /// Sorts [ReactionGroup]s by the date of their last reaction. + static int byLastReactionAt(ReactionGroup a, ReactionGroup b) { + return a.lastReactionAt.compareTo(b.lastReactionAt); + } +} diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 0000c0e34d..5cb08edf0c 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -5,6 +5,7 @@ - `StreamReactionPicker` now requires reactions to be explicitly handled via `onReactionPicked`. *(Automatic handling is no longer supported.)* - `StreamMessageAction` is now generic `(StreamMessageAction)`, enhancing type safety. Individual onTap callbacks have been removed; actions are now handled centrally by widgets like `StreamMessageWidget.onCustomActionTap` or modals using action types. - `StreamMessageReactionsModal` no longer requires the `messageTheme` parameter. The theme now automatically derives from the `reverse` property. +- `StreamMessageWidget` no longer requires the `showReactionTail` parameter. The reaction picker tail is now always shown when the reaction picker is visible. For more details, please refer to the [migration guide](Unpublished). diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart index 5168626eda..e98c74fd25 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/reactions/reactions_align.dart'; +import 'package:stream_chat_flutter/src/reactions/picker/reaction_picker_bubble_overlay.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -71,56 +71,30 @@ class StreamMessageActionsModal extends StatelessWidget { Widget build(BuildContext context) { final theme = StreamChatTheme.of(context); - final Widget? reactionPicker = switch (showReactionPicker) { - false => null, - true => LayoutBuilder( - builder: (context, constraints) { - final orientation = MediaQuery.of(context).orientation; - final messageTheme = theme.getMessageTheme(reverse: reverse); - final messageFontSize = messageTheme.messageTextStyle?.fontSize; - - final alignment = message.calculateReactionPickerAlignment( - constraints: constraints, - fontSize: messageFontSize, - orientation: orientation, - reverse: reverse, - ); - - final onReactionPicked = switch (onActionTap) { - null => null, - final onActionTap => (reaction) { - return onActionTap.call( - SelectReaction(message: message, reaction: reaction), - ); - }, - }; - - return Align( - alignment: alignment, - child: reactionPickerBuilder(context, message, onReactionPicked), - ); - }, - ), - }; - final alignment = switch (reverse) { true => AlignmentDirectional.centerEnd, false => AlignmentDirectional.centerStart, }; + final onReactionPicked = switch (onActionTap) { + null => null, + final onActionTap => (reaction) => onActionTap( + SelectReaction(message: message, reaction: reaction), + ), + }; + return StreamMessageModal( + spacing: 4, alignment: alignment, - headerBuilder: (context) { - return Column( - spacing: 10, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: alignment.toColumnCrossAxisAlignment(), - children: [ - reactionPicker, - IgnorePointer(child: messageWidget), - ].nonNulls.toList(growable: false), - ); - }, + headerBuilder: (context) => ReactionPickerBubbleOverlay( + message: message, + reverse: reverse, + visible: showReactionPicker, + anchorOffset: const Offset(0, -8), + onReactionPicked: onReactionPicked, + reactionPickerBuilder: reactionPickerBuilder, + child: IgnorePointer(child: messageWidget), + ), contentBuilder: (context) { final actions = Column( mainAxisSize: MainAxisSize.min, diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart index 70278f3dcb..8cdb697282 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; -import 'package:stream_chat_flutter/src/reactions/reactions_align.dart'; +import 'package:stream_chat_flutter/src/reactions/picker/reaction_picker_bubble_overlay.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@template streamMessageReactionsModal} @@ -64,58 +64,32 @@ class StreamMessageReactionsModal extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = StreamChatTheme.of(context); - final messageTheme = theme.getMessageTheme(reverse: reverse); - - final Widget? reactionPicker = switch (showReactionPicker) { - false => null, - true => LayoutBuilder( - builder: (context, constraints) { - final orientation = MediaQuery.of(context).orientation; - final messageFontSize = messageTheme.messageTextStyle?.fontSize; - - final alignment = message.calculateReactionPickerAlignment( - constraints: constraints, - fontSize: messageFontSize, - orientation: orientation, - reverse: reverse, - ); - - final onReactionPicked = switch (this.onReactionPicked) { - null => null, - final onPicked => (reaction) { - return onPicked.call( - SelectReaction(message: message, reaction: reaction), - ); - }, - }; - - return Align( - alignment: alignment, - child: reactionPickerBuilder(context, message, onReactionPicked), - ); - }, - ), - }; - final alignment = switch (reverse) { true => AlignmentDirectional.centerEnd, false => AlignmentDirectional.centerStart, }; + final onReactionPicked = switch (this.onReactionPicked) { + null => null, + final onPicked => (reaction) { + return onPicked.call( + SelectReaction(message: message, reaction: reaction), + ); + }, + }; + return StreamMessageModal( + spacing: 4, alignment: alignment, - headerBuilder: (context) { - return Column( - spacing: 10, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: alignment.toColumnCrossAxisAlignment(), - children: [ - reactionPicker, - IgnorePointer(child: messageWidget), - ].nonNulls.toList(growable: false), - ); - }, + headerBuilder: (context) => ReactionPickerBubbleOverlay( + message: message, + reverse: reverse, + visible: showReactionPicker, + anchorOffset: const Offset(0, -8), + onReactionPicked: onReactionPicked, + reactionPickerBuilder: reactionPickerBuilder, + child: IgnorePointer(child: messageWidget), + ), contentBuilder: (context) { final reactions = message.latestReactions; final hasReactions = reactions != null && reactions.isNotEmpty; diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart index 62ebaada6d..b60db28f10 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart @@ -164,9 +164,9 @@ class _MessageCardState extends State { return Container( constraints: const BoxConstraints().copyWith(maxWidth: widthLimit), - margin: EdgeInsets.symmetric( - horizontal: (widget.isFailedState ? 12.0 : 0.0) + - (widget.showUserAvatar == DisplayWidget.gone ? 0 : 4.0), + margin: EdgeInsetsDirectional.only( + end: widget.reverse && widget.isFailedState ? 12.0 : 0.0, + start: !widget.reverse && widget.isFailedState ? 12.0 : 0.0, ), clipBehavior: Clip.hardEdge, decoration: ShapeDecoration( diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index 7cc3320187..a5408c404a 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -6,6 +6,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart'; import 'package:stream_chat_flutter/src/message_widget/message_widget_content.dart'; +import 'package:stream_chat_flutter/src/misc/flexible_fractionally_sized_box.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// The display behaviour of a widget @@ -51,7 +52,6 @@ class StreamMessageWidget extends StatefulWidget { this.onReactionsTap, this.onReactionsHover, this.showReactionPicker = true, - this.showReactionTail, this.showUserAvatar = DisplayWidget.show, this.showSendingIndicator = true, this.showThreadReplyIndicator = false, @@ -258,12 +258,6 @@ class StreamMessageWidget extends StatefulWidget { /// {@endtemplate} final bool showReactionPicker; - /// {@template showReactionPickerTail} - /// Whether or not to show the reaction picker tail. - /// This is calculated internally in most cases and does not need to be set. - /// {@endtemplate} - final bool? showReactionTail; - /// {@template onShowMessage} /// Callback when show message is tapped /// {@endtemplate} @@ -438,7 +432,6 @@ class StreamMessageWidget extends StatefulWidget { void Function(String)? onLinkTap, bool? showReactionBrowser, bool? showReactionPicker, - bool? showReactionTail, List? readList, ShowMessageCallback? onShowMessage, bool? showUsername, @@ -508,7 +501,6 @@ class StreamMessageWidget extends StatefulWidget { onUserAvatarTap: onUserAvatarTap ?? this.onUserAvatarTap, onLinkTap: onLinkTap ?? this.onLinkTap, showReactionPicker: showReactionPicker ?? this.showReactionPicker, - showReactionTail: showReactionTail ?? this.showReactionTail, onShowMessage: onShowMessage ?? this.onShowMessage, showUsername: showUsername ?? this.showUsername, showTimestamp: showTimestamp ?? this.showTimestamp, @@ -704,76 +696,73 @@ class _StreamMessageWidgetState extends State child: MouseRegion(child: child), ); }, - child: Padding( - padding: widget.padding ?? const EdgeInsets.all(8), - child: FractionallySizedBox( - alignment: switch (widget.reverse) { - true => Alignment.centerRight, - false => Alignment.centerLeft, - }, - widthFactor: widget.widthFactor, - child: Builder(builder: (context) { - return MessageWidgetContent( - streamChatTheme: theme, - showUsername: showUsername, - showTimeStamp: showTimeStamp, - showEditedLabel: showEditedLabel, - showThreadReplyIndicator: showThreadReplyIndicator, - showSendingIndicator: showSendingIndicator, - showInChannel: showInChannel, - isGiphy: isGiphy, - isOnlyEmoji: isOnlyEmoji, - hasUrlAttachments: hasUrlAttachments, - messageTheme: widget.messageTheme, - reverse: widget.reverse, - message: widget.message, - hasNonUrlAttachments: hasNonUrlAttachments, - hasPoll: hasPoll, - hasQuotedMessage: hasQuotedMessage, - textPadding: widget.textPadding, - attachmentBuilders: widget.attachmentBuilders, - attachmentPadding: widget.attachmentPadding, - attachmentShape: widget.attachmentShape, - onAttachmentTap: widget.onAttachmentTap, - onReplyTap: widget.onReplyTap, - onThreadTap: widget.onThreadTap, - onShowMessage: widget.onShowMessage, - attachmentActionsModalBuilder: - widget.attachmentActionsModalBuilder, - avatarWidth: avatarWidth, - bottomRowPadding: bottomRowPadding, - isFailedState: isFailedState, - isPinned: isPinned, - messageWidget: widget, - showBottomRow: showBottomRow, - showPinHighlight: widget.showPinHighlight, - showReactionPickerTail: widget.showReactionTail == true, - showReactions: shouldShowReactions, - onReactionsTap: () { - final message = widget.message; - return switch (widget.onReactionsTap) { - final onReactionsTap? => onReactionsTap(message), - _ => _showMessageReactionsModal(context, message), - }; - }, - onReactionsHover: widget.onReactionsHover, - showUserAvatar: widget.showUserAvatar, - streamChat: streamChat, - translateUserAvatar: widget.translateUserAvatar, - shape: widget.shape, - borderSide: widget.borderSide, - borderRadiusGeometry: widget.borderRadiusGeometry, - textBuilder: widget.textBuilder, - quotedMessageBuilder: widget.quotedMessageBuilder, - onLinkTap: widget.onLinkTap, - onMentionTap: widget.onMentionTap, - onQuotedMessageTap: widget.onQuotedMessageTap, - bottomRowBuilderWithDefaultWidget: - widget.bottomRowBuilderWithDefaultWidget, - onUserAvatarTap: widget.onUserAvatarTap, - userAvatarBuilder: widget.userAvatarBuilder, - ); - }), + child: FlexibleFractionallySizedBox( + widthFactor: widget.widthFactor, + alignment: switch (widget.reverse) { + true => AlignmentDirectional.centerEnd, + false => AlignmentDirectional.centerStart, + }, + child: Padding( + padding: widget.padding ?? const EdgeInsets.all(8), + child: MessageWidgetContent( + streamChatTheme: theme, + showUsername: showUsername, + showTimeStamp: showTimeStamp, + showEditedLabel: showEditedLabel, + showThreadReplyIndicator: showThreadReplyIndicator, + showSendingIndicator: showSendingIndicator, + showInChannel: showInChannel, + isGiphy: isGiphy, + isOnlyEmoji: isOnlyEmoji, + hasUrlAttachments: hasUrlAttachments, + messageTheme: widget.messageTheme, + reverse: widget.reverse, + message: widget.message, + hasNonUrlAttachments: hasNonUrlAttachments, + hasPoll: hasPoll, + hasQuotedMessage: hasQuotedMessage, + textPadding: widget.textPadding, + attachmentBuilders: widget.attachmentBuilders, + attachmentPadding: widget.attachmentPadding, + attachmentShape: widget.attachmentShape, + onAttachmentTap: widget.onAttachmentTap, + onReplyTap: widget.onReplyTap, + onThreadTap: widget.onThreadTap, + onShowMessage: widget.onShowMessage, + attachmentActionsModalBuilder: + widget.attachmentActionsModalBuilder, + avatarWidth: avatarWidth, + bottomRowPadding: bottomRowPadding, + isFailedState: isFailedState, + isPinned: isPinned, + messageWidget: widget, + showBottomRow: showBottomRow, + showPinHighlight: widget.showPinHighlight, + showReactions: shouldShowReactions, + onReactionsTap: () { + final message = widget.message; + return switch (widget.onReactionsTap) { + final onReactionsTap? => onReactionsTap(message), + _ => _showMessageReactionsModal(context, message), + }; + }, + onReactionsHover: widget.onReactionsHover, + showUserAvatar: widget.showUserAvatar, + streamChat: streamChat, + translateUserAvatar: widget.translateUserAvatar, + shape: widget.shape, + borderSide: widget.borderSide, + borderRadiusGeometry: widget.borderRadiusGeometry, + textBuilder: widget.textBuilder, + quotedMessageBuilder: widget.quotedMessageBuilder, + onLinkTap: widget.onLinkTap, + onMentionTap: widget.onMentionTap, + onQuotedMessageTap: widget.onQuotedMessageTap, + bottomRowBuilderWithDefaultWidget: + widget.bottomRowBuilderWithDefaultWidget, + onUserAvatarTap: widget.onUserAvatarTap, + userAvatarBuilder: widget.userAvatarBuilder, + ), ), ), ), @@ -936,7 +925,6 @@ class _StreamMessageWidgetState extends State showSendingIndicator: false, padding: EdgeInsets.zero, showPinHighlight: false, - showReactionTail: showPicker, showUserAvatar: switch (widget.reverse) { true => DisplayWidget.gone, false => DisplayWidget.show, @@ -1055,7 +1043,6 @@ class _StreamMessageWidgetState extends State showSendingIndicator: false, padding: EdgeInsets.zero, showPinHighlight: false, - showReactionTail: showPicker, showUserAvatar: switch (widget.reverse) { true => DisplayWidget.gone, false => DisplayWidget.show, diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart index 41a46982d7..dbf9b99ba6 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_portal/flutter_portal.dart'; import 'package:meta/meta.dart'; import 'package:stream_chat_flutter/src/reactions/desktop_reactions_builder.dart'; +import 'package:stream_chat_flutter/src/reactions/indicator/reaction_indicator_bubble_overlay.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Signature for the builder function that will be called when the message @@ -53,7 +53,6 @@ class MessageWidgetContent extends StatelessWidget { required this.onReplyTap, required this.attachmentActionsModalBuilder, required this.textPadding, - required this.showReactionPickerTail, required this.translateUserAvatar, required this.bottomRowPadding, required this.showInChannel, @@ -189,9 +188,6 @@ class MessageWidgetContent extends StatelessWidget { /// {@macro quotedMessageBuilder} final Widget Function(BuildContext, Message)? quotedMessageBuilder; - /// {@macro showReactionPickerTail} - final bool showReactionPickerTail; - /// {@macro translateUserAvatar} final bool translateUserAvatar; @@ -265,140 +261,58 @@ class MessageWidgetContent extends StatelessWidget { currentUser: streamChat.currentUser!, ), Row( - crossAxisAlignment: CrossAxisAlignment.end, + spacing: 8, mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, children: [ - if (!reverse && - showUserAvatar == DisplayWidget.show && - message.user != null) ...[ - UserAvatarTransform( - onUserAvatarTap: onUserAvatarTap, - userAvatarBuilder: userAvatarBuilder, - translateUserAvatar: translateUserAvatar, - messageTheme: messageTheme, - message: message, - ), - const SizedBox(width: 4), - ], - if (showUserAvatar == DisplayWidget.hide) - SizedBox(width: avatarWidth + 4), - Flexible( - child: PortalTarget( - visible: isMobileDevice && showReactions, - portalFollower: ReactionIndicator( - message: message, - messageTheme: messageTheme, - ownId: streamChat.currentUser!.id, + ...[ + Flexible( + child: ReactionIndicatorBubbleOverlay( reverse: reverse, + message: message, onTap: onReactionsTap, - ), - anchor: Aligned( - target: Alignment(reverse ? -1 : 1, -1), - follower: Alignment(reverse ? 1 : -1, 1), - offset: Offset(reverse ? 12 : -12, 42), - shiftToWithinBound: const AxisFlag(x: true), - ), - child: Stack( - clipBehavior: Clip.none, - children: [ - Padding( - padding: showReactions - ? const EdgeInsets.only(top: 28) - : EdgeInsets.zero, - child: (message.isDeleted && !isFailedState) - ? Container( - margin: EdgeInsets.symmetric( - horizontal: showUserAvatar == - DisplayWidget.gone - ? 0 - : 4.0, - ), - child: StreamDeletedMessage( - borderRadiusGeometry: - borderRadiusGeometry, - borderSide: borderSide, - shape: shape, - messageTheme: messageTheme, - ), - ) - : MessageCard( - message: message, - isFailedState: isFailedState, - showUserAvatar: showUserAvatar, - messageTheme: messageTheme, - hasQuotedMessage: hasQuotedMessage, - hasUrlAttachments: hasUrlAttachments, - hasNonUrlAttachments: - hasNonUrlAttachments, - hasPoll: hasPoll, - isOnlyEmoji: isOnlyEmoji, - isGiphy: isGiphy, - attachmentBuilders: attachmentBuilders, - attachmentPadding: attachmentPadding, - attachmentShape: attachmentShape, - onAttachmentTap: onAttachmentTap, - onReplyTap: onReplyTap, - onShowMessage: onShowMessage, - attachmentActionsModalBuilder: - attachmentActionsModalBuilder, - textPadding: textPadding, - reverse: reverse, - onQuotedMessageTap: onQuotedMessageTap, - onMentionTap: onMentionTap, - onLinkTap: onLinkTap, - textBuilder: textBuilder, - quotedMessageBuilder: - quotedMessageBuilder, - borderRadiusGeometry: - borderRadiusGeometry, - borderSide: borderSide, - shape: shape, - ), - ), - // TODO: Make tail part of the Reaction Picker. - if (showReactionPickerTail) - PositionedDirectional( - end: reverse ? null : 4, - start: reverse ? 4 : null, - top: -8, - child: CustomPaint( - painter: ReactionBubblePainter( - streamChatTheme.colorTheme.barsBg, - Colors.transparent, - Colors.transparent, - tailCirclesSpace: 1, - flipTail: !reverse, - ), - ), - ), - ], + visible: isMobileDevice && showReactions, + anchorOffset: const Offset(0, 36), + childSizeDelta: switch (showUserAvatar) { + DisplayWidget.gone => Offset.zero, + // Size adjustment for the user avatar + _ => const Offset(40, 0), + }, + child: Padding( + padding: switch (showReactions) { + true => const EdgeInsets.only(top: 28), + false => EdgeInsets.zero, + }, + child: _buildMessageCard(context), + ), ), ), + ].addConditionally( + reverse: reverse, + condition: (_) => message.user != null, + switch (showUserAvatar) { + DisplayWidget.gone => null, + DisplayWidget.hide => SizedBox(width: avatarWidth), + DisplayWidget.show => UserAvatarTransform( + onUserAvatarTap: onUserAvatarTap, + userAvatarBuilder: userAvatarBuilder, + translateUserAvatar: translateUserAvatar, + messageTheme: messageTheme, + message: message, + ), + }, ), - if (reverse && - showUserAvatar == DisplayWidget.show && - message.user != null) ...[ - UserAvatarTransform( - onUserAvatarTap: onUserAvatarTap, - userAvatarBuilder: userAvatarBuilder, - translateUserAvatar: translateUserAvatar, - messageTheme: messageTheme, - message: message, - ), - const SizedBox(width: 4), - ], - if (showUserAvatar == DisplayWidget.hide) - SizedBox(width: avatarWidth + 4), ], ), if (isDesktopDeviceOrWeb && showReactions) ...[ Padding( - padding: showUserAvatar != DisplayWidget.gone - ? EdgeInsets.only( - left: avatarWidth + 4, - right: avatarWidth + 4, - ) - : EdgeInsets.zero, + padding: switch (showUserAvatar) { + DisplayWidget.gone => EdgeInsets.zero, + _ => EdgeInsets.only( + left: avatarWidth + 4, + right: avatarWidth + 4, + ) + }, child: DesktopReactionsBuilder( message: message, messageTheme: messageTheme, @@ -431,6 +345,47 @@ class MessageWidgetContent extends StatelessWidget { ); } + Widget _buildMessageCard(BuildContext context) { + if (message.isDeleted && !isFailedState) { + return StreamDeletedMessage( + borderRadiusGeometry: borderRadiusGeometry, + borderSide: borderSide, + shape: shape, + messageTheme: messageTheme, + ); + } + + return MessageCard( + message: message, + isFailedState: isFailedState, + showUserAvatar: showUserAvatar, + messageTheme: messageTheme, + hasQuotedMessage: hasQuotedMessage, + hasUrlAttachments: hasUrlAttachments, + hasNonUrlAttachments: hasNonUrlAttachments, + hasPoll: hasPoll, + isOnlyEmoji: isOnlyEmoji, + isGiphy: isGiphy, + attachmentBuilders: attachmentBuilders, + attachmentPadding: attachmentPadding, + attachmentShape: attachmentShape, + onAttachmentTap: onAttachmentTap, + onReplyTap: onReplyTap, + onShowMessage: onShowMessage, + attachmentActionsModalBuilder: attachmentActionsModalBuilder, + textPadding: textPadding, + reverse: reverse, + onQuotedMessageTap: onQuotedMessageTap, + onMentionTap: onMentionTap, + onLinkTap: onLinkTap, + textBuilder: textBuilder, + quotedMessageBuilder: quotedMessageBuilder, + borderRadiusGeometry: borderRadiusGeometry, + borderSide: borderSide, + shape: shape, + ); + } + Widget _buildBottomRow(BuildContext context) { final defaultWidget = BottomRow( onThreadTap: onThreadTap, @@ -463,3 +418,17 @@ class MessageWidgetContent extends StatelessWidget { return defaultWidget; } } + +extension on Iterable { + Iterable addConditionally( + T? item, { + required bool condition(T element), + bool reverse = false, + }) sync* { + for (final element in this) { + if (item != null && !reverse && condition(element)) yield item; + yield element; + if (item != null && reverse && condition(element)) yield item; + } + } +} diff --git a/packages/stream_chat_flutter/lib/src/misc/flexible_fractionally_sized_box.dart b/packages/stream_chat_flutter/lib/src/misc/flexible_fractionally_sized_box.dart new file mode 100644 index 0000000000..86da240000 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/misc/flexible_fractionally_sized_box.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; + +/// A widget that sizes its child to a fraction of the total available space. +class FlexibleFractionallySizedBox extends StatelessWidget { + /// Creates a widget that sizes its child to a fraction of the total available + /// space. + /// + /// If non-null, the [widthFactor] and [heightFactor] arguments must be + /// non-negative. + const FlexibleFractionallySizedBox({ + super.key, + this.alignment = Alignment.center, + this.widthFactor, + this.heightFactor, + this.child, + }) : assert(widthFactor == null || widthFactor >= 0.0, ''), + assert(heightFactor == null || heightFactor >= 0.0, ''); + + /// The widget below this widget in the tree. + /// + /// {@macro flutter.widgets.ProxyWidget.child} + final Widget? child; + + /// If non-null, the fraction of the incoming width given to the child. + /// + /// If non-null, the child is given a tight width constraint that is the max + /// incoming width constraint multiplied by this factor. + /// + /// If null, the incoming width constraints are passed to the child + /// unmodified. + final double? widthFactor; + + /// If non-null, the fraction of the incoming height given to the child. + /// + /// If non-null, the child is given a tight height constraint that is the max + /// incoming height constraint multiplied by this factor. + /// + /// If null, the incoming height constraints are passed to the child + /// unmodified. + final double? heightFactor; + + /// How to align the child. + /// + /// The x and y values of the alignment control the horizontal and vertical + /// alignment, respectively. An x value of -1.0 means that the left edge of + /// the child is aligned with the left edge of the parent whereas an x value + /// of 1.0 means that the right edge of the child is aligned with the right + /// edge of the parent. Other values interpolate (and extrapolate) linearly. + /// For example, a value of 0.0 means that the center of the child is aligned + /// with the center of the parent. + /// + /// Defaults to [Alignment.center]. + /// + /// See also: + /// + /// * [Alignment], a class with convenient constants typically used to + /// specify an [AlignmentGeometry]. + /// * [AlignmentDirectional], like [Alignment] for specifying alignments + /// relative to text direction. + final AlignmentGeometry alignment; + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, constraints) { + var maxWidth = constraints.maxWidth; + if (widthFactor case final widthFactor?) { + final width = maxWidth * widthFactor; + maxWidth = width; + } + + var maxHeight = constraints.maxHeight; + if (heightFactor case final heightFactor?) { + final height = maxHeight * heightFactor; + maxHeight = height; + } + + return UnconstrainedBox( + alignment: alignment, + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: maxWidth, + maxHeight: maxHeight, + ), + child: child, + ), + ); + }, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/misc/size_change_listener.dart b/packages/stream_chat_flutter/lib/src/misc/size_change_listener.dart new file mode 100644 index 0000000000..1e6a2adfcd --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/misc/size_change_listener.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; + +/// A widget that calls the callback when the layout dimensions of +/// its child change. +class SizeChangeListener extends SingleChildRenderObjectWidget { + /// Creates a new instance of [SizeChangeListener]. + const SizeChangeListener({ + super.key, + required this.onSizeChanged, + super.child, + }); + + /// The action to perform when the size of child widget changes. + final ValueChanged onSizeChanged; + + @override + RenderObject createRenderObject(BuildContext context) { + return _RenderSizeChangedWithCallback(onSizeChanged: onSizeChanged); + } +} + +class _RenderSizeChangedWithCallback extends RenderProxyBox { + _RenderSizeChangedWithCallback({ + required this.onSizeChanged, + }); + + final ValueChanged onSizeChanged; + Size? _oldSize; + + @override + void performLayout() { + super.performLayout(); + if (size != _oldSize) { + _oldSize = size; + WidgetsBinding.instance.addPostFrameCallback((_) { + // Call the callback with the new size + onSizeChanged.call(size); + }); + } + } +} diff --git a/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator.dart b/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator.dart new file mode 100644 index 0000000000..8f57179b2b --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator.dart @@ -0,0 +1,107 @@ +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/reactions/indicator/reaction_indicator_icon_list.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// {@template streamReactionIndicator} +/// A widget that displays a horizontal list of reaction icons that users have +/// reacted with on a message. +/// +/// This widget is typically used to show the reactions on a message in a +/// compact way, allowing users to see which reactions have been added +/// to a message without opening a full user reactions view. +/// {@endtemplate} +class StreamReactionIndicator extends StatelessWidget { + /// {@macro streamReactionIndicator} + const StreamReactionIndicator({ + super.key, + this.onTap, + required this.message, + this.backgroundColor, + this.padding = const EdgeInsets.all(8), + this.scrollable = true, + this.borderRadius = const BorderRadius.all(Radius.circular(26)), + this.reactionSorting = ReactionSorting.byFirstReactionAt, + }); + + /// Message to attach the reaction to. + final Message message; + + /// Callback triggered when the reaction indicator is tapped. + final VoidCallback? onTap; + + /// Background color for the reaction indicator. + final Color? backgroundColor; + + /// Padding around the reaction picker. + /// + /// Defaults to `EdgeInsets.all(8)`. + final EdgeInsets padding; + + /// Whether the reaction picker should be scrollable. + /// + /// Defaults to `true`. + final bool scrollable; + + /// Border radius for the reaction picker. + /// + /// Defaults to a circular border with a radius of 26. + final BorderRadius? borderRadius; + + /// Sorting strategy for the reaction. + /// + /// Defaults to sorting by the first reaction at. + final Comparator reactionSorting; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final config = StreamChatConfiguration.of(context); + final reactionIcons = config.reactionIcons; + + final ownReactions = {...?message.ownReactions?.map((it) => it.type)}; + final indicatorIcons = message.reactionGroups?.entries + .sortedByCompare((it) => it.value, reactionSorting) + .map((group) { + final reactionIcon = reactionIcons.firstWhere( + (it) => it.type == group.key, + orElse: () => const StreamReactionIcon.unknown(), + ); + + return ReactionIndicatorIcon( + type: reactionIcon.type, + builder: reactionIcon.builder, + isSelected: ownReactions.contains(reactionIcon.type), + ); + }); + + final isSingleIndicatorIcon = indicatorIcons?.length == 1; + final extraPadding = switch (isSingleIndicatorIcon) { + true => EdgeInsets.zero, + false => const EdgeInsets.symmetric(horizontal: 4), + }; + + final indicator = ReactionIndicatorIconList( + indicatorIcons: [...?indicatorIcons], + ); + + return Material( + borderRadius: borderRadius, + clipBehavior: Clip.antiAlias, + color: backgroundColor ?? theme.colorTheme.barsBg, + child: InkWell( + onTap: onTap, + child: Padding( + padding: padding.add(extraPadding), + child: switch (scrollable) { + true => SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: indicator, + ), + false => indicator, + }, + ), + ), + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_bubble_overlay.dart b/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_bubble_overlay.dart new file mode 100644 index 0000000000..cb4ce0d465 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_bubble_overlay.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/reactions/indicator/reaction_indicator.dart'; +import 'package:stream_chat_flutter/src/reactions/reaction_bubble_overlay.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// {@template reactionIndicatorBubbleOverlay} +/// A widget that displays a reaction indicator bubble overlay attached to a +/// [child] widget. Typically used to show the reactions for a [Message]. +/// +/// It positions the reaction indicator relative to the provided [child] widget, +/// using the given [anchorOffset] and [childSizeDelta] for fine-tuned placement +/// {@endtemplate} +class ReactionIndicatorBubbleOverlay extends StatelessWidget { + /// {@macro reactionIndicatorBubbleOverlay} + const ReactionIndicatorBubbleOverlay({ + super.key, + this.onTap, + required this.message, + required this.child, + this.visible = true, + this.reverse = false, + this.anchorOffset = Offset.zero, + this.childSizeDelta = Offset.zero, + }); + + /// Whether the overlay should be visible. + final bool visible; + + /// Whether to reverse the alignment of the overlay. + final bool reverse; + + /// The widget to which the overlay is anchored. + final Widget child; + + /// The message to display reactions for. + final Message message; + + /// Callback triggered when the reaction indicator is tapped. + final VoidCallback? onTap; + + /// The offset to apply to the anchor position. + final Offset anchorOffset; + + /// The additional size delta to apply to the child widget for positioning. + final Offset childSizeDelta; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final messageTheme = theme.getMessageTheme(reverse: reverse); + + return ReactionBubbleOverlay( + visible: visible, + childSizeDelta: childSizeDelta, + config: ReactionBubbleConfig( + fillColor: messageTheme.reactionsBackgroundColor, + borderColor: messageTheme.reactionsBorderColor, + maskColor: messageTheme.reactionsMaskColor, + ), + anchor: ReactionBubbleAnchor( + offset: anchorOffset, + follower: AlignmentDirectional.bottomCenter, + target: AlignmentDirectional(reverse ? -1 : 1, -1), + ), + reaction: StreamReactionIndicator( + onTap: onTap, + message: message, + backgroundColor: messageTheme.reactionsBackgroundColor, + ), + child: child, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_icon_list.dart b/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_icon_list.dart new file mode 100644 index 0000000000..c01222fc7a --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/reactions/indicator/reaction_indicator_icon_list.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/misc/reaction_icon.dart'; + +/// {@template reactionIndicatorIconBuilder} +/// Function signature for building a custom reaction icon widget. +/// +/// This is used to customize how each reaction icon is displayed in the +/// [ReactionIndicatorIconList]. +/// +/// Parameters: +/// - [context]: The build context. +/// - [icon]: The reaction icon data containing type and selection state. +/// {@endtemplate} +typedef ReactionIndicatorIconBuilder = Widget Function( + BuildContext context, + ReactionIndicatorIcon icon, +); + +/// {@template reactionIndicatorIconList} +/// A widget that displays a list of reactionIcons that users have reacted with +/// on a message. +/// +/// also see: +/// - [StreamReactionIndicator], which is a higher-level widget that uses this +/// widget to display a reaction indicator in a modal or inline. +/// {@endtemplate} +class ReactionIndicatorIconList extends StatelessWidget { + /// {@macro reactionIndicatorIconList} + const ReactionIndicatorIconList({ + super.key, + required this.indicatorIcons, + this.iconBuilder = _defaultIconBuilder, + }); + + /// The list of available reaction indicator icons. + final List indicatorIcons; + + /// The builder used to create the reaction indicator icons. + final ReactionIndicatorIconBuilder iconBuilder; + + static Widget _defaultIconBuilder( + BuildContext context, + ReactionIndicatorIcon icon, + ) { + return icon.build(context); + } + + @override + Widget build(BuildContext context) { + return Wrap( + spacing: 8, + runSpacing: 4, + runAlignment: WrapAlignment.center, + alignment: WrapAlignment.spaceAround, + crossAxisAlignment: WrapCrossAlignment.center, + children: [...indicatorIcons.map((icon) => iconBuilder(context, icon))], + ); + } +} + +/// {@template reactionIndicatorIcon} +/// A data class that represents a reaction icon within the reaction indicator. +/// +/// This class holds information about a specific reaction, such as its type, +/// whether it's currently selected by the user, and a builder function +/// to construct its visual representation. +/// {@endtemplate} +class ReactionIndicatorIcon { + /// {@macro reactionIndicatorIcon} + const ReactionIndicatorIcon({ + required this.type, + this.isSelected = false, + this.iconSize = 16, + required ReactionIconBuilder builder, + }) : _builder = builder; + + /// The unique identifier for the reaction type (e.g., "like", "love"). + final String type; + + /// A boolean indicating whether this reaction is currently selected by the + /// user. + final bool isSelected; + + /// The size of the reaction icon. + final double iconSize; + + /// Builds the actual widget for this reaction icon using the provided + /// [context], selection state, and icon size. + Widget build(BuildContext context) => _builder(context, isSelected, iconSize); + final ReactionIconBuilder _builder; +} diff --git a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart index 75da2e4cc5..06456e85cf 100644 --- a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart @@ -36,7 +36,7 @@ class StreamReactionPicker extends StatelessWidget { required this.message, required this.reactionIcons, this.onReactionPicked, - this.padding = const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + this.padding = const EdgeInsets.all(4), this.scrollable = true, this.borderRadius = const BorderRadius.all(Radius.circular(24)), }); @@ -85,7 +85,7 @@ class StreamReactionPicker extends StatelessWidget { /// Padding around the reaction picker. /// - /// Defaults to `EdgeInsets.symmetric(horizontal: 8, vertical: 4)`. + /// Defaults to `EdgeInsets.all(4)`. final EdgeInsets padding; /// Whether the reaction picker should be scrollable. @@ -108,12 +108,18 @@ class StreamReactionPicker extends StatelessWidget { onReactionPicked: onReactionPicked, ); + final isSinglePickerIcon = reactionIcons.length == 1; + final extraPadding = switch (isSinglePickerIcon) { + true => EdgeInsets.zero, + false => const EdgeInsets.symmetric(horizontal: 4), + }; + return Material( borderRadius: borderRadius, clipBehavior: Clip.antiAlias, color: theme.colorTheme.barsBg, child: Padding( - padding: padding, + padding: padding.add(extraPadding), child: switch (scrollable) { false => reactionPicker, true => SingleChildScrollView( diff --git a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart new file mode 100644 index 0000000000..a13cc5f3fe --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/reactions/picker/reaction_picker.dart'; +import 'package:stream_chat_flutter/src/reactions/picker/reaction_picker_icon_list.dart'; +import 'package:stream_chat_flutter/src/reactions/reaction_bubble_overlay.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// {@template reactionPickerBubbleOverlay} +/// A widget that displays a reaction picker bubble overlay attached to a +/// [child] widget. Typically used with the [MessageWidget] as the child. +/// +/// It positions the reaction picker relative to the provided [child] widget, +/// using the given [anchorOffset] and [childSizeDelta] for fine-tuned placement +/// {@endtemplate} +class ReactionPickerBubbleOverlay extends StatelessWidget { + /// {@macro reactionPickerBubbleOverlay} + const ReactionPickerBubbleOverlay({ + super.key, + required this.message, + required this.child, + this.onReactionPicked, + this.visible = true, + this.reverse = false, + this.anchorOffset = Offset.zero, + this.childSizeDelta = Offset.zero, + this.reactionPickerBuilder = StreamReactionPicker.builder, + }); + + /// Whether the overlay should be visible. + final bool visible; + + /// Whether to reverse the alignment of the overlay. + final bool reverse; + + /// The widget to which the overlay is anchored. + final Widget child; + + /// The message to attach the reaction to. + final Message message; + + /// Callback triggered when a reaction is picked. + final OnReactionPicked? onReactionPicked; + + /// Builder for the reaction picker widget. + final ReactionPickerBuilder reactionPickerBuilder; + + /// The offset to apply to the anchor position. + final Offset anchorOffset; + + /// The additional size delta to apply to the child widget for positioning. + final Offset childSizeDelta; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + return ReactionBubbleOverlay( + visible: visible, + childSizeDelta: childSizeDelta, + config: ReactionBubbleConfig( + maskWidth: 0, + borderWidth: 0, + fillColor: colorTheme.barsBg, + ), + anchor: ReactionBubbleAnchor( + offset: anchorOffset, + follower: AlignmentDirectional.bottomCenter, + target: AlignmentDirectional(reverse ? -1 : 1, -1), + ), + reaction: reactionPickerBuilder.call(context, message, onReactionPicked), + child: child, + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart index 17dc677648..124757aeb4 100644 --- a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart @@ -7,7 +7,7 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// {@template onReactionPressed} /// Callback called when a reaction icon is pressed. /// {@endtemplate} -typedef OnReactionPicked = void Function(Reaction reaction); +typedef OnReactionPicked = ValueSetter; /// {@template onReactionPickerIconPressed} /// Callback called when a reaction picker icon is pressed. @@ -28,7 +28,7 @@ typedef OnReactionPickerIconPressed = ValueSetter; typedef ReactionPickerIconBuilder = Widget Function( BuildContext context, ReactionPickerIcon icon, - OnReactionPickerIconPressed? onPressed, + VoidCallback? onPressed, ); /// {@template reactionPickerIconList} @@ -70,7 +70,7 @@ class ReactionPickerIconList extends StatefulWidget { static Widget _defaultIconBuilder( BuildContext context, ReactionPickerIcon icon, - OnReactionPickerIconPressed? onPressed, + VoidCallback? onPressed, ) { return ReactionIconButton( icon: icon, @@ -183,8 +183,8 @@ class _ReactionPickerIconListState extends State { ); final onPressed = switch (widget.onReactionPicked) { - final onPicked? => (type) { - final picked = reaction ?? Reaction(type: type); + final onPicked? => () { + final picked = reaction ?? Reaction(type: icon.type); return onPicked(picked); }, _ => null, @@ -222,8 +222,9 @@ class ReactionPickerIcon { const ReactionPickerIcon({ required this.type, this.isSelected = false, - required this.builder, - }); + this.iconSize = 24, + required ReactionIconBuilder builder, + }) : _builder = builder; /// The unique identifier for the reaction type (e.g., "like", "love"). final String type; @@ -232,9 +233,13 @@ class ReactionPickerIcon { /// user. final bool isSelected; - /// A builder function responsible for creating the widget that visually - /// represents this reaction icon. - final ReactionIconBuilder builder; + /// The size of the reaction icon. + final double iconSize; + + /// Builds the actual widget for this reaction icon using the provided + /// [context], selection state, and icon size. + Widget build(BuildContext context) => _builder(context, isSelected, iconSize); + final ReactionIconBuilder _builder; } /// {@template reactionIconButton} @@ -255,25 +260,20 @@ class ReactionIconButton extends StatelessWidget { final ReactionPickerIcon icon; /// Callback triggered when the reaction picker icon is pressed. - final OnReactionPickerIconPressed? onPressed; + final VoidCallback? onPressed; @override Widget build(BuildContext context) { return IconButton( - iconSize: 24, - icon: icon.builder(context, icon.isSelected, 24), + key: Key(icon.type), + iconSize: icon.iconSize, + onPressed: onPressed, + icon: icon.build(context), padding: const EdgeInsets.all(4), style: IconButton.styleFrom( tapTargetSize: MaterialTapTargetSize.shrinkWrap, - minimumSize: const Size.square(24), + minimumSize: Size.square(icon.iconSize), ), - onPressed: switch (onPressed) { - final onPressed? => () { - final type = icon.type; - return onPressed(type); - }, - _ => null, - }, ); } } diff --git a/packages/stream_chat_flutter/lib/src/reactions/reaction_bubble_overlay.dart b/packages/stream_chat_flutter/lib/src/reactions/reaction_bubble_overlay.dart new file mode 100644 index 0000000000..bd1b50034e --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/reactions/reaction_bubble_overlay.dart @@ -0,0 +1,373 @@ +// ignore_for_file: cascade_invocations + +import 'dart:math' as math; + +import 'package:flutter/material.dart'; +import 'package:flutter_portal/flutter_portal.dart'; +import 'package:stream_chat_flutter/src/misc/size_change_listener.dart'; + +/// Signature for building a custom ReactionBubble widget. +typedef ReactionBubbleBuilder = Widget Function( + BuildContext context, + ReactionBubbleConfig config, + Widget child, +); + +/// Defines the anchor settings for positioning a ReactionBubble relative to a +/// target widget. +class ReactionBubbleAnchor { + /// Creates an anchor with custom alignment and offset. + const ReactionBubbleAnchor({ + this.offset = Offset.zero, + required this.target, + required this.follower, + this.shiftToWithinBound = const AxisFlag(x: true), + }); + + /// Creates an anchor that positions the bubble at the top-end of the + /// target widget. + const ReactionBubbleAnchor.topEnd({ + this.offset = Offset.zero, + this.shiftToWithinBound = const AxisFlag(x: true), + }) : target = AlignmentDirectional.topEnd, + follower = AlignmentDirectional.bottomCenter; + + /// Creates an anchor that positions the bubble at the top-start of the + /// target widget. + const ReactionBubbleAnchor.topStart({ + this.offset = Offset.zero, + this.shiftToWithinBound = const AxisFlag(x: true), + }) : target = AlignmentDirectional.topStart, + follower = AlignmentDirectional.bottomCenter; + + /// Additional offset applied to the bubble position. + final Offset offset; + + /// Target alignment relative to the target widget. + final AlignmentDirectional target; + + /// Alignment of the bubble follower relative to the target alignment. + final AlignmentDirectional follower; + + /// Whether to shift the bubble within the visible screen bounds along each + /// axis if it exceeds the screen size. + final AxisFlag shiftToWithinBound; +} + +/// An overlay widget that displays a reaction bubble near a child widget. +class ReactionBubbleOverlay extends StatefulWidget { + /// Creates a new instance of [ReactionBubbleOverlay]. + const ReactionBubbleOverlay({ + super.key, + this.visible = true, + required this.child, + required this.reaction, + this.childSizeDelta = Offset.zero, + this.builder = _defaultBuilder, + this.config = const ReactionBubbleConfig(), + this.anchor = const ReactionBubbleAnchor.topEnd(), + }); + + /// The target child widget to anchor the reaction bubble to. + final Widget child; + + /// The reaction widget to display inside the bubble. + final Widget reaction; + + /// Whether the reaction bubble is visible. + final bool visible; + + /// Optional adjustment to the child's reported size. + final Offset childSizeDelta; + + /// The configuration used for rendering the reaction bubble. + final ReactionBubbleConfig config; + + /// The anchor configuration to control bubble positioning. + final ReactionBubbleAnchor anchor; + + /// The builder used to create the bubble appearance. + final ReactionBubbleBuilder builder; + + static Widget _defaultBuilder( + BuildContext context, + ReactionBubbleConfig config, + Widget child, + ) { + return RepaintBoundary( + child: CustomPaint( + painter: ReactionBubblePainter(config: config), + child: child, + ), + ); + } + + @override + State createState() => _ReactionBubbleOverlayState(); +} + +class _ReactionBubbleOverlayState extends State { + Size? _childSize; + + /// Calculates the alignment for the bubble tail relative to the bubble rect. + AlignmentGeometry _calculateTailAlignment({ + required Size childSize, + required Rect bubbleRect, + required Size availableSpace, + bool reverse = false, + }) { + final childEdgeX = switch (reverse) { + true => availableSpace.width - childSize.width, + false => childSize.width + }; + + final idealBubbleLeft = childEdgeX - (bubbleRect.width / 2); + final maxLeft = availableSpace.width - bubbleRect.width; + final actualBubbleLeft = idealBubbleLeft.clamp(0, math.max(0, maxLeft)); + final tailOffset = childEdgeX - actualBubbleLeft; + + if (tailOffset == 0) return AlignmentDirectional.bottomCenter; + return AlignmentDirectional((tailOffset * 2 / bubbleRect.width) - 1, 1); + } + + @override + Widget build(BuildContext context) { + final child = SizeChangeListener( + onSizeChanged: (size) => setState(() => _childSize = size), + child: widget.child, + ); + + final childSize = _childSize; + // If the child size is not available or the overlay should not be visible, + // return the child without any overlay. + if (childSize == null || !widget.visible) return child; + + final alignment = widget.anchor; + final direction = Directionality.maybeOf(context); + final targetAlignment = alignment.target.resolve(direction); + final followerAlignment = alignment.follower.resolve(direction); + final availableSpace = MediaQuery.sizeOf(context); + + final reverse = targetAlignment.x < 0; + final config = widget.config.copyWith( + flipTail: reverse, + tailAlignment: (bubbleRect) { + final alignment = _calculateTailAlignment( + reverse: reverse, + bubbleRect: bubbleRect, + availableSpace: availableSpace, + childSize: childSize + widget.childSizeDelta, + ); + + return alignment.resolve(direction); + }, + ); + + return PortalTarget( + anchor: Aligned( + target: targetAlignment, + follower: followerAlignment, + offset: widget.anchor.offset, + shiftToWithinBound: widget.anchor.shiftToWithinBound, + ), + portalFollower: widget.builder(context, config, widget.reaction), + child: child, + ); + } +} + +/// Defines the visual configuration of a ReactionBubble. +class ReactionBubbleConfig { + /// Creates a new instance of [ReactionBubbleConfig] with default values. + const ReactionBubbleConfig({ + this.flipTail = false, + this.fillColor, + this.maskColor, + this.borderColor, + this.maskWidth = 2.0, + this.borderWidth = 1.0, + this.bigTailCircleRadius = 4.0, + this.smallTailCircleRadius = 2.0, + this.tailAlignment = _defaultTailAlignment, + }); + + /// Whether to flip the tail horizontally. + final bool flipTail; + + /// Fill color of the bubble. + final Color? fillColor; + + /// Mask color of the bubble (used for visual masking). + final Color? maskColor; + + /// Border color of the bubble. + final Color? borderColor; + + /// Width of the mask stroke. + final double maskWidth; + + /// Width of the border stroke. + final double borderWidth; + + /// Radius of the larger circle at the bubble tail. + final double bigTailCircleRadius; + + /// Radius of the smaller circle at the bubble tail. + final double smallTailCircleRadius; + + /// Function that defines the alignment of the tail within the bubble rect. + final Alignment Function(Rect) tailAlignment; + + static Alignment _defaultTailAlignment(Rect rect) => Alignment.bottomCenter; + + /// The total height contribution of the bubble tail. + double get tailHeight => bigTailCircleRadius * 2 + smallTailCircleRadius * 2; + + /// Returns a copy of this config with optional overrides. + ReactionBubbleConfig copyWith({ + bool? flipTail, + Color? fillColor, + Color? maskColor, + Color? borderColor, + double? maskWidth, + double? borderWidth, + double? bigTailCircleRadius, + double? smallTailCircleRadius, + Alignment Function(Rect)? tailAlignment, + }) { + return ReactionBubbleConfig( + flipTail: flipTail ?? this.flipTail, + fillColor: fillColor ?? this.fillColor, + maskColor: maskColor ?? this.maskColor, + borderColor: borderColor ?? this.borderColor, + maskWidth: maskWidth ?? this.maskWidth, + borderWidth: borderWidth ?? this.borderWidth, + bigTailCircleRadius: bigTailCircleRadius ?? this.bigTailCircleRadius, + smallTailCircleRadius: + smallTailCircleRadius ?? this.smallTailCircleRadius, + tailAlignment: tailAlignment ?? this.tailAlignment, + ); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + return other is ReactionBubbleConfig && + runtimeType == other.runtimeType && + flipTail == other.flipTail && + fillColor == other.fillColor && + maskColor == other.maskColor && + borderColor == other.borderColor && + maskWidth == other.maskWidth && + borderWidth == other.borderWidth && + bigTailCircleRadius == other.bigTailCircleRadius && + smallTailCircleRadius == other.smallTailCircleRadius && + tailAlignment == other.tailAlignment; + } + + @override + int get hashCode => + flipTail.hashCode ^ + fillColor.hashCode ^ + maskColor.hashCode ^ + borderColor.hashCode ^ + maskWidth.hashCode ^ + borderWidth.hashCode ^ + bigTailCircleRadius.hashCode ^ + smallTailCircleRadius.hashCode ^ + tailAlignment.hashCode; +} + +/// A CustomPainter that draws a ReactionBubble based on a ReactionBubbleConfig. +class ReactionBubblePainter extends CustomPainter { + /// Creates a [ReactionBubblePainter] with the specified configuration. + ReactionBubblePainter({ + this.config = const ReactionBubbleConfig(), + }) : _fillPaint = Paint() + ..color = config.fillColor ?? Colors.white + ..style = PaintingStyle.fill, + _maskPaint = Paint() + ..color = config.maskColor ?? Colors.white + ..style = PaintingStyle.fill, + _borderPaint = Paint() + ..color = config.borderColor ?? Colors.black + ..style = PaintingStyle.stroke + ..strokeWidth = config.borderWidth; + + /// Configuration used to style the bubble. + final ReactionBubbleConfig config; + + final Paint _fillPaint; + final Paint _borderPaint; + final Paint _maskPaint; + + @override + void paint(Canvas canvas, Size size) { + final tailHeight = config.tailHeight; + final fullHeight = size.height + tailHeight; + final bubbleHeight = fullHeight - tailHeight; + final bubbleWidth = size.width; + + final bubbleRect = RRect.fromRectAndRadius( + Rect.fromLTRB(0, 0, bubbleWidth, bubbleHeight), + Radius.circular(bubbleHeight / 2), + ); + + final alignment = config.tailAlignment.call(bubbleRect.outerRect); + final bigTailCircleCenter = alignment.withinRect(bubbleRect.tallMiddleRect); + + final bigTailCircleRect = Rect.fromCircle( + center: bigTailCircleCenter, + radius: config.bigTailCircleRadius, + ); + + final smallTailCircleOffset = Offset( + config.flipTail ? bigTailCircleRect.right : bigTailCircleRect.left, + bigTailCircleRect.bottom + config.smallTailCircleRadius, + ); + + final smallTailCircleRect = Rect.fromCircle( + center: smallTailCircleOffset, + radius: config.smallTailCircleRadius, + ); + + final reactionBubbleMaskPath = _buildCombinedPath( + bubbleRect.inflate(config.maskWidth), + bigTailCircleRect.inflate(config.maskWidth), + smallTailCircleRect.inflate(config.maskWidth), + ); + + canvas.drawPath(reactionBubbleMaskPath, _maskPaint); + + final reactionBubblePath = _buildCombinedPath( + bubbleRect, + bigTailCircleRect, + smallTailCircleRect, + ); + + canvas.drawPath(reactionBubblePath, _borderPaint); + canvas.drawPath(reactionBubblePath, _fillPaint); + } + + /// Builds a combined path of the bubble and tail circles. + Path _buildCombinedPath( + RRect bubble, + Rect bigCircle, + Rect smallCircle, + ) { + final bubblePath = Path()..addRRect(bubble); + final bigTailPath = Path()..addOval(bigCircle); + final smallTailPath = Path()..addOval(smallCircle); + + return Path.combine( + PathOperation.union, + Path.combine(PathOperation.union, bubblePath, bigTailPath), + smallTailPath, + ); + } + + @override + bool shouldRepaint(covariant ReactionBubblePainter oldDelegate) { + return true; + } +} diff --git a/packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart b/packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart deleted file mode 100644 index 7bc904b95c..0000000000 --- a/packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template reactionIndicator} -/// Indicates the reaction a [StreamMessageWidget] has. -/// -/// Used in [MessageWidgetContent]. -/// {@endtemplate} -class ReactionIndicator extends StatelessWidget { - /// {@macro reactionIndicator} - const ReactionIndicator({ - super.key, - required this.ownId, - required this.message, - required this.onTap, - required this.reverse, - required this.messageTheme, - }); - - /// The id of the current user. - final String ownId; - - /// {@macro message} - final Message message; - - /// The callback to perform when the widget is tapped or clicked. - final VoidCallback onTap; - - /// {@macro reverse} - final bool reverse; - - /// {@macro messageTheme} - final StreamMessageThemeData messageTheme; - - @override - Widget build(BuildContext context) { - final reactionsMap = {}; - for (final reaction in [...?message.latestReactions]) { - final reactionType = reaction.type; - final userId = reaction.user?.id; - - if (reactionsMap.containsKey(reactionType) && userId != ownId) continue; - reactionsMap[reactionType] = reaction; - } - - final reactionsList = reactionsMap.values.sorted((prev, curr) { - final prevUserId = prev.user?.id; - final currUserId = curr.user?.id; - - if (prevUserId == null && currUserId == null) return 0; - if (prevUserId == null) return 1; - if (currUserId == null) return -1; - - if (prevUserId == ownId) return 1; - return -1; - }); - - return GestureDetector( - onTap: onTap, - child: StreamReactionBubble( - key: ValueKey('${message.id}.reactions'), - reverse: reverse, - flipTail: reverse, - backgroundColor: - messageTheme.reactionsBackgroundColor ?? Colors.transparent, - borderColor: messageTheme.reactionsBorderColor ?? Colors.transparent, - maskColor: messageTheme.reactionsMaskColor ?? Colors.transparent, - reactions: reactionsList, - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/reactions/reactions_align.dart b/packages/stream_chat_flutter/lib/src/reactions/reactions_align.dart deleted file mode 100644 index 218ac3f866..0000000000 --- a/packages/stream_chat_flutter/lib/src/reactions/reactions_align.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// Extension on [Message] that provides alignment calculations for reaction -/// pickers. -/// -/// This extension adds functionality to determine the optimal positioning of -/// reaction pickers based on message size and available screen space. -extension ReactionPickerAlignment on Message { - /// Calculates the alignment for the reaction picker based on the message size - /// and the available space. - /// - /// The [fontSize] is used to calculate the size of the message, if not - /// provided, the font size of 1 is used. - /// - /// The [orientation] is used to calculate the size of the message, if not - /// provided, the orientation of the device is used. - AlignmentGeometry calculateReactionPickerAlignment({ - required BoxConstraints constraints, - double? fontSize, - Orientation orientation = Orientation.portrait, - bool reverse = false, - }) { - final maxWidth = constraints.maxWidth; - - final roughSentenceSize = roughMessageSize(fontSize); - final hasAttachments = attachments.isNotEmpty; - final isReply = quotedMessageId != null; - final isAttachment = hasAttachments && !isReply; - - // divFactor is the percentage of the available space that the message - // takes. - // - // When the divFactor is bigger than 0.5 that means that the messages is - // bigger than 50% of the available space and the modal should have an - // offset in the direction that the message grows. When the divFactor is - // smaller than 0.5 then the offset should be to he side opposite of the - // message growth. - // - // In resume, when divFactor > 0.5 then result > 0, when divFactor < 0.5 - // then result < 0. - var divFactor = 0.5; - - // When in portrait, attachments normally take 75% of the screen, when in - // landscape, attachments normally take 50% of the screen. - if (isAttachment) { - divFactor = switch (orientation) { - Orientation.portrait => 0.75, - Orientation.landscape => 0.5, - }; - } else { - divFactor = roughSentenceSize == 0 ? 0.5 : (roughSentenceSize / maxWidth); - } - - final signal = reverse ? 1 : -1; - final result = signal * (1 - divFactor * 2.0); - - // Ensure reactions don't get pushed past the edge of the screen. - // - // This happens if divFactor is really big. When this happens, we can simply - // move the model all the way to the end of screen. - return AlignmentDirectional(result.clamp(-1, 1), 0); - } -} diff --git a/packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart b/packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart index 6871b843ff..68065e8afc 100644 --- a/packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/avatars/user_avatar.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; -import 'package:stream_chat_flutter/src/reactions/reaction_bubble.dart'; +import 'package:stream_chat_flutter/src/misc/reaction_icon.dart'; +import 'package:stream_chat_flutter/src/reactions/indicator/reaction_indicator_icon_list.dart'; +import 'package:stream_chat_flutter/src/reactions/reaction_bubble_overlay.dart'; +import 'package:stream_chat_flutter/src/stream_chat_configuration.dart'; import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/utils/extensions.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; @@ -95,7 +98,15 @@ class _UserReactionItem extends StatelessWidget { final isCurrentUserReaction = reactionUser.id == currentUser?.id; final theme = StreamChatTheme.of(context); - final messageTheme = theme.getMessageTheme(reverse: !isCurrentUserReaction); + final messageTheme = theme.getMessageTheme(reverse: isCurrentUserReaction); + + final config = StreamChatConfiguration.of(context); + final reactionIcons = config.reactionIcons; + + final reactionIcon = reactionIcons.firstWhere( + (it) => it.type == reaction.type, + orElse: () => const StreamReactionIcon.unknown(), + ); return Column( mainAxisSize: MainAxisSize.min, @@ -112,21 +123,33 @@ class _UserReactionItem extends StatelessWidget { constraints: const BoxConstraints.tightFor(height: 64, width: 64), ), PositionedDirectional( - bottom: 0, - start: isCurrentUserReaction ? 0 : null, + bottom: 8, end: isCurrentUserReaction ? null : 0, + start: isCurrentUserReaction ? 0 : null, child: IgnorePointer( - child: StreamReactionBubble( - reactions: [reaction], - reverse: isCurrentUserReaction, - flipTail: isCurrentUserReaction, - backgroundColor: messageTheme.reactionsBackgroundColor ?? - Colors.transparent, - borderColor: - messageTheme.reactionsBorderColor ?? Colors.transparent, - maskColor: - messageTheme.reactionsMaskColor ?? Colors.transparent, - tailCirclesSpacing: 1, + child: RepaintBoundary( + child: CustomPaint( + painter: ReactionBubblePainter( + config: ReactionBubbleConfig( + flipTail: isCurrentUserReaction, + fillColor: messageTheme.reactionsBackgroundColor, + borderColor: messageTheme.reactionsBorderColor, + maskColor: messageTheme.reactionsMaskColor, + ), + ), + child: Padding( + padding: const EdgeInsets.all(8), + child: ReactionIndicatorIconList( + indicatorIcons: [ + ReactionIndicatorIcon( + type: reactionIcon.type, + isSelected: isCurrentUserReaction, + builder: reactionIcon.builder, + ), + ], + ), + ), + ), ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart index f1cb07953b..2a1a22e028 100644 --- a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart @@ -677,8 +677,8 @@ class StreamChatThemeData { /// If [reverse] is true, it returns the [otherMessageTheme], otherwise it /// returns the [ownMessageTheme]. StreamMessageThemeData getMessageTheme({bool reverse = false}) { - if (reverse) return otherMessageTheme; - return ownMessageTheme; + if (reverse) return ownMessageTheme; + return otherMessageTheme; } /// Creates a copy of [StreamChatThemeData] with specified attributes diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 2b36105d19..8d581e796f 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -106,7 +106,6 @@ export 'src/poll/stream_poll_text_field.dart'; export 'src/reactions/picker/reaction_picker.dart'; export 'src/reactions/picker/reaction_picker_icon_list.dart'; export 'src/reactions/reaction_bubble.dart'; -export 'src/reactions/reaction_indicator.dart'; export 'src/reactions/user_reactions.dart'; export 'src/scroll_view/channel_scroll_view/stream_channel_grid_tile.dart'; export 'src/scroll_view/channel_scroll_view/stream_channel_grid_view.dart'; diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_dark.png index 4c6b39c5f02c0cb4851f6dd8e983b34c59a59543..42832c2e756827715593d184934eb28986de749c 100644 GIT binary patch delta 3340 zcmXAsdpy(oAIHD56{T=;4mHe9_2YE9ko(cbx}4~OI*eSWQ@Pt*hpqXNL8iTh*@%(l1qrlM#Cngm=W3Jy5F4h`S0`iJU;LDT?{^aM@BrUDrtU& z9+wU5BTt}$IH{?rUfy-Vf-6ngZ!cjo4RB?}#UCGAsk&A@t9EM}aPA`Quvvs}Ywzoe zlDShYD-YOc9cVbJR4-@zUZ98>~Cu)LdKGwh23ioi+u4(_cv|TqR@+{G|V61ZaRIR8tLdZG}*4_0W z^)A`3wHMMdoAQT*LdDm&5?KQ^yY2mnu(80uJ+QI5I@1%S=672rFVuqZAFfMn(^M-@ z&qDV|X9ddCY3JR5R&r{8M3_Em#qS>$37PccywW!>`gg<;*HTpBZ$HyNdmOI5^ZCzOHW<@&EWC1z_)DWS?yPScwaoG+;d765-W>W`hHxQ zFj%ET%{xzzF9t>TWj{p}oj;5mSR|DxAt`GqE)H(ox%StGZs(m_H)(q>Nji{2!j$ta zmbj*;pW{o3W$&cVC+@Xow2i~54wga#e#EnVaMNq5I$A)cP7f4<+=~QG8TqM)@@(nO z*b-Ndo}?H?{`TZ$i^i2^{sYvY#MCw`DW-13%MYC5cPI(h(X97u`my4ezB`ZSo3c@3 zOh@c;Mc)!l#W1)eCaJ8=Cw9xs>v&YTl=Vg^5>|WkMY+~zM{wM!25kI5u#UfC7!W49 zZfieF;AFB{ceM4Jima^5`{ja3X4~jt3;ir-1Dto+9Z^Vh9&A$dkmsv>LE?~CCul*s z9$d`bi@=O4^Tz3`!h{Z4=w!9D6x%iuU0w5_@wD+!V`k}qS;m&D(m OMN)rG1VV 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 literal 5199 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 z zxDH?eD&@C5SasvMKKFdsQVEGsJm&zlg_p|Q?aGU-LL#WnNFA`lJTNp@|mHI4h_Wo3`C^4XS9GMOBH zGdrhghEgislp)|!C4?B3ENM@kY&}UJtg_6lT3q8`cVFr2OaQxO>Y{&Dz0zDdF8y3e-^nR`l;tmb zrLc~~vw{&;@n%+XCN-!0u&JzFBmV#qHtO^H+it%seL#qs#TE?)m6M>CXQ7AH(#I5{ zw$|nhG9d{LAWP_o6vz6V?RpDr1G>7pexnRA3jww#y50_vU>v-BXq3H>ecQwFA50F$ihu%wJyxu$t$SX_- zRrpmMoF^nDlIC;5E%$a``ys6lk#Dm=F7CrGM*m8A+u|i^9H&>v(3%%-gUGgNiQjr- zR&|w-G+asR;hfd zokX4Qd>Gf@Cx~nCF88cXDpo*;OOokZl4OuvX%MvCyfo!X@@3$R!U==lBiKJ%7Jv3_ f{*RkiGT6iCVXI@eI{9Ez5V-JnH^&P5z;FKvs=zTX diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_dark.png index e5eec7fd0cac96c3daa436da703803c52327ed0f..c9e02502f37a10e5ea81e0c0311e733367ebce63 100644 GIT binary patch literal 5159 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 L1s<&RjlS|vc61oA delta 3478 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 delta 3688 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 F{U4q8$8rDw literal 8389 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 literal 8934 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 n?*>R8y$kSPferN=*bpf^IqlI0}d$2#AUi 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 D-Y$-8 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png index f8e44836ab5202f5d4e30ecf67d73313436e6d23..e172a54eb4869972e07725fa747f41c0c44b180a 100644 GIT binary patch literal 12157 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 X$^)CUG2@8=0Uzy01`li0pS=1nU(oDT literal 12163 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 literal 12993 zcmeHucT`hPyKWE_q$(mvM+E_?O7BSTARTE+kxrz94#5JbNN<7=P-;R43DQ-BP^5Q4 zks1hKgbnti4vUXZD^wduHBu-sgGVyf!t~p{HS|0f9jD zdb*lsAP_|g2z1Vd`XW$bxKsNI_@W3j(@_Ui4{>e*C+7pz^(?4?Pb9S~P{|9@)4XpH znzy?UmSJ!G7_+w&QG={rw1zabG}@#!&fH7zarU7_tJS`)yYW5r2F1>0ALD!RIeJeX zv%LG#N5@B*BLRy|p?pTCcwOT9RTl{)#j2KLt=nu`%jCoGrK9TV_4eZ;L`B8Jw8^Ln zL`4gMlvi}i8Zuddo-R3Q#dSpB8W=d`eqI8_T&quT0D->DX~uv+Z!hzLK)23QgT7Ex zoC8Uy|GVhlBk}Jw@n22hRn5$W82N(Xvi^Sk%vVT6Qwv_F>-W!dW~JY@xtTh0 zdfN7Jw0r}Dkycc!=dvK_jg2SLQc}H0wlK{tAz@*2Ticx6+*~Ossp4nP zD4x6K-%``h8^)L$7|?!wCf$Yf^_{7`pO~0<1#km3W2HRp{jsU3 z+XMA)95|Ul?!5f{7`*59R22e&xD)&!CU0VLQs^>uc|$`w?d~?+!W@&UEz9yVNXf^K z>S(0zs-bKC4K;n!hzLcXunZ{N-QDdLySV=fBy<;epqG!2Nbud5=RZ%{J1+C`f5#nF zR8>{Ybc1LRRaHjOot-n?YTQ6YadUIdtd(3*(vX-kn(8~w3UH@L0!T#rAI7Q zucw5l*S3NPY9O)QLOlV{^f zwS5;SO1-N)%s6uOyjPVQdV2Qj*Ma$rq=>#+$#Sk( z^V6qK*9)S8f`YfU++o&EOEE+u6*Jw%gAMP)?SA3K!biNkdT+X&|F%WIJDr*Z23~2D zl7*L)*k!!P3 z?Zu1nQWA2-7^hIZkh8v%Mz_E%`yJ)UgdN8xqq6s8A`j(!InI@}TV zs>Hn)w!?#iS_i8IO2w>>k$O<#vTBx+$r%RMndkS44_?;fq})zY`27Rlvc>h!h^?I} zw&emdVeKfN8?B_QY(6q1%3-6Yqti=sj9!1m9ld59 zKG1lw-cqftgBq*pe2S7O8m_9W{GqY+!0^28CF)ppnpkz==%v2&g|b+kQuBp&B6hm7 zNb_duHEsjaZ!%RQyxqvI$>*UzTh{i-fKGk*Nc0&tn$Xf>EOyd(^=dj+DcBw@He)t& z&uw4H#EIB18?@$8#^>oOg`k2GX-RurxJ=CLVHy_lP*Xh5u^X}T$g#~1ch+U+ibg68 zk7Lf3g|VAEX?)7~c`zZ%`^eihNQBEPZDMiC>!A6Wn%W0b-BevZ#?A|Go(UuQ3rkCT zHlvbB*w=v_8zma?g#P6uH_mNYZ8w{0_X6mR?L99i_jh)WZxIH;(9S{)Z3E@w2}y;3 zPv&1ANht69=}%<9=5pK3~ZJz#CKPM)F_6ZudY;j;; zKN+&mI8H^MlEUnqVUrt9q3+a?(3~eXo8ROjI=L`j!OGZ?7tKk1eqyZc!=r+b+rsS~ zQVKHFl*38|M*)0Hmz4L`DDv&imc%;_-tcX4bsn{bqv*i~oyevpC%-#tmFM_%eRrL2 zsVFGG$T$xvL^cDLvFc*8ODmt}Qx7@PU$11Ie!Rvw{=qKe;<@7Ue8`h(?%LGhCz;jy5p?Ll+13I>|UzLOzb9E8ZR{w|$&mmiDY3 zGH|;QDRQ`p61Z*BTAL3BL(z83G#B{wI>Yv3_&lSd9nXH3)F7abO!et~7Xt7`X~iGj zf@WuO(G!7FFDiZQDTOFX&t3tMQGNJ}=5l!7*_03rv$efMT=aC?+1i?Z!AMfy3sqlG zR@UdU&&-THP|V&Phb^#fv~#9em^+l@``l1^ZE1kpFh{>DJtKQ>Tcv*dB^Ric6TX1CP5PQo*2}#9@0`gAkI1IY} zG@eZCj26MIrxeRN5VWIK(MwLF5lIDdnMVO4c}A{7o==$j!Db^W+Dxy-#OuwW zVdFis-q`?Vt9b}BIBJ&xqtc4Y7?jGK#8z)YOP|WACNAgLx8NGX$H}tQo65&Dm<#S4 zZ~EJ8aAC7G1`O@|FS_bQA%L$ma3Z&m(N1Ui+$1-$fQr(IeL%ei@8ywrl|LQh-@5Qh zi6(}nJT-@nA{i`0YWiv-Ea|Iq!qH9oNSj-)G}nw~B08?lzi7bRWfa#a{={*3BGbYP5U@sNs$9*$D+CIq>-v{#=j zc+(PR)9R;;UHdspbMx}_of!8{NbWn!Cy^=+N3GM$u6vj@*8s$?3wFaw#qyHvpHxCY7C$uwr!XfA;-$@Yv&nCJ;8(hK*fK?k150t8K4>cS9hlXwJwh?|zy{i9`tbYFv>KQ5!+ zoPG?_^#a=^svz`X=jr5Cc24%GL0rcJaqdXl=uW3;$EcD;;)d+CHYJ0Fvo9Lq2ieI6 zY24)Qnu7urVhs>pG&tfrRnPe88R)n71YlF$5y4wSjFmndM~1XZ5tR<-bzfiS;js>6 zh@cTIM<6Et4$Z+J?o>^@EmUyZJ$q-N2)&4}9%qkLpMkEghi{E62RhD+3)5~P?G_uc z!s8krQp9FjY*8)7y6_VS>%$G{6aiTH?QM5Oq*LK=BvG8!G0s|2;`7YbyPW*VgC9Oq zA>ELL%BTh+ReS)kt*@`ot&OJSNAq@d>zk9R*bHoo~HZW@HRI}6(s=F6z zZ;k6zuZbA!wpDEsF>rIc!KE@Lgz^vC9>iIg7tN~JRBr>@fVbss@xrH-lvE7N!9`pm z=$=Fld;rVyv9&N5c~Ixf?1QN(;34d??b~!(gZ;!qpJsj}lcNa-c_bD}8xFuFDh0I&QC_(Wj!Qzeq<<@9E{G&mrSu8Wp8{ z|9Kj4hqku1l!U|=EBt za+NJD3IHS;z~D=MaV=jK5fq$;Wa{#bK}*ZZfY&O`$;tT#2i>TY_6ZKoIuQa1vbP}q zpIL{BdM0J&JLct;hR@VYlhWq{UeHsdf?=2vPEP=k zh;`-nm-<;`QSMy0rG=GufU}{b{k1gz`c}>PdZk$`w zauolV9XnvTG@=<=$Y+~XLL_QiT3E2O3VvxxX#(w?P$Fu;Kc<&sp2Oi)))Lq607yw% z98B>ohiZyup#J)k3;Vp{6lM<|2z3_FZrCUS9R+#`Ozk71f#aJkZfHa`TsrzJu9Rq> z5QCpz?&3ng9gah4>k$tnCC&Bum@Wvh)-J9`UStxZ9YES*o;9M7zOh~F06wdIvd+o- z)zmgx{~R;LlG7LaA&M1zRllF0+WkMaJ2ck^UK>AAN zvr1$H#{5oZ^yXT6{Dtm_k^*%7h8hT@O??>@bLHH5(4&{2|FbAHkMcXd?KI=OAX7(I zOimu<%c|PCtmbNi7*JdQ!{upywc23*6#xiR*faz%q7Nmi+E+?SgIGlep*e|cP z@x*=KoT-rdiF;|ne-zzJl^;^Cz1_X)uXQuwX98)ckzq zMXK;??$OHnx=P&BKOYr5DZRwV>$HE5)*B9lz#WU+z_gbmTC9>*nO9t50s|Ia-WIqm zrL5eSb2r8P!le{Glksu$To}wug4xVguu@Gz5VhCm&uN=w`8l~KtPiim&vc2O$zQAJ zf!4+oTMPxWDFvnLXe8gqV_jEi6&g^j{%4;5iKDCRS4g=aEiDZIZ%aYuv|&s-aQLP_ z{&L(4aRBhcL}L3*b{?MTnHih9gxG6>p)qnvMOj%afQ>S-fW`ng&U@JuIOI63931lh zW$5AI;eZ=^DP&8x&v#)Gf4z2s6`M zYZa7x(RT6GFlPL47kykn&kH{HEGBqo=0*Y75_9^9ZJ&h~h-pp^cWExZI9A{T>B2A1 zB7Hfo`s*7mlEFRz1+u=reyqR=a)p-GU=fqI~!p%JZ53Bs7#*%`z)YOZneW@cv2FL8cB zAb__BzLJs*f+G<9CVHSpIUXVU8bcIJ4Don#CXmhTCy`lkfJxwvFlBt8T0;PQ(4VJ{ zkp{Lz|J}y(Yi+Wiv#Z0^2!y`5xjC>Zrvy>{Gn&6eL%ZdW+9DC^NKla`h*gTv*GO38-9KZNZq zOA)yNmKK@t`rDOn5cejhEIn|sRdbNOQfJoA&2rT*oD}svp|CQIngi?}C6_`_x!teP z8%D-MeGQ^vS$ya$cVWWJ*g=q{xg>s{C=!M&p1|wOu}g;r*qj{V#@tRqJf|0f0i)V+ zs`**2$_u4Vk#-IZ)mIJwX$yewTe%SN`G#cDmj3}7UVC1p*5x72wR6>uHh!PZt6Lmo*w#dxMz(XJ5)lSLqDR_Z= zbOAzOLz?wT_-ZeIf{YvmK3_2{cxw|&SN=fC4>a%?zU7UyYi(Bi6* zui%I^?)3X`CBs+vI>ROxuFV46xlFhtOv~J=VD*-0cSfDE@)veMAPk$}vlB*XC53#S z15V+ESB(>vo}00Ldit^tX}d(tHfjxe@CJ?;V5C;>3lQ3x{&Y+%rRo|k9Up=Ze%}(` zGCA7`-<@r*^B~ljP4Ltz$WaR2fC(t?|4tyH#82(-4jUZ3Qx=flS&>H`f)@*OQrTvc zL?b@LiwG@;>xWivxLnd&y)-z8V$MnS4pzyHglZ3meL!(i|5-aQE)}D5KaG5BgVIYn zMyu%H!iLuYfF@=x@lY1m`DD91Bk7Dc@*)eA5h5LOtBMQ5N^WacQdD zoq=;aNz@1%3RgVF$HIaTWjjKXF2;n6s4V8{-@?occP{S_@Er7Ej`|K2>p2Z9IXIYe z^0Ea?{JvS<{B;MWE68mi$et*yz%zY1(H8yZIDQiH^Rvn+&d(yut$bz@!j5IMiOPGH z5mW8*g80K7TAn(}wmZLAc}wS{zGr8BX0GjnRhKxSH*<}VIBCIU1s%4T`u*C?ovt(V zA*W+qL%en6Ta=ymor#D58(4OpTLz?UVl{SFC(8|9U1t_@_CCa8x_h^~8YzXvoqlK2 z-K%42f2Cv+{u4EfRfX=nXJ^Y#b=RxrZ_dhW6uWWxppWBS#&%d5zm|)?QABlrML!E_ zEn6y}K9eLT9qcU1Hc*hCC^n@2(1xmRt?vD3IuBdUSlJoA>EP!P%vh#gOOr&=trf#O z+ILlh*we&q{S7~sXrrE%H*qjJQCX0H^^#JONZlC??~}gd;v$Lgt4iH%Xb?MXq3sgy z_xOGfTD_y~9}pm;`~)XIo9M7n`LP?7CFAQk7Sg$2Zp_V5NS=C1qG-OU_Qo|Jz!-|p z;kmh5&+ritaw>@HE&u02J@0W>R9x!*) zvh})RA3Qv3aFmyQSS;$hI98tSpwYMdZd8br+)0Fe9F-$9#Q`3H^;|J^$3b%P=I_xC ze&s3GTh{_v!$*)}blIK(kyh}Ir-!lgLDsh6$KMNO97Zw}hSFg8G{U8v;q1%{_o}b8 z&0Qz2xahFeq?fEZydZwVM5~jkJ`gGQV?nlV;_Xk>+fnfrEDXh{p7ytoQ(tcDA*-g5 z(&hMA^FCYU{?94fVOy{R^`b1@&+K`x%aI)c{(sgj!-r@SA4zQ5agysq!VISGifrjM zAt$#(F={>iJ8MfOO3^k{upMAF)JPP^nlY92HD{zQY$W+*WvcD24`Q_2?!Be$gRDiX zTfbTmLX2KNV_|P$HQCs^;`ujQKF5T6-M$Gm$~nD%CXf2X%6=bJXX3qfk4K!Vi;*f4 zPAX(+I{Iy<{41i9#L?`xTz2gNRBek_&1&>&a(iXEKpY?1Ok^1wiit_;cxqPnOwYHb zV$56I<3TUZqaiXkCy8$`RugbAlhQ#_{B=X>wG(pn`h%5tklwZ~-rIMhpAR#Xvi;dnc7 zzdp_`O&HPmdnUbdE#{4g(CjUq0xJ!3$iAF=u7j&xZi1#0gbw;4-rnhI*0xYZ-fZGe zXA@!v50|M(Rv}rxoE)QmL(S^z0F{Ynr1QoB{DZqsP;veKBd@n)L*=a>5W3lIj(hGL z7hXjBdR184e#zbon{7xaH4oWPjG}|q2{<@#Sz$)W-34eXE0eiF_P9DJnY$GjXvA}( zFtCPcVi!WKzq+fQs1gP!83lMm#8h<&&#T^^8PoLXi-{RXKkd_&Bz$}e3!2(9OZG)s zg@u_)O5(%sZBC#5XlpApNsaCH+A;uTiA)=awG9wYe=Kvs5jTtBea$;gf`qh6c@4HM zbrYvnyKIN>uWz=ue9Bb|rLOQ^*l2-uoV(A}4o zj~K~otQgBx0liyS#}&dWRmD*s$uVPq>zk473OCt=DF7It>;$&xZM zS>(XA-YZe|7JSnn5R=p2T!3x6rLm}^g{GBN9@Y7ZU)BEnMxX4q9B;gzoS6yjnHH6LslR~ubBG25G5x!alLZ`h+v%)@ zJL+I`O}#D9=AAP~PBL7HQ%X#hkZnhzh}Di^9sx9yZn5X=?Cb}1$x((py&-;vtU22VwF`rKI%x{?O&}pD*(i)5a1>y5p(YK zwbeJLqw>pD54+VpSLupldV1aj-uMJCvq$rR$-h3YCb`P@2uRDQ+!!9Ok27Tng$WGf z&2R-44!(_E-iU+I@y4frpGr>dge5{8}mm)u~{3A%l zcdl5VAkr*k-aj6|Kz+Yd5|fO2A???sqjOl;zm3*i%HR2wzTMJ7n6e|hUpm!(FAG*7 z5%guAryhG4chdgnNLSthI6kL8-&j9|;2gVGF98I#wFrx>-=8c%ajLVi7ic~Cs|Dsx zw`n_(u-5BGCk;-YYezp!O__NC!3040#5}aKvnJqyFp%3JWC0T3U|kkYWKO`;?AiSc zgRShnG!8xzPJIfQw6xxWMf~cEPE1>>H0^~VyF~tXFPKMqkdxk^n&u7m1z@SA6~h+q z^E3I~R~-h}&qI3Mv|k-3ehyF)Awkv9*Yuq?r7r0Tub}UFU5ds=U;D;k;zXGWzaGF` zT1v6lWe&gXSz*7nei552{jWy?K(x1xR?%GH zIvsYrfcy#2mei z_23UKe7coSZ(OoLIDF~PpO=5NUAudWJPD{tRf)p7x;;0Z0emrhD<>%I@RPLH($FcL zYNi*-O(AlvoV+yM0Z)C<5StuZsalu;7>9i!*do3e_DSm&9)GN`?dCA)_E4@}5vFY1$re5l<40*UlIM zCnqNX>Gy$Bs;N>(n}at`^x6YRu-IZHzyv5CG&pU})U9HbvZAgQX^3}zZ0^mg21K>t zF#BmEL6+o-#zsptvdIg-A&IkTH7l`#8VqXPWal;>Dz4|kd$YtMfH#$+w7md0Tdn&^ zt!@J>LXai82sUe|OP!5XsOv*^ZdyQU6=Zi9`ebD=Ix)pzZQra|!&+oeLLOQh`CvWf zE|!=`FP~BR6qr65ih7#G<7y7tfce;qBSxPe4*eVeQYl6;nneTXbfM+jtV_G?t_h=< zJR|tTk{O`;gm27Z#*>AG?@XYlYZez(=u3w5tv;ImXIoH|D9xXN{b-;$iPRRJ?&gf_ z>>M{I@quWN-svJ%Hpt|_d-}_ldt^1rvO=pEJ`RUlLEt6^~ormrsKLEJG9^+ z14NP!I&0Yab1b;T44Nh-DH$>3IrL18w_Um~fVl5MEEbttK-kAq~i z;a+?ygIhV^qxO9OY~75^^f|~<3ijl`Z6ImQQI64Ft4Ajg5(GTS7#(_6F{Bj0 zsWa_#WEHDEfHv-W_*mWwcu|uy=ej_rtB5MNzA!7c7+#T+y{gX^Q2XeC&5+`;vKr+=0mU8E({Ek z*;g-OX_+N#kE~~NysiI%EHW@QL>uB^9`Qc+y{zCp+3b$O4o~ye>UQFtpTR zLUCs&bTZhuC&!kGfwOn(>`O<~$-Z?iUi0QM_9~P_NjOZp6Yaw{xj7pkYT$_26Rw~} zv{yMM6~oML<>n?8i_=A9@uTZ39Mu$( zdG&^skMiuBYGujaDpvEFsX0+oPNxY?-XRf1_WYJB;yGO6xM#0P3w2`HV>90pjY5akX#w zm=7wd8jVrOhZW7u+R?V`TO8B9KZ|=%Pu9fdbA}w-Bt(QG-gtSNH^x!jmQs-^iUQAn zcqCZq4DDg$fB zlsAG_%erBouKn(7D0WiaPc!D?Nn660JNOb1qM8l9c9WKw!W}UM;=l%Ce_l7$fxMA$ z09J*(zk}#vOZds>{TP8w(|*79A{l@31g!QC`8 zzOt6cClyU?jLkH>25x@=61qaqfgm`M52ITCKs*M(&3sF#4`3K9^WHt@DNxInX%8k&@=XF ztWoezJT2>JLNbsTmgTm!GVL?9Eru@Lt79V^CA|O=bx0vgX2ROb_31rt*14D4TYY7UYb`Lbx$)}R*;gCcVdmwA zNMFE^CZ{amjU}E&yOWxvD(HFLy(_%@)h!B@vTcuB7e7Ih`8>UDe}v~8AH2clVrzTu zg^$oGd)sDdqskzI?+*o;@}ZO5pMce1D_E}i%?L*eK;vp+3%j(;1l)%nT$gG-I@6w99GvW#+u?B4>bN*dm$< zi%82%U2E0#rXf(ZDO5kJbO99E#wO`9@pFO0uQNZ8W2|*zDg!Axot}BItC&ylJPoFM zO!1!?$-V4*Bpg&V>V8uSwBxX`=Guw1DD_|B^}lLR|1&N9--uUN{)5B~C2c#257h5l z-vr4~4dV~y1Bd(Y0bU&`MR~(&&UH3`hz1$}qV-G3OlmP8o4}R5(7J?}$n(8BJ3jx^ zX||fP1L_u_hyzL(DC>1_nG_%z02KdQt#dZgFpQ_O^G85(P&vn!s_PLNDyLdP5fk`V zyuXRbdE(E-GysAA!U6!&E}HE#@z&YAZMY1&APWe)9#Ri?oO$`d z!lMxp5z?}<*)?4hYFU7|OE^4aX}#VHD2{r3OxVrM!VnNI4#;Ck;#Tf&OlC@-Zm<0- z8Y?LLDWKy81B&tAijV6|8ApT6n2n8~-#_mgnV4WsMnFT7%R{8s_U%lvA z_2*KFv;h(#y?lK$mvG|WQ6QVLmA%h@B_AoN?+Oh}Rw*D`37~g%b$5Y2RRHn|a`4w4 zXlMxHK+ninQB#vls-B9;YYKFFjm3Haaj6h9O&_q!V(?e)d!hiGMjWZsBTdPxYi{05E P;G?HytXZx8==uKwg!*yp diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png index 29d2e83ccf0c23a541b1653713aee4080a001d27..2439b81f0bb752f85d7c0f73a1a1a6cb06e01405 100644 GIT binary patch literal 12239 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 literal 12111 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

H>*Sz5UI+nH5x&Bk#`vX+HqWPx!pMvtN zJG}{>yzwf7gU*nr9@YsSUIv@~XkX>Xw58v3BZJ;qHd0vO2X6ph#%k-!zI_UalCQ zl>lMWy{7h4Zqv<%;N`tt+JiXwhFPt6fevQoQwD9|*OkA6j6FqMU`1}X+C?Q3J2Y)z zaTTK=1yTdEHcY@>Su3oX*fkL{l5He>W2f{=v53tjbr9v;v=iS^ zoo|(@)wKALwbS8_sPl~w;{EdWO&LCOAg7?R`BrVc6x(+1-fuGlqIt}YAj1eOntObu zH+f_=;BrQRaj`zaaB1iL_>sOzl3J#r1mb(LB(^@kQ>h0ib-KJ@M37GI=zi`OvVe6a{iSbu@0LNO0XKTY(9im%XUe#L@Vz3^xEuPVXoIB4~=kZ4|+#8?yI;x{RTXbHgs#LoF@z5}TS(1u^NTKZPteTvx z6%mA$eTknnecwr`e+2Y>mN{=27LVL?v3Y(P*qP6QtkoxoRTMOkLM)a{e0L1|6ZV3A z;IwJc{cDVlueufh2OY>M0Z3#q_N?u%LIcGaGOUaz6zVx(+yEzY_iP*Pt*)pOL0|e8 zxy(jpFv6Fmrg0=YIr--=`n^)@m+@5zbx*O+Q34B68N#a}3h{iq4V2;2Ab?5dU_R)k z9Ic!0+8%FU_YR|u=D~E&sN)0h3iV)Jb&czNz{&rI#h4V`&6@=YOf2WIY@mtD1h0EX zeg-dpa1?G<6dcI`FxC^LWLF8$y6)JEr!N6Y8dLor40VSCz(fPIbQ!`J zn*_R>gR<`bn;Q`X;pGl5G2A_m&H(c*K~lBwj*S$_DRdaomN~sgCsbr~B|%YWa7$*fI70 z4<&DRUjbGajjjmN)XIe9D7*fZ1c%6*QO zJ;p}xf94`0aW6Ygy}rm}E^#jPDiHN0FZT)Pl!6X2F;IejZJLb$!CES-rB<)+>6yR9 zvK$pm|EF2K|DvMs-%bAy!T#?m=Kmjxx3`ZO^h*b+#>q2PAmB36Gt;fSeK+>M0XMV) AhX4Qo diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png index 99265680388ad7695cab725d12f416c85f29625e..382c565a0abae62534cd03f79e4f273757963f66 100644 GIT binary patch literal 13372 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 reactionIcons, }) { - return MaterialApp( - debugShowCheckedModeBanner: false, - home: StreamChatConfiguration( - data: StreamChatConfigurationData(reactionIcons: reactionIcons), - child: StreamChatTheme( - data: StreamChatThemeData(brightness: brightness), - child: Builder(builder: (context) { - final theme = StreamChatTheme.of(context); - return Scaffold( - backgroundColor: theme.colorTheme.appBg, - body: ColoredBox( - color: theme.colorTheme.overlay, - child: Padding( - padding: const EdgeInsets.all(8), - child: child, + return Portal( + child: MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChatConfiguration( + data: StreamChatConfigurationData(reactionIcons: reactionIcons), + child: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: ColoredBox( + color: theme.colorTheme.overlay, + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), ), - ), - ); - }), + ); + }), + ), ), ), ); diff --git a/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart index ab4362c81f..2b942ad0de 100644 --- a/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart +++ b/packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart @@ -1,5 +1,6 @@ import 'package:alchemist/alchemist.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -182,21 +183,18 @@ void main() { final theme = StreamChatTheme.of(context); final messageTheme = theme.getMessageTheme(reverse: reverse); - return Align( - alignment: reverse ? Alignment.centerRight : Alignment.centerLeft, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 8, - horizontal: 16, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(14), - color: messageTheme.messageBackgroundColor, - ), - child: Text( - message.text ?? '', - style: messageTheme.messageTextStyle, - ), + return Container( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 16, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14), + color: messageTheme.messageBackgroundColor, + ), + child: Text( + message.text ?? '', + style: messageTheme.messageTextStyle, ), ); }, @@ -246,29 +244,31 @@ Widget _wrapWithMaterialApp( Brightness? brightness, List? reactionIcons, }) { - return MaterialApp( - debugShowCheckedModeBanner: false, - home: StreamChat( - client: client, - // Mock the connectivity stream to always return wifi. - connectivityStream: Stream.value([ConnectivityResult.wifi]), - child: StreamChatConfiguration( - data: StreamChatConfigurationData(reactionIcons: reactionIcons), - child: StreamChatTheme( - data: StreamChatThemeData(brightness: brightness), - child: Builder(builder: (context) { - final theme = StreamChatTheme.of(context); - return Scaffold( - backgroundColor: theme.colorTheme.appBg, - body: ColoredBox( - color: theme.colorTheme.overlay, - child: Padding( - padding: const EdgeInsets.all(8), - child: child, + return Portal( + child: MaterialApp( + debugShowCheckedModeBanner: false, + home: StreamChat( + client: client, + // Mock the connectivity stream to always return wifi. + connectivityStream: Stream.value([ConnectivityResult.wifi]), + child: StreamChatConfiguration( + data: StreamChatConfigurationData(reactionIcons: reactionIcons), + child: StreamChatTheme( + data: StreamChatThemeData(brightness: brightness), + child: Builder(builder: (context) { + final theme = StreamChatTheme.of(context); + return Scaffold( + backgroundColor: theme.colorTheme.appBg, + body: ColoredBox( + color: theme.colorTheme.overlay, + child: Padding( + padding: const EdgeInsets.all(8), + child: child, + ), ), - ), - ); - }), + ); + }), + ), ), ), ), diff --git a/packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart b/packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart index 4dbb51949a..0c86fc637c 100644 --- a/packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart +++ b/packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart @@ -59,7 +59,7 @@ void main() { type: reactionIcons.first.type, builder: reactionIcons.first.builder, ), - onPressed: (type) {}, + onPressed: () {}, ), ), ); @@ -81,7 +81,7 @@ void main() { type: reactionIcons.first.type, builder: reactionIcons.first.builder, ), - onPressed: (type) { + onPressed: () { callbackTriggered = true; }, ), @@ -110,7 +110,7 @@ void main() { type: reactionIcons.first.type, builder: reactionIcons.first.builder, ), - onPressed: (type) {}, + onPressed: () {}, ), ), ); @@ -127,7 +127,7 @@ void main() { type: reactionIcons.first.type, builder: reactionIcons.first.builder, ), - onPressed: (type) {}, + onPressed: () {}, ), ), ); From d2aabea7415b52ac8a39b6c32a633d4eee921d63 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Tue, 17 Jun 2025 16:55:50 +0200 Subject: [PATCH 05/34] chore(ui): make `CustomMessageAction` extendable --- .../message_action/message_action_type.dart | 2 +- sample_app/lib/pages/channel_page.dart | 146 ++++++++++++------ 2 files changed, 99 insertions(+), 49 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart b/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart index 4f4ceb4cef..5aea4980b1 100644 --- a/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart +++ b/packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart @@ -125,7 +125,7 @@ final class ThreadReply extends MessageAction { /// Custom message action that allows for additional data to be passed /// along with the message. -final class CustomMessageAction extends MessageAction { +class CustomMessageAction extends MessageAction { /// Create a new custom message action const CustomMessageAction({ required super.message, diff --git a/sample_app/lib/pages/channel_page.dart b/sample_app/lib/pages/channel_page.dart index 8a9bdbe57a..baf8e01108 100644 --- a/sample_app/lib/pages/channel_page.dart +++ b/sample_app/lib/pages/channel_page.dart @@ -152,23 +152,7 @@ class _ChannelPageState extends State { color: colorTheme.textLowEmphasis, ), title: const Text('Edit Reminder'), - onTap: (message) async { - Navigator.of(context).pop(); - - final option = await showDialog( - context: context, - builder: (_) => EditReminderDialog( - isBookmarkReminder: reminder.remindAt == null, - ), - ); - - if (option == null) return; - final client = StreamChat.of(context).client; - final messageId = message.id; - final remindAt = option.remindAt; - - client.updateReminder(messageId, remindAt: remindAt).ignore(); - }, + action: EditReminder(message: message, reminder: reminder), ), StreamMessageAction( leading: StreamSvgIcon( @@ -176,14 +160,7 @@ class _ChannelPageState extends State { color: colorTheme.textLowEmphasis, ), title: const Text('Remove from later'), - onTap: (message) { - Navigator.of(context).pop(); - - final client = StreamChat.of(context).client; - final messageId = message.id; - - client.deleteReminder(messageId).ignore(); - }, + action: RemoveReminder(message: message, reminder: reminder), ), ] else ...[ StreamMessageAction( @@ -192,21 +169,7 @@ class _ChannelPageState extends State { color: colorTheme.textLowEmphasis, ), title: const Text('Remind me'), - onTap: (message) async { - Navigator.of(context).pop(); - - final reminder = await showDialog( - context: context, - builder: (_) => const CreateReminderDialog(), - ); - - if (reminder == null) return; - final client = StreamChat.of(context).client; - final messageId = message.id; - final remindAt = reminder.remindAt; - - client.createReminder(messageId, remindAt: remindAt).ignore(); - }, + action: CreateReminder(message: message), ), StreamMessageAction( leading: Icon( @@ -214,14 +177,7 @@ class _ChannelPageState extends State { color: colorTheme.textLowEmphasis, ), title: const Text('Save for later'), - onTap: (message) { - Navigator.of(context).pop(); - - final client = StreamChat.of(context).client; - final messageId = message.id; - - client.createReminder(messageId).ignore(); - }, + action: CreateBookmark(message: message), ), ], ] @@ -263,6 +219,13 @@ class _ChannelPageState extends State { defaultMessageWidget.copyWith( onReplyTap: _reply, customActions: customOptions, + onCustomActionTap: (it) async => await switch (it) { + CreateReminder() => _createReminder(it.message), + CreateBookmark() => _createBookmark(it.message), + EditReminder() => _editReminder(it.message, it.reminder), + RemoveReminder() => _removeReminder(it.message, it.reminder), + _ => null, + }, onShowMessage: (message, channel) => GoRouter.of(context).goNamed( Routes.CHANNEL_PAGE.name, pathParameters: Routes.CHANNEL_PAGE.params(channel), @@ -283,6 +246,56 @@ class _ChannelPageState extends State { ); } + Future _editReminder( + Message message, + MessageReminder reminder, + ) async { + final option = await showDialog( + context: context, + builder: (_) => EditReminderDialog( + isBookmarkReminder: reminder.remindAt == null, + ), + ); + + if (option == null) return; + final client = StreamChat.of(context).client; + final messageId = message.id; + final remindAt = option.remindAt; + + return client.updateReminder(messageId, remindAt: remindAt).ignore(); + } + + Future _removeReminder( + Message message, + MessageReminder reminder, + ) async { + final client = StreamChat.of(context).client; + final messageId = message.id; + + return client.deleteReminder(messageId).ignore(); + } + + Future _createReminder(Message message) async { + final reminder = await showDialog( + context: context, + builder: (_) => const CreateReminderDialog(), + ); + + if (reminder == null) return; + final client = StreamChat.of(context).client; + final messageId = message.id; + final remindAt = reminder.remindAt; + + return client.createReminder(messageId, remindAt: remindAt).ignore(); + } + + Future _createBookmark(Message message) async { + final client = StreamChat.of(context).client; + final messageId = message.id; + + return client.createReminder(messageId).ignore(); + } + bool defaultFilter(Message m) { final currentUser = StreamChat.of(context).currentUser; final isMyMessage = m.user?.id == currentUser?.id; @@ -291,3 +304,40 @@ class _ChannelPageState extends State { return true; } } + +class ReminderMessageAction extends CustomMessageAction { + const ReminderMessageAction({ + required super.message, + this.reminder, + }); + + final MessageReminder? reminder; +} + +final class CreateReminder extends ReminderMessageAction { + const CreateReminder({required super.message}); +} + +final class CreateBookmark extends ReminderMessageAction { + const CreateBookmark({required super.message}); +} + +final class EditReminder extends ReminderMessageAction { + const EditReminder({ + required super.message, + required this.reminder, + }) : super(reminder: reminder); + + @override + final MessageReminder reminder; +} + +final class RemoveReminder extends ReminderMessageAction { + const RemoveReminder({ + required super.message, + required this.reminder, + }) : super(reminder: reminder); + + @override + final MessageReminder reminder; +} From f9d454c028f74a1d3cc230c3c2cde33df58652df Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 18 Jun 2025 14:45:31 +0200 Subject: [PATCH 06/34] chore(repo): add migration guide --- migrations/v10-migration.md | 256 ++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 migrations/v10-migration.md diff --git a/migrations/v10-migration.md b/migrations/v10-migration.md new file mode 100644 index 0000000000..56f083d56a --- /dev/null +++ b/migrations/v10-migration.md @@ -0,0 +1,256 @@ +# 🚀 Flutter SDK v10.0 Migration Guide + +**Important!** This guide details breaking changes in **SDK v10.0**. Carefully follow each step to ensure a smooth and efficient migration. + +--- + +## 📋 Breaking Changes Overview + +This guide includes breaking changes grouped by release phase: + +### 🚧 v10.0.0-beta.1 + +- [**StreamReactionPicker**](#-streamreactionpicker-refactor) +- [**StreamMessageAction**](#-streammessageaction-refactor) +- [**StreamMessageReactionsModal**](#-streammessagereactionsmodal-refactor) +- [**StreamMessageWidget**](#-streammessagewidget-refactor) + +--- + +## 🧪 Migration for v10.0.0-beta.1 + +### 🛠 StreamReactionPicker Refactor + +The reaction picker has been refactored for modularity, flexibility, and explicit reaction handling. + +### Key Changes: +**Key Changes:** +- New `StreamReactionPicker.builder` constructor +- Added properties: `padding`, `scrollable`, `borderRadius` +- Removed automatic reaction handling → use `onReactionPicked` + +### Migration Steps: + +**Before:** +```dart +StreamReactionPicker( + message: message, +); +``` + +**After (Recommended using Builder):** +```dart +StreamReactionPicker.builder( + context, + message, + (Reaction reaction) { + // Explicitly handle reaction here + }, +); +``` + +**After (Alternative Direct Configuration):** +```dart +StreamReactionPicker( + message: message, + reactionIcons: StreamChatConfiguration.of(context).reactionIcons, + onReactionPicked: (Reaction reaction) { + // Explicit reaction handling + }, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + scrollable: true, + borderRadius: BorderRadius.circular(24), +); +``` + +> ⚠️ **Important:** +> Automatic reaction handling has been removed. You must explicitly handle reactions. + +### Summary of Changes: + +| Aspect | Previous | New Behavior | +|------------------------|---------------|----------------------------------------------| +| Reaction Handling | Automatic | Explicit (`onReactionPicked`) | +| Platform Constructor | None | Yes (`StreamReactionPicker.builder`) | +| Customization | Limited | Enhanced (`padding`, `borderRadius`, `scrollable`) | + +--- + +## ✅ StreamMessageAction Refactor + +The `StreamMessageAction` is refactored for type safety, centralization, and enhanced customization. + +### Key Changes: +- **Type-safe Actions:** Now generic (`StreamMessageAction`) for stronger typing. +- **Centralized Action Handling:** Individual action callbacks replaced with centralized handling via `onCustomActionTap`. +- **Customization Options:** New props: + - `isDestructive`: Flag destructive actions. + - `iconColor`: Customize icon color. + - `titleTextColor`: Title color customization. + - `titleTextStyle`: Title text styling. + - `backgroundColor`: Background color customization. + +### Migration Steps: + +**Before:** +```dart +final customAction = StreamMessageAction( + title: Text('Custom Action'), + leading: Icon(Icons.settings), + onTap: (Message message) { + // Handle action + }, +); + +StreamMessageWidget( + message: message, + customActions: [customAction], +); +``` + +**After (Recommended - Type-safe):** +```dart +final customAction = StreamMessageAction( + action: CustomMessageAction( + message: message, + extraData: {'type': 'custom_action'}, + ), + title: Text('Custom Action'), + leading: Icon(Icons.settings), + isDestructive: false, + iconColor: Colors.blue, +); + +StreamMessageWidget( + message: message, + customActions: [customAction], + onCustomActionTap: (CustomMessageAction action) { + // Handle action based on extraData + }, +); +``` + +> ⚠️ **Important:** +> Individual `onTap` callbacks have been removed. Always use centralized `onCustomActionTap`. + +### Summary of Changes: + +| Aspect | Previous | New Behavior | +|------------------|--------------------------------|------------------------------------------| +| Action Typing | Untyped | Generic (type-safe) | +| Action Handling | Individual `onTap` callbacks | Centralized (`onCustomActionTap`) | +| Customization | Limited | Enhanced (`iconColor`, `backgroundColor`, etc.) | + +--- + +## ✅ StreamMessageReactionsModal Refactor + +Refactored to leverage `StreamMessageModal`, improving consistency and explicit reaction handling. + +### Key Changes: +- **Base Widget Changed:** Now uses `StreamMessageModal` internally. +- **Removed `messageTheme` Property:** Theme now automatically derived from `reverse`. +- **Explicit Reaction Handling:** Reactions must be handled explicitly through `onReactionPicked`. + +### Migration Steps: + +**Step 1: Remove `messageTheme`:** +```dart +// Before +StreamMessageReactionsModal( + message: message, + messageWidget: myMessageWidget, + messageTheme: myCustomMessageTheme, // remove this + reverse: true, +); + +// After +StreamMessageReactionsModal( + message: message, + messageWidget: myMessageWidget, + reverse: true, +); +``` + +**Step 2: Explicit Reaction Handling:** +```dart +// Before (automatic handling) +StreamMessageReactionsModal( + message: message, + messageWidget: myMessageWidget, + // reactions handled internally +); + +// After (explicit handling) +StreamMessageReactionsModal( + message: message, + messageWidget: myMessageWidget, + onReactionPicked: (SelectReaction reactionAction) { + // Explicitly send or delete reaction + }, +); +``` + +> ⚠️ **Important:** +> Automatic handling is removed—explicit reaction handling required. + +### Summary of Changes: + +| Aspect | Previous | New Behavior | +|--------------------|---------------------------|------------------------------------| +| Reaction Handling | Automatic | Explicit (`onReactionPicked`) | +| Base Widget | Custom implementation | Uses `StreamMessageModal` | +| `messageTheme` Prop| Required | Removed; derived from `reverse` | + +--- + +## ✅ StreamMessageWidget Refactor + +The `StreamMessageWidget` has been simplified by removing the `showReactionTail` parameter and always showing the reaction picker tail when the reaction picker is visible. + +### Key Changes: +- **Removed `showReactionTail` Parameter:** The parameter is no longer needed as the tail is always shown when the reaction picker is visible. +- **Automatic Tail Display:** The reaction picker tail now automatically appears when the reaction picker is visible, providing consistent UX. + +### Migration Steps: + +**Before:** +```dart +StreamMessageWidget( + message: message, + showReactionTail: true, // Remove this parameter +); + +// or + +StreamMessageWidget( + message: message, + showReactionTail: false, // Remove this parameter +); +``` + +**After:** +```dart +StreamMessageWidget( + message: message, + // showReactionTail parameter removed - tail shown automatically +); +``` + +> ⚠️ **Important:** +> The `showReactionTail` parameter has been completely removed. The reaction picker tail will always be shown when the reaction picker is visible, ensuring consistent behavior across your app. + +### Summary of Changes: + +| Aspect | Previous | New Behavior | +|------------------------|-----------------------------------|----------------------------------------------| +| Tail Display Control | Manual (`showReactionTail`) | Automatic (always shown when picker visible) | +| Parameter Required | Optional boolean parameter | Parameter removed | +| Consistency | Could be inconsistent | Always consistent | + +--- + +✅ **You're ready to migrate!** +Ensure you test your application thoroughly after applying these changes. + +--- From 5a2dc40319db77744045df4887f9c380d09d23b5 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 18 Jun 2025 14:46:19 +0200 Subject: [PATCH 07/34] chore(repo): update CHANGELOG.md --- packages/stream_chat_flutter/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 99ea8ad764..44e7f04a94 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -7,7 +7,7 @@ - `StreamMessageReactionsModal` no longer requires the `messageTheme` parameter. The theme now automatically derives from the `reverse` property. - `StreamMessageWidget` no longer requires the `showReactionTail` parameter. The reaction picker tail is now always shown when the reaction picker is visible. -For more details, please refer to the [migration guide](Unpublished). +For more details, please refer to the [migration guide](../../migrations/v10-migration.md). ✅ Added From 76debfdbb2c018bb8485db8135d04b6fa8366791 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 18 Jun 2025 14:49:50 +0200 Subject: [PATCH 08/34] chore(repo): update migration guide --- migrations/v10-migration.md | 166 +++++++++++------------------------- 1 file changed, 49 insertions(+), 117 deletions(-) diff --git a/migrations/v10-migration.md b/migrations/v10-migration.md index 56f083d56a..61a1fc0062 100644 --- a/migrations/v10-migration.md +++ b/migrations/v10-migration.md @@ -1,6 +1,6 @@ -# 🚀 Flutter SDK v10.0 Migration Guide +# 🚀 Flutter SDK v10 Migration Guide -**Important!** This guide details breaking changes in **SDK v10.0**. Carefully follow each step to ensure a smooth and efficient migration. +**Important!** This guide outlines all breaking changes introduced in the Flutter SDK **v10.0.0** release, including pre-release stages like `v10.0.0-beta.1`. Follow each section based on the version you're migrating from. --- @@ -10,26 +10,24 @@ This guide includes breaking changes grouped by release phase: ### 🚧 v10.0.0-beta.1 -- [**StreamReactionPicker**](#-streamreactionpicker-refactor) -- [**StreamMessageAction**](#-streammessageaction-refactor) -- [**StreamMessageReactionsModal**](#-streammessagereactionsmodal-refactor) -- [**StreamMessageWidget**](#-streammessagewidget-refactor) +- [StreamReactionPicker](#-streamreactionpicker) +- [StreamMessageAction](#-streammessageaction) +- [StreamMessageReactionsModal](#-streammessagereactionsmodal) +- [StreamMessageWidget](#-streammessagewidget) --- ## 🧪 Migration for v10.0.0-beta.1 -### 🛠 StreamReactionPicker Refactor +### 🛠 StreamReactionPicker -The reaction picker has been refactored for modularity, flexibility, and explicit reaction handling. +#### Key Changes: -### Key Changes: -**Key Changes:** - New `StreamReactionPicker.builder` constructor - Added properties: `padding`, `scrollable`, `borderRadius` -- Removed automatic reaction handling → use `onReactionPicked` +- Automatic reaction handling removed — must now use `onReactionPicked` -### Migration Steps: +#### Migration Steps: **Before:** ```dart @@ -38,24 +36,24 @@ StreamReactionPicker( ); ``` -**After (Recommended using Builder):** +**After (Recommended – Builder):** ```dart StreamReactionPicker.builder( context, message, (Reaction reaction) { - // Explicitly handle reaction here + // Explicitly handle reaction }, ); ``` -**After (Alternative Direct Configuration):** +**After (Alternative – Direct Configuration):** ```dart StreamReactionPicker( message: message, reactionIcons: StreamChatConfiguration.of(context).reactionIcons, onReactionPicked: (Reaction reaction) { - // Explicit reaction handling + // Handle reaction here }, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), scrollable: true, @@ -64,51 +62,32 @@ StreamReactionPicker( ``` > ⚠️ **Important:** -> Automatic reaction handling has been removed. You must explicitly handle reactions. - -### Summary of Changes: - -| Aspect | Previous | New Behavior | -|------------------------|---------------|----------------------------------------------| -| Reaction Handling | Automatic | Explicit (`onReactionPicked`) | -| Platform Constructor | None | Yes (`StreamReactionPicker.builder`) | -| Customization | Limited | Enhanced (`padding`, `borderRadius`, `scrollable`) | +> Automatic reaction handling has been removed. You must explicitly handle reactions using `onReactionPicked`. --- -## ✅ StreamMessageAction Refactor +### 🛠 StreamMessageAction -The `StreamMessageAction` is refactored for type safety, centralization, and enhanced customization. +#### Key Changes: -### Key Changes: -- **Type-safe Actions:** Now generic (`StreamMessageAction`) for stronger typing. -- **Centralized Action Handling:** Individual action callbacks replaced with centralized handling via `onCustomActionTap`. -- **Customization Options:** New props: - - `isDestructive`: Flag destructive actions. - - `iconColor`: Customize icon color. - - `titleTextColor`: Title color customization. - - `titleTextStyle`: Title text styling. - - `backgroundColor`: Background color customization. +- Now generic: `StreamMessageAction` +- Individual `onTap` handlers removed — use `onCustomActionTap` instead +- Added new styling props for better customization -### Migration Steps: +#### Migration Steps: **Before:** ```dart final customAction = StreamMessageAction( title: Text('Custom Action'), leading: Icon(Icons.settings), - onTap: (Message message) { + onTap: (message) { // Handle action }, ); - -StreamMessageWidget( - message: message, - customActions: [customAction], -); ``` -**After (Recommended - Type-safe):** +**After (Type-safe):** ```dart final customAction = StreamMessageAction( action: CustomMessageAction( @@ -125,107 +104,67 @@ StreamMessageWidget( message: message, customActions: [customAction], onCustomActionTap: (CustomMessageAction action) { - // Handle action based on extraData + // Handle action here }, ); ``` > ⚠️ **Important:** -> Individual `onTap` callbacks have been removed. Always use centralized `onCustomActionTap`. - -### Summary of Changes: - -| Aspect | Previous | New Behavior | -|------------------|--------------------------------|------------------------------------------| -| Action Typing | Untyped | Generic (type-safe) | -| Action Handling | Individual `onTap` callbacks | Centralized (`onCustomActionTap`) | -| Customization | Limited | Enhanced (`iconColor`, `backgroundColor`, etc.) | +> Individual `onTap` callbacks have been removed. Always handle actions using the centralized `onCustomActionTap`. --- -## ✅ StreamMessageReactionsModal Refactor +### 🛠 StreamMessageReactionsModal -Refactored to leverage `StreamMessageModal`, improving consistency and explicit reaction handling. +#### Key Changes: -### Key Changes: -- **Base Widget Changed:** Now uses `StreamMessageModal` internally. -- **Removed `messageTheme` Property:** Theme now automatically derived from `reverse`. -- **Explicit Reaction Handling:** Reactions must be handled explicitly through `onReactionPicked`. +- Based on `StreamMessageModal` for consistency +- `messageTheme` removed — inferred automatically +- Reaction handling must now be handled via `onReactionPicked` -### Migration Steps: +#### Migration Steps: -**Step 1: Remove `messageTheme`:** +**Before:** ```dart -// Before -StreamMessageReactionsModal( - message: message, - messageWidget: myMessageWidget, - messageTheme: myCustomMessageTheme, // remove this - reverse: true, -); - -// After StreamMessageReactionsModal( message: message, messageWidget: myMessageWidget, + messageTheme: myCustomMessageTheme, reverse: true, ); ``` -**Step 2: Explicit Reaction Handling:** +**After:** ```dart -// Before (automatic handling) -StreamMessageReactionsModal( - message: message, - messageWidget: myMessageWidget, - // reactions handled internally -); - -// After (explicit handling) StreamMessageReactionsModal( message: message, messageWidget: myMessageWidget, + reverse: true, onReactionPicked: (SelectReaction reactionAction) { - // Explicitly send or delete reaction + // Handle reaction explicitly }, ); ``` > ⚠️ **Important:** -> Automatic handling is removed—explicit reaction handling required. - -### Summary of Changes: - -| Aspect | Previous | New Behavior | -|--------------------|---------------------------|------------------------------------| -| Reaction Handling | Automatic | Explicit (`onReactionPicked`) | -| Base Widget | Custom implementation | Uses `StreamMessageModal` | -| `messageTheme` Prop| Required | Removed; derived from `reverse` | +> `messageTheme` has been removed. Reaction handling must now be explicit using `onReactionPicked`. --- -## ✅ StreamMessageWidget Refactor +### 🛠 StreamMessageWidget -The `StreamMessageWidget` has been simplified by removing the `showReactionTail` parameter and always showing the reaction picker tail when the reaction picker is visible. +#### Key Changes: -### Key Changes: -- **Removed `showReactionTail` Parameter:** The parameter is no longer needed as the tail is always shown when the reaction picker is visible. -- **Automatic Tail Display:** The reaction picker tail now automatically appears when the reaction picker is visible, providing consistent UX. +- `showReactionTail` parameter has been removed +- Tail now automatically shows when the picker is visible -### Migration Steps: +#### Migration Steps: **Before:** ```dart StreamMessageWidget( message: message, - showReactionTail: true, // Remove this parameter -); - -// or - -StreamMessageWidget( - message: message, - showReactionTail: false, // Remove this parameter + showReactionTail: true, ); ``` @@ -233,24 +172,17 @@ StreamMessageWidget( ```dart StreamMessageWidget( message: message, - // showReactionTail parameter removed - tail shown automatically ); ``` > ⚠️ **Important:** -> The `showReactionTail` parameter has been completely removed. The reaction picker tail will always be shown when the reaction picker is visible, ensuring consistent behavior across your app. - -### Summary of Changes: - -| Aspect | Previous | New Behavior | -|------------------------|-----------------------------------|----------------------------------------------| -| Tail Display Control | Manual (`showReactionTail`) | Automatic (always shown when picker visible) | -| Parameter Required | Optional boolean parameter | Parameter removed | -| Consistency | Could be inconsistent | Always consistent | +> The `showReactionTail` parameter is no longer supported. Tail is now always shown when the picker is visible. --- -✅ **You're ready to migrate!** -Ensure you test your application thoroughly after applying these changes. +## 🎉 You're Ready to Migrate! ---- +- ✅ Use `StreamReactionPicker.builder` or supply `onReactionPicked` +- ✅ Convert all `StreamMessageAction` instances to type-safe generic usage +- ✅ Centralize handling with `onCustomActionTap` +- ✅ Remove deprecated props like `showReactionTail` and `messageTheme` From 75d9d17f2b02d8da853a71ff08ab78c7d260aefe Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 18 Jun 2025 15:13:46 +0200 Subject: [PATCH 09/34] chore(repo): release v10.0.0-beta.1 (#2283) --- melos.yaml | 10 +++++----- packages/stream_chat/CHANGELOG.md | 4 ++++ packages/stream_chat/example/pubspec.yaml | 2 +- packages/stream_chat/lib/version.dart | 2 +- packages/stream_chat/pubspec.yaml | 2 +- packages/stream_chat_flutter/CHANGELOG.md | 2 +- packages/stream_chat_flutter/example/pubspec.yaml | 6 +++--- packages/stream_chat_flutter/pubspec.yaml | 4 ++-- packages/stream_chat_flutter_core/CHANGELOG.md | 4 ++++ packages/stream_chat_flutter_core/example/pubspec.yaml | 2 +- packages/stream_chat_flutter_core/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/CHANGELOG.md | 4 ++++ .../stream_chat_localizations/example/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/CHANGELOG.md | 4 ++++ packages/stream_chat_persistence/example/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/pubspec.yaml | 4 ++-- sample_app/pubspec.yaml | 6 +++--- 18 files changed, 44 insertions(+), 28 deletions(-) diff --git a/melos.yaml b/melos.yaml index 1808f97714..9f7e32834c 100644 --- a/melos.yaml +++ b/melos.yaml @@ -80,11 +80,11 @@ command: share_plus: ^11.0.0 shimmer: ^3.0.0 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^9.12.0 - stream_chat_flutter: ^9.12.0 - stream_chat_flutter_core: ^9.12.0 - stream_chat_localizations: ^9.12.0 - stream_chat_persistence: ^9.12.0 + stream_chat: ^10.0.0-beta.1 + stream_chat_flutter: ^10.0.0-beta.1 + stream_chat_flutter_core: ^10.0.0-beta.1 + stream_chat_localizations: ^10.0.0-beta.1 + stream_chat_persistence: ^10.0.0-beta.1 streaming_shared_preferences: ^2.0.0 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index ecce475e63..3cf50ec003 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.1 + +- Bug fixes and improvements + ## 9.12.0 ✅ Added diff --git a/packages/stream_chat/example/pubspec.yaml b/packages/stream_chat/example/pubspec.yaml index 91f6e6f05b..cd6224d39d 100644 --- a/packages/stream_chat/example/pubspec.yaml +++ b/packages/stream_chat/example/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^9.12.0 + stream_chat: ^10.0.0-beta.1 flutter: uses-material-design: true diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index 4793e6786b..06ca748e00 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -9,4 +9,4 @@ /// Current package version /// Used in [SystemEnvironmentManager] to build the `x-stream-client` header -const PACKAGE_VERSION = '9.12.0'; +const PACKAGE_VERSION = '10.0.0-beta.1'; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index 31fd90de08..22dc553efb 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat homepage: https://getstream.io/ description: The official Dart client for Stream Chat, a service for building chat applications. -version: 9.12.0 +version: 10.0.0-beta.1 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 44e7f04a94..bea0aa027b 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.1 🛑️ Breaking diff --git a/packages/stream_chat_flutter/example/pubspec.yaml b/packages/stream_chat_flutter/example/pubspec.yaml index 2c3dd4b7ab..f97a7da471 100644 --- a/packages/stream_chat_flutter/example/pubspec.yaml +++ b/packages/stream_chat_flutter/example/pubspec.yaml @@ -25,9 +25,9 @@ dependencies: flutter: sdk: flutter responsive_builder: ^0.7.0 - stream_chat_flutter: ^9.12.0 - stream_chat_localizations: ^9.12.0 - stream_chat_persistence: ^9.12.0 + stream_chat_flutter: ^10.0.0-beta.1 + stream_chat_localizations: ^10.0.0-beta.1 + stream_chat_persistence: ^10.0.0-beta.1 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 912e52269d..5fdd3f761b 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 9.12.0 +version: 10.0.0-beta.1 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -56,7 +56,7 @@ dependencies: rxdart: ^0.28.0 share_plus: ^11.0.0 shimmer: ^3.0.0 - stream_chat_flutter_core: ^9.12.0 + stream_chat_flutter_core: ^10.0.0-beta.1 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 781350449d..adb1a4d72d 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.1 + +- Updated `stream_chat` dependency to [`10.0.0-beta.1`](https://pub.dev/packages/stream_chat/changelog). + ## 9.12.0 ✅ Added diff --git a/packages/stream_chat_flutter_core/example/pubspec.yaml b/packages/stream_chat_flutter_core/example/pubspec.yaml index 288c3d83df..43f8bfc7af 100644 --- a/packages/stream_chat_flutter_core/example/pubspec.yaml +++ b/packages/stream_chat_flutter_core/example/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter_core: ^9.12.0 + stream_chat_flutter_core: ^10.0.0-beta.1 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index 6caa2eee83..1382a05af5 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter_core homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. -version: 9.12.0 +version: 10.0.0-beta.1 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -31,7 +31,7 @@ dependencies: meta: ^1.9.1 package_info_plus: ^8.3.0 rxdart: ^0.28.0 - stream_chat: ^9.12.0 + stream_chat: ^10.0.0-beta.1 dev_dependencies: build_runner: ^2.4.9 diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 4b73d6a21e..5c38648bce 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.1 + +- Updated `stream_chat_flutter` dependency to [`10.0.0-beta.1`](https://pub.dev/packages/stream_chat_flutter/changelog). + ## 9.12.0 - Updated `stream_chat_flutter` dependency to [`9.12.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_localizations/example/pubspec.yaml b/packages/stream_chat_localizations/example/pubspec.yaml index 20cb187fed..0a862ff842 100644 --- a/packages/stream_chat_localizations/example/pubspec.yaml +++ b/packages/stream_chat_localizations/example/pubspec.yaml @@ -24,8 +24,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter: ^9.12.0 - stream_chat_localizations: ^9.12.0 + stream_chat_flutter: ^10.0.0-beta.1 + stream_chat_localizations: ^10.0.0-beta.1 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_localizations/pubspec.yaml b/packages/stream_chat_localizations/pubspec.yaml index 6effbba1be..3ba3e2c659 100644 --- a/packages/stream_chat_localizations/pubspec.yaml +++ b/packages/stream_chat_localizations/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_chat_localizations description: The Official localizations for Stream Chat Flutter, a service for building chat applications -version: 9.12.0 +version: 10.0.0-beta.1 homepage: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -26,7 +26,7 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - stream_chat_flutter: ^9.12.0 + stream_chat_flutter: ^10.0.0-beta.1 dev_dependencies: flutter_test: diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 229c7e634e..8473c01bef 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.1 + +- Updated `stream_chat` dependency to [`10.0.0-beta.1`](https://pub.dev/packages/stream_chat/changelog). + ## 9.12.0 - Updated `stream_chat` dependency to [`9.12.0`](https://pub.dev/packages/stream_chat/changelog). diff --git a/packages/stream_chat_persistence/example/pubspec.yaml b/packages/stream_chat_persistence/example/pubspec.yaml index 07bb28c423..1487dc0d50 100644 --- a/packages/stream_chat_persistence/example/pubspec.yaml +++ b/packages/stream_chat_persistence/example/pubspec.yaml @@ -23,8 +23,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^9.12.0 - stream_chat_persistence: ^9.12.0 + stream_chat: ^10.0.0-beta.1 + stream_chat_persistence: ^10.0.0-beta.1 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index e12887d920..818bb59ced 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_persistence homepage: https://github.com/GetStream/stream-chat-flutter description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. -version: 9.12.0 +version: 10.0.0-beta.1 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -30,7 +30,7 @@ dependencies: path: ^1.8.3 path_provider: ^2.1.3 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^9.12.0 + stream_chat: ^10.0.0-beta.1 dev_dependencies: build_runner: ^2.4.9 diff --git a/sample_app/pubspec.yaml b/sample_app/pubspec.yaml index 0ef3357ff9..ccb7a547f9 100644 --- a/sample_app/pubspec.yaml +++ b/sample_app/pubspec.yaml @@ -34,9 +34,9 @@ dependencies: lottie: ^3.1.2 provider: ^6.0.5 sentry_flutter: ^8.3.0 - stream_chat_flutter: ^9.12.0 - stream_chat_localizations: ^9.12.0 - stream_chat_persistence: ^9.12.0 + stream_chat_flutter: ^10.0.0-beta.1 + stream_chat_localizations: ^10.0.0-beta.1 + stream_chat_persistence: ^10.0.0-beta.1 streaming_shared_preferences: ^2.0.0 uuid: ^4.4.0 video_player: ^2.8.7 From 0ffdd7c85773a614e2389e47311dc6d42d92e1d8 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Mon, 30 Jun 2025 12:30:50 +0200 Subject: [PATCH 10/34] chore: include latest stable release in beta changelogs --- packages/stream_chat/CHANGELOG.md | 8 ++++++-- packages/stream_chat_flutter/CHANGELOG.md | 4 ++++ packages/stream_chat_flutter_core/CHANGELOG.md | 4 ++++ packages/stream_chat_localizations/CHANGELOG.md | 8 ++++++-- packages/stream_chat_persistence/CHANGELOG.md | 8 ++++++-- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index b884e96c1d..34d5a28375 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,11 +1,15 @@ -## 10.0.0-beta.1 +## Upcoming Beta -- Bug fixes and improvements +- Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat/changelog). ## 9.13.0 - Bug fixes and improvements +## 10.0.0-beta.1 + +- Bug fixes and improvements + ## 9.12.0 ✅ Added diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 06b4958ea9..1ef1b50dd0 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## Upcoming Beta + +- Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_flutter/changelog). + ## 9.13.0 🐞 Fixed diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 225dfdc97e..6c3e1ccf74 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,7 @@ +## Upcoming Beta + +- Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog). + ## 9.13.0 🐞 Fixed diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 4de8a930f9..3aaee8a330 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,11 +1,15 @@ -## 10.0.0-beta.1 +## Upcoming Beta -- Updated `stream_chat_flutter` dependency to [`10.0.0-beta.1`](https://pub.dev/packages/stream_chat_flutter/changelog). +- Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_localizations/changelog). ## 9.13.0 - Updated `stream_chat_flutter` dependency to [`9.13.0`](https://pub.dev/packages/stream_chat_flutter/changelog). +## 10.0.0-beta.1 + +- Updated `stream_chat_flutter` dependency to [`10.0.0-beta.1`](https://pub.dev/packages/stream_chat_flutter/changelog). + ## 9.12.0 - Updated `stream_chat_flutter` dependency to [`9.12.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 6cac378809..547560aa46 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,11 +1,15 @@ -## 10.0.0-beta.1 +## Upcoming Beta -- Updated `stream_chat` dependency to [`10.0.0-beta.1`](https://pub.dev/packages/stream_chat/changelog). +- Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_persistence/changelog). ## 9.13.0 - Updated `stream_chat` dependency to [`9.13.0`](https://pub.dev/packages/stream_chat/changelog). +## 10.0.0-beta.1 + +- Updated `stream_chat` dependency to [`10.0.0-beta.1`](https://pub.dev/packages/stream_chat/changelog). + ## 9.12.0 - Updated `stream_chat` dependency to [`9.12.0`](https://pub.dev/packages/stream_chat/changelog). From 8c8dbd25132f114c3e1c2e37155896552a253d2b Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Mon, 30 Jun 2025 12:44:11 +0200 Subject: [PATCH 11/34] chore(repo): release v10.0.0-beta.2 (#2292) --- melos.yaml | 10 +++++----- packages/stream_chat/CHANGELOG.md | 2 +- packages/stream_chat/example/pubspec.yaml | 2 +- packages/stream_chat/lib/version.dart | 2 +- packages/stream_chat/pubspec.yaml | 2 +- packages/stream_chat_flutter/CHANGELOG.md | 2 +- packages/stream_chat_flutter/example/pubspec.yaml | 6 +++--- packages/stream_chat_flutter/pubspec.yaml | 4 ++-- packages/stream_chat_flutter_core/CHANGELOG.md | 2 +- packages/stream_chat_flutter_core/example/pubspec.yaml | 2 +- packages/stream_chat_flutter_core/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/CHANGELOG.md | 2 +- .../stream_chat_localizations/example/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/CHANGELOG.md | 2 +- packages/stream_chat_persistence/example/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/pubspec.yaml | 4 ++-- sample_app/pubspec.yaml | 6 +++--- 18 files changed, 32 insertions(+), 32 deletions(-) diff --git a/melos.yaml b/melos.yaml index 9f7e32834c..b3abdab213 100644 --- a/melos.yaml +++ b/melos.yaml @@ -80,11 +80,11 @@ command: share_plus: ^11.0.0 shimmer: ^3.0.0 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.1 - stream_chat_flutter: ^10.0.0-beta.1 - stream_chat_flutter_core: ^10.0.0-beta.1 - stream_chat_localizations: ^10.0.0-beta.1 - stream_chat_persistence: ^10.0.0-beta.1 + stream_chat: ^10.0.0-beta.2 + stream_chat_flutter: ^10.0.0-beta.2 + stream_chat_flutter_core: ^10.0.0-beta.2 + stream_chat_localizations: ^10.0.0-beta.2 + stream_chat_persistence: ^10.0.0-beta.2 streaming_shared_preferences: ^2.0.0 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 34d5a28375..381b1529b3 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.2 - Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat/changelog). diff --git a/packages/stream_chat/example/pubspec.yaml b/packages/stream_chat/example/pubspec.yaml index cd6224d39d..2dac7f5e7c 100644 --- a/packages/stream_chat/example/pubspec.yaml +++ b/packages/stream_chat/example/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.1 + stream_chat: ^10.0.0-beta.2 flutter: uses-material-design: true diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index 06ca748e00..77fc35ca06 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -9,4 +9,4 @@ /// Current package version /// Used in [SystemEnvironmentManager] to build the `x-stream-client` header -const PACKAGE_VERSION = '10.0.0-beta.1'; +const PACKAGE_VERSION = '10.0.0-beta.2'; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index 22dc553efb..fcdee2bc68 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat homepage: https://getstream.io/ description: The official Dart client for Stream Chat, a service for building chat applications. -version: 10.0.0-beta.1 +version: 10.0.0-beta.2 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 1ef1b50dd0..ba571d20b6 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.2 - Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_flutter/example/pubspec.yaml b/packages/stream_chat_flutter/example/pubspec.yaml index f97a7da471..41ac689903 100644 --- a/packages/stream_chat_flutter/example/pubspec.yaml +++ b/packages/stream_chat_flutter/example/pubspec.yaml @@ -25,9 +25,9 @@ dependencies: flutter: sdk: flutter responsive_builder: ^0.7.0 - stream_chat_flutter: ^10.0.0-beta.1 - stream_chat_localizations: ^10.0.0-beta.1 - stream_chat_persistence: ^10.0.0-beta.1 + stream_chat_flutter: ^10.0.0-beta.2 + stream_chat_localizations: ^10.0.0-beta.2 + stream_chat_persistence: ^10.0.0-beta.2 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 5fdd3f761b..b8459010a0 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.1 +version: 10.0.0-beta.2 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -56,7 +56,7 @@ dependencies: rxdart: ^0.28.0 share_plus: ^11.0.0 shimmer: ^3.0.0 - stream_chat_flutter_core: ^10.0.0-beta.1 + stream_chat_flutter_core: ^10.0.0-beta.2 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 6c3e1ccf74..1f9c55f5bb 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.2 - Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog). diff --git a/packages/stream_chat_flutter_core/example/pubspec.yaml b/packages/stream_chat_flutter_core/example/pubspec.yaml index 43f8bfc7af..0abb614d50 100644 --- a/packages/stream_chat_flutter_core/example/pubspec.yaml +++ b/packages/stream_chat_flutter_core/example/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter_core: ^10.0.0-beta.1 + stream_chat_flutter_core: ^10.0.0-beta.2 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index 1382a05af5..d39763cc79 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter_core homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.1 +version: 10.0.0-beta.2 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -31,7 +31,7 @@ dependencies: meta: ^1.9.1 package_info_plus: ^8.3.0 rxdart: ^0.28.0 - stream_chat: ^10.0.0-beta.1 + stream_chat: ^10.0.0-beta.2 dev_dependencies: build_runner: ^2.4.9 diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 3aaee8a330..fabcc714cb 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.2 - Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_localizations/changelog). diff --git a/packages/stream_chat_localizations/example/pubspec.yaml b/packages/stream_chat_localizations/example/pubspec.yaml index 0a862ff842..298679e12e 100644 --- a/packages/stream_chat_localizations/example/pubspec.yaml +++ b/packages/stream_chat_localizations/example/pubspec.yaml @@ -24,8 +24,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.1 - stream_chat_localizations: ^10.0.0-beta.1 + stream_chat_flutter: ^10.0.0-beta.2 + stream_chat_localizations: ^10.0.0-beta.2 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_localizations/pubspec.yaml b/packages/stream_chat_localizations/pubspec.yaml index 3ba3e2c659..93d68bd522 100644 --- a/packages/stream_chat_localizations/pubspec.yaml +++ b/packages/stream_chat_localizations/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_chat_localizations description: The Official localizations for Stream Chat Flutter, a service for building chat applications -version: 10.0.0-beta.1 +version: 10.0.0-beta.2 homepage: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -26,7 +26,7 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.1 + stream_chat_flutter: ^10.0.0-beta.2 dev_dependencies: flutter_test: diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 547560aa46..5ff047fc4e 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.2 - Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_persistence/changelog). diff --git a/packages/stream_chat_persistence/example/pubspec.yaml b/packages/stream_chat_persistence/example/pubspec.yaml index 1487dc0d50..0b52b8f1fa 100644 --- a/packages/stream_chat_persistence/example/pubspec.yaml +++ b/packages/stream_chat_persistence/example/pubspec.yaml @@ -23,8 +23,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.1 - stream_chat_persistence: ^10.0.0-beta.1 + stream_chat: ^10.0.0-beta.2 + stream_chat_persistence: ^10.0.0-beta.2 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index 818bb59ced..800a1a0923 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_persistence homepage: https://github.com/GetStream/stream-chat-flutter description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.1 +version: 10.0.0-beta.2 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -30,7 +30,7 @@ dependencies: path: ^1.8.3 path_provider: ^2.1.3 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.1 + stream_chat: ^10.0.0-beta.2 dev_dependencies: build_runner: ^2.4.9 diff --git a/sample_app/pubspec.yaml b/sample_app/pubspec.yaml index ccb7a547f9..960ae43812 100644 --- a/sample_app/pubspec.yaml +++ b/sample_app/pubspec.yaml @@ -34,9 +34,9 @@ dependencies: lottie: ^3.1.2 provider: ^6.0.5 sentry_flutter: ^8.3.0 - stream_chat_flutter: ^10.0.0-beta.1 - stream_chat_localizations: ^10.0.0-beta.1 - stream_chat_persistence: ^10.0.0-beta.1 + stream_chat_flutter: ^10.0.0-beta.2 + stream_chat_localizations: ^10.0.0-beta.2 + stream_chat_persistence: ^10.0.0-beta.2 streaming_shared_preferences: ^2.0.0 uuid: ^4.4.0 video_player: ^2.8.7 From 74bb46036d531d0adbe2fccafa1bb43c1f8ba40f Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 3 Jul 2025 16:13:38 +0200 Subject: [PATCH 12/34] feat(ui)!: refactor poll message into attachment (#2296) --- packages/stream_chat_flutter/CHANGELOG.md | 8 +++ .../lib/src/attachment/attachment.dart | 3 + .../attachment/attachment_widget_catalog.dart | 5 -- .../builder/attachment_widget_builder.dart | 12 +++- .../builder/poll_attachment_builder.dart | 55 +++++++++++++++++++ .../poll_attachment.dart} | 43 ++++++++++----- .../voice_recording_attachment_playlist.dart | 1 - .../lib/src/message_widget/message_card.dart | 44 +++++---------- .../src/message_widget/message_widget.dart | 6 -- .../message_widget_content.dart | 5 -- .../lib/stream_chat_flutter.dart | 1 - ...ce_recording_attachment_playlist_test.dart | 1 - .../voice_recording_attachment_test.dart | 1 - 13 files changed, 120 insertions(+), 65 deletions(-) create mode 100644 packages/stream_chat_flutter/lib/src/attachment/builder/poll_attachment_builder.dart rename packages/stream_chat_flutter/lib/src/{message_widget/poll_message.dart => attachment/poll_attachment.dart} (78%) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index ba571d20b6..afc8f5517b 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,11 @@ +## Upcoming Beta + +🛑️ Breaking + +- `PollMessage` widget has been removed and replaced with `PollAttachment` for better integration + with the attachment system. Polls can now be customized through `PollAttachmentBuilder` or by + creating custom poll attachment widgets via the attachment builder system. + ## 10.0.0-beta.2 - Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_flutter/lib/src/attachment/attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/attachment.dart index 0b73a93c7c..bbc818e9b5 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/attachment.dart @@ -3,5 +3,8 @@ export 'file_attachment.dart'; export 'gallery_attachment.dart'; export 'giphy_attachment.dart'; export 'image_attachment.dart'; +export 'poll_attachment.dart'; export 'url_attachment.dart'; export 'video_attachment.dart'; +export 'voice_recording_attachment.dart'; +export 'voice_recording_attachment_playlist.dart'; diff --git a/packages/stream_chat_flutter/lib/src/attachment/attachment_widget_catalog.dart b/packages/stream_chat_flutter/lib/src/attachment/attachment_widget_catalog.dart index 5e51c7333b..78c0ba1f52 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/attachment_widget_catalog.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/attachment_widget_catalog.dart @@ -37,11 +37,6 @@ class AttachmentWidgetCatalog { Widget build(BuildContext context, Message message) { assert(!message.isDeleted, 'Cannot build attachment for deleted message'); - assert( - message.attachments.isNotEmpty, - 'Cannot build attachment for message without attachments', - ); - // The list of attachments to build the widget for. final attachments = message.attachments.grouped; for (final builder in builders) { diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart index bbdc950ba0..64382b2d28 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart @@ -12,6 +12,7 @@ part 'url_attachment_builder.dart'; part 'video_attachment_builder.dart'; part 'voice_recording_attachment_playlist_builder.dart'; part 'voice_recording_attachment_builder/voice_recording_attachment_builder.dart'; +part 'poll_attachment_builder.dart'; /// {@template streamAttachmentWidgetTapCallback} /// Signature for a function that's called when the user taps on an attachment. @@ -43,6 +44,8 @@ abstract class StreamAttachmentWidgetBuilder { /// * [FileAttachmentBuilder] /// * [ImageAttachmentBuilder] /// * [VideoAttachmentBuilder] + /// * [VoiceRecordingAttachmentPlaylistBuilder] + /// * [PollAttachmentBuilder] /// * [UrlAttachmentBuilder] /// * [FallbackAttachmentBuilder] /// @@ -72,7 +75,14 @@ abstract class StreamAttachmentWidgetBuilder { return [ ...?customAttachmentBuilders, - // Handles a mix of image, gif, video, url and file attachments. + // Handles poll attachments. + PollAttachmentBuilder( + shape: shape, + padding: padding, + ), + + // Handles a mix of image, gif, video, url, file and voice recording + // attachments. MixedAttachmentBuilder( padding: padding, onAttachmentTap: onAttachmentTap, diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/poll_attachment_builder.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/poll_attachment_builder.dart new file mode 100644 index 0000000000..53066b0c64 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/attachment/builder/poll_attachment_builder.dart @@ -0,0 +1,55 @@ +part of 'attachment_widget_builder.dart'; + +const _kDefaultPollMessageConstraints = BoxConstraints( + maxWidth: 270, +); + +/// {@template pollAttachmentBuilder} +/// A widget builder for Poll attachment type. +/// +/// This builder is used when a message contains a poll. +/// {@endtemplate} +class PollAttachmentBuilder extends StreamAttachmentWidgetBuilder { + /// {@macro urlAttachmentBuilder} + const PollAttachmentBuilder({ + this.shape, + this.padding = const EdgeInsets.all(8), + this.constraints = _kDefaultPollMessageConstraints, + }); + + /// The shape of the poll attachment. + final ShapeBorder? shape; + + /// The constraints to apply to the poll attachment widget. + final BoxConstraints constraints; + + /// The padding to apply to the poll attachment widget. + final EdgeInsetsGeometry padding; + + @override + bool canHandle( + Message message, + Map> attachments, + ) { + final poll = message.poll; + return poll != null; + } + + @override + Widget build( + BuildContext context, + Message message, + Map> attachments, + ) { + assert(debugAssertCanHandle(message, attachments), ''); + + return Padding( + padding: padding, + child: PollAttachment( + message: message, + shape: shape, + constraints: constraints, + ), + ); + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_widget/poll_message.dart b/packages/stream_chat_flutter/lib/src/attachment/poll_attachment.dart similarity index 78% rename from packages/stream_chat_flutter/lib/src/message_widget/poll_message.dart rename to packages/stream_chat_flutter/lib/src/attachment/poll_attachment.dart index aec0646c78..231d4ad455 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/poll_message.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/poll_attachment.dart @@ -8,38 +8,41 @@ import 'package:stream_chat_flutter/src/poll/stream_poll_comments_dialog.dart'; import 'package:stream_chat_flutter/src/poll/stream_poll_options_dialog.dart'; import 'package:stream_chat_flutter/src/poll/stream_poll_results_dialog.dart'; import 'package:stream_chat_flutter/src/stream_chat.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; const _maxVisibleOptionCount = 10; -const _kDefaultPollMessageConstraints = BoxConstraints( - maxWidth: 270, -); - /// {@template pollMessage} -/// A widget that displays a poll message. -/// -/// Used in [MessageCard] to display a poll message. +/// A widget that displays a message poll attachment in a [StreamMessageWidget]. /// {@endtemplate} -class PollMessage extends StatefulWidget { +class PollAttachment extends StatefulWidget { /// {@macro pollMessage} - const PollMessage({ + const PollAttachment({ super.key, required this.message, + this.shape, + this.constraints = const BoxConstraints(), }); /// The message with the poll to display. final Message message; + /// The shape of the poll attachment. + final ShapeBorder? shape; + + /// The constraints to apply to the poll attachment widget. + final BoxConstraints constraints; + @override - State createState() => _PollMessageState(); + State createState() => _PollAttachmentState(); } -class _PollMessageState extends State { +class _PollAttachmentState extends State { late final _messageNotifier = ValueNotifier(widget.message); @override - void didUpdateWidget(covariant PollMessage oldWidget) { + void didUpdateWidget(covariant PollAttachment oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.message != widget.message) { // If the message changes, schedule an update for the next frame @@ -57,6 +60,17 @@ class _PollMessageState extends State { @override Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + + final shape = widget.shape ?? + RoundedRectangleBorder( + side: BorderSide( + color: theme.colorTheme.borders, + strokeAlign: BorderSide.strokeAlignOutside, + ), + borderRadius: BorderRadius.circular(14), + ); + return ValueListenableBuilder( valueListenable: _messageNotifier, builder: (context, message, child) { @@ -96,8 +110,9 @@ class _PollMessageState extends State { channel.createPollOption(poll, PollOption(text: optionText)); } - return ConstrainedBox( - constraints: _kDefaultPollMessageConstraints, + return Container( + constraints: widget.constraints, + decoration: ShapeDecoration(shape: shape), child: StreamPollInteractor( poll: poll, currentUser: currentUser, diff --git a/packages/stream_chat_flutter/lib/src/attachment/voice_recording_attachment_playlist.dart b/packages/stream_chat_flutter/lib/src/attachment/voice_recording_attachment_playlist.dart index d4bb67c0f7..2bd55a8023 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/voice_recording_attachment_playlist.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/voice_recording_attachment_playlist.dart @@ -1,6 +1,5 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/attachment/voice_recording_attachment.dart'; import 'package:stream_chat_flutter/src/audio/audio_playlist_controller.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart index b60db28f10..6a0e214faa 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_card.dart @@ -17,7 +17,6 @@ class MessageCard extends StatefulWidget { required this.hasQuotedMessage, required this.hasUrlAttachments, required this.hasNonUrlAttachments, - required this.hasPoll, required this.isOnlyEmoji, required this.isGiphy, required this.attachmentBuilders, @@ -66,9 +65,6 @@ class MessageCard extends StatefulWidget { /// {@macro hasNonUrlAttachments} final bool hasNonUrlAttachments; - /// {@macro hasPoll} - final bool hasPoll; - /// {@macro isOnlyEmoji} final bool isOnlyEmoji; @@ -128,10 +124,6 @@ class _MessageCardState extends State { final attachmentsKey = GlobalKey(); double? widthLimit; - bool get hasAttachments { - return widget.hasUrlAttachments || widget.hasNonUrlAttachments; - } - void _updateWidthLimit() { final attachmentContext = attachmentsKey.currentContext; final renderBox = attachmentContext?.findRenderObject() as RenderBox?; @@ -150,11 +142,9 @@ class _MessageCardState extends State { // If there is an attachment, we need to wait for the attachment to be // rendered to get the width of the attachment and set it as the width // limit of the message card. - if (hasAttachments) { - WidgetsBinding.instance.addPostFrameCallback((_) { - _updateWidthLimit(); - }); - } + WidgetsBinding.instance.addPostFrameCallback((_) { + _updateWidthLimit(); + }); } @override @@ -201,23 +191,17 @@ class _MessageCardState extends State { hasNonUrlAttachments: widget.hasNonUrlAttachments, ), ), - if (hasAttachments) - ParseAttachments( - key: attachmentsKey, - message: widget.message, - attachmentBuilders: widget.attachmentBuilders, - attachmentPadding: widget.attachmentPadding, - attachmentShape: widget.attachmentShape, - onAttachmentTap: widget.onAttachmentTap, - onShowMessage: widget.onShowMessage, - onReplyTap: widget.onReplyTap, - attachmentActionsModalBuilder: - widget.attachmentActionsModalBuilder, - ), - if (widget.hasPoll) - PollMessage( - message: widget.message, - ), + ParseAttachments( + key: attachmentsKey, + message: widget.message, + attachmentBuilders: widget.attachmentBuilders, + attachmentPadding: widget.attachmentPadding, + attachmentShape: widget.attachmentShape, + onAttachmentTap: widget.onAttachmentTap, + onShowMessage: widget.onShowMessage, + onReplyTap: widget.onReplyTap, + attachmentActionsModalBuilder: widget.attachmentActionsModalBuilder, + ), TextBubble( messageTheme: widget.messageTheme, message: widget.message, diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index a5408c404a..1e871fd7a2 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -600,11 +600,6 @@ class _StreamMessageWidgetState extends State bool get hasNonUrlAttachments => widget.message.attachments .any((it) => it.type != AttachmentType.urlPreview); - /// {@template hasPoll} - /// `true` if the [message] contains a poll. - /// {@endtemplate} - bool get hasPoll => widget.message.poll != null; - /// {@template hasUrlAttachments} /// `true` if any of the [message]'s attachments are a giphy with a /// [Attachment.titleLink]. @@ -719,7 +714,6 @@ class _StreamMessageWidgetState extends State reverse: widget.reverse, message: widget.message, hasNonUrlAttachments: hasNonUrlAttachments, - hasPoll: hasPoll, hasQuotedMessage: hasQuotedMessage, textPadding: widget.textPadding, attachmentBuilders: widget.attachmentBuilders, diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart index dbf9b99ba6..1bdd74812c 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart @@ -42,7 +42,6 @@ class MessageWidgetContent extends StatelessWidget { required this.hasQuotedMessage, required this.hasUrlAttachments, required this.hasNonUrlAttachments, - required this.hasPoll, required this.isOnlyEmoji, required this.isGiphy, required this.attachmentBuilders, @@ -137,9 +136,6 @@ class MessageWidgetContent extends StatelessWidget { /// {@macro hasNonUrlAttachments} final bool hasNonUrlAttachments; - /// {@macro hasPoll} - final bool hasPoll; - /// {@macro isOnlyEmoji} final bool isOnlyEmoji; @@ -363,7 +359,6 @@ class MessageWidgetContent extends StatelessWidget { hasQuotedMessage: hasQuotedMessage, hasUrlAttachments: hasUrlAttachments, hasNonUrlAttachments: hasNonUrlAttachments, - hasPoll: hasPoll, isOnlyEmoji: isOnlyEmoji, isGiphy: isGiphy, attachmentBuilders: attachmentBuilders, diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 8d581e796f..0f47afb664 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -79,7 +79,6 @@ export 'src/message_widget/message_text.dart'; export 'src/message_widget/message_widget.dart'; export 'src/message_widget/message_widget_content_components.dart'; export 'src/message_widget/moderated_message.dart'; -export 'src/message_widget/poll_message.dart'; export 'src/message_widget/system_message.dart'; export 'src/message_widget/text_bubble.dart'; export 'src/misc/adaptive_dialog_action.dart'; diff --git a/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_playlist_test.dart b/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_playlist_test.dart index 0f6786f3bb..fc3ffd107a 100644 --- a/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_playlist_test.dart +++ b/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_playlist_test.dart @@ -1,7 +1,6 @@ import 'package:alchemist/alchemist.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:stream_chat_flutter/src/attachment/voice_recording_attachment.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import '../mocks.dart'; diff --git a/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_test.dart b/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_test.dart index ef95e4b220..529e14f133 100644 --- a/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_test.dart +++ b/packages/stream_chat_flutter/test/src/attachment/voice_recording_attachment_test.dart @@ -2,7 +2,6 @@ import 'package:alchemist/alchemist.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:stream_chat_flutter/src/attachment/voice_recording_attachment.dart'; import 'package:stream_chat_flutter/src/audio/audio_playlist_state.dart'; import 'package:stream_chat_flutter/src/misc/audio_waveform.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; From cc69eb37c6873891cbce7536af4344e545c747c1 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 10 Jul 2025 16:46:03 +0200 Subject: [PATCH 13/34] refactor(llc): introduce event controller, resolver (#2301) --- .../stream_chat/lib/src/client/client.dart | 22 +++--- .../lib/src/client/event_resolvers.dart | 37 +++++++++ .../lib/src/core/util/event_controller.dart | 77 +++++++++++++++++++ packages/stream_chat/test/src/mocks.dart | 4 +- 4 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 packages/stream_chat/lib/src/client/event_resolvers.dart create mode 100644 packages/stream_chat/lib/src/core/util/event_controller.dart diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index f848182cfa..a55530ef8a 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -5,6 +5,7 @@ import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; import 'package:rxdart/rxdart.dart'; import 'package:stream_chat/src/client/channel.dart'; +import 'package:stream_chat/src/client/event_resolvers.dart' as event_resolvers; import 'package:stream_chat/src/client/retry_policy.dart'; import 'package:stream_chat/src/core/api/attachment_file_uploader.dart'; import 'package:stream_chat/src/core/api/requests.dart'; @@ -33,6 +34,7 @@ import 'package:stream_chat/src/core/models/poll_option.dart'; import 'package:stream_chat/src/core/models/poll_vote.dart'; import 'package:stream_chat/src/core/models/thread.dart'; import 'package:stream_chat/src/core/models/user.dart'; +import 'package:stream_chat/src/core/util/event_controller.dart'; import 'package:stream_chat/src/core/util/utils.dart'; import 'package:stream_chat/src/db/chat_persistence_client.dart'; import 'package:stream_chat/src/event_type.dart'; @@ -222,21 +224,15 @@ class StreamChatClient { StreamSubscription? _connectionStatusSubscription; - final _eventController = PublishSubject(); - /// Stream of [Event] coming from [_ws] connection /// Listen to this or use the [on] method to filter specific event types - Stream get eventStream => _eventController.stream.map( - // If the poll vote is an answer, we should emit a different event - // to make it easier to handle in the state. - (event) => switch ((event.type, event.pollVote?.isAnswer == true)) { - (EventType.pollVoteCasted || EventType.pollVoteChanged, true) => - event.copyWith(type: EventType.pollAnswerCasted), - (EventType.pollVoteRemoved, true) => - event.copyWith(type: EventType.pollAnswerRemoved), - _ => event, - }, - ); + Stream get eventStream => _eventController.stream; + late final _eventController = EventController( + resolvers: [ + event_resolvers.pollAnswerCastedResolver, + event_resolvers.pollAnswerRemovedResolver, + ], + ); final _wsConnectionStatusController = BehaviorSubject.seeded(ConnectionStatus.disconnected); diff --git a/packages/stream_chat/lib/src/client/event_resolvers.dart b/packages/stream_chat/lib/src/client/event_resolvers.dart new file mode 100644 index 0000000000..fc2117fb58 --- /dev/null +++ b/packages/stream_chat/lib/src/client/event_resolvers.dart @@ -0,0 +1,37 @@ +import 'package:stream_chat/src/core/models/event.dart'; +import 'package:stream_chat/src/event_type.dart'; + +/// Resolves casted or changed poll vote events into more specific +/// `pollAnswerCasted` events for easier downstream state handling. +/// +/// Applies when: +/// - `event.type` is `pollVoteCasted` or `pollVoteChanged`, and +/// - `event.pollVote?.isAnswer == true` +/// +/// Returns a modified event with type `pollAnswerCasted`, +/// or `null` if not applicable. +Event? pollAnswerCastedResolver(Event event) { + return switch (event.type) { + EventType.pollVoteCasted || + EventType.pollVoteChanged when event.pollVote?.isAnswer == true => + event.copyWith(type: EventType.pollAnswerCasted), + _ => null, + }; +} + +/// Resolves removed poll vote events into more specific +/// `pollAnswerRemoved` events for easier downstream state handling. +/// +/// Applies when: +/// - `event.type` is `pollVoteRemoved`, and +/// - `event.pollVote?.isAnswer == true` +/// +/// Returns a modified event with type `pollAnswerRemoved`, +/// or `null` if not applicable. +Event? pollAnswerRemovedResolver(Event event) { + return switch (event.type) { + EventType.pollVoteRemoved when event.pollVote?.isAnswer == true => + event.copyWith(type: EventType.pollAnswerRemoved), + _ => null, + }; +} diff --git a/packages/stream_chat/lib/src/core/util/event_controller.dart b/packages/stream_chat/lib/src/core/util/event_controller.dart new file mode 100644 index 0000000000..4e98d33b9a --- /dev/null +++ b/packages/stream_chat/lib/src/core/util/event_controller.dart @@ -0,0 +1,77 @@ +import 'dart:async'; +import 'package:rxdart/rxdart.dart'; +import 'package:stream_chat/src/core/models/event.dart'; + +/// A function that inspects an event and optionally resolves it into a +/// more specific or refined version of the same type. +/// +/// If the resolver does not recognize or handle the event, +/// it returns `null`, allowing other resolvers to attempt resolution. +typedef EventResolver = T? Function(T event); + +/// {@template eventController} +/// A reactive event stream controller for [Event]s that supports conditional +/// resolution before emitting events to subscribers. +/// +/// When an event is added: +/// - Each resolver is evaluated in order. +/// - The first resolver that returns a non-null result is used to produce +/// the resolved event that gets emitted. +/// - If no resolver returns a result, the original event is emitted unchanged. +/// +/// This is useful for normalizing or refining generic events into more +/// specific ones (e.g. rewriting `pollVoteCasted` into `pollAnswerCasted`) +/// before they reach business logic or state layers. +/// {@endtemplate} +class EventController extends Subject { + /// {@macro eventController} + factory EventController({ + bool sync = false, + void Function()? onListen, + void Function()? onCancel, + List> resolvers = const [], + }) { + // ignore: close_sinks + final controller = StreamController.broadcast( + sync: sync, + onListen: onListen, + onCancel: onCancel, + ); + + return EventController._( + controller, + controller.stream, + resolvers, + ); + } + + EventController._( + super.controller, + super.stream, + this._resolvers, + ); + + /// The list of resolvers used to inspect and optionally resolve events + /// before they are emitted. + /// + /// Resolvers are evaluated in order. The first to return a non-null result + /// determines the event that will be emitted. If none apply, the original + /// event is emitted as-is. + final List> _resolvers; + + /// Adds an [event] to the stream. + /// + /// Each [EventResolver] is applied in order until one returns a non-null + /// result. That resolved event is emitted, and no further resolvers are + /// evaluated. If all resolvers return `null`, the original event is emitted. + @override + void add(T event) { + for (final resolver in _resolvers) { + final result = resolver(event); + if (result != null) return super.add(result); + } + + // No resolver matched — emit the event as-is. + return super.add(event); + } +} diff --git a/packages/stream_chat/test/src/mocks.dart b/packages/stream_chat/test/src/mocks.dart index 26e000e13e..00aa1e0939 100644 --- a/packages/stream_chat/test/src/mocks.dart +++ b/packages/stream_chat/test/src/mocks.dart @@ -1,7 +1,6 @@ import 'package:dio/dio.dart'; import 'package:logging/logging.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:rxdart/rxdart.dart'; import 'package:stream_chat/src/client/channel.dart'; import 'package:stream_chat/src/client/client.dart'; import 'package:stream_chat/src/core/api/attachment_file_uploader.dart'; @@ -18,6 +17,7 @@ import 'package:stream_chat/src/core/http/stream_http_client.dart'; import 'package:stream_chat/src/core/http/token_manager.dart'; import 'package:stream_chat/src/core/models/channel_config.dart'; import 'package:stream_chat/src/core/models/event.dart'; +import 'package:stream_chat/src/core/util/event_controller.dart'; import 'package:stream_chat/src/db/chat_persistence_client.dart'; import 'package:stream_chat/src/event_type.dart'; import 'package:stream_chat/src/ws/websocket.dart'; @@ -98,7 +98,7 @@ class MockStreamChatClient extends Mock implements StreamChatClient { @override Stream get eventStream => _eventController.stream; - final _eventController = PublishSubject(); + final _eventController = EventController(); void addEvent(Event event) => _eventController.add(event); @override From 74188e30e07052edc95639bbaac2e65bf25758ef Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 11 Jul 2025 13:06:58 +0200 Subject: [PATCH 14/34] refactor(ui)!: add support for non-attachment types in attachment picker (#2293) --- migrations/v10-migration.md | 190 +++++ packages/stream_chat_flutter/CHANGELOG.md | 16 +- .../src/bottom_sheets/edit_message_sheet.dart | 4 - .../options/stream_gallery_picker.dart | 63 +- .../stream_attachment_picker.dart | 794 ++++++------------ ...stream_attachment_picker_bottom_sheet.dart | 209 ++--- .../stream_attachment_picker_controller.dart | 259 ++++++ .../stream_attachment_picker_option.dart | 198 +++++ .../stream_attachment_picker_result.dart | 58 ++ .../message_input/stream_message_input.dart | 103 +-- .../lib/src/utils/extensions.dart | 40 +- .../lib/stream_chat_flutter.dart | 3 + 12 files changed, 1183 insertions(+), 754 deletions(-) create mode 100644 packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_controller.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_option.dart create mode 100644 packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_result.dart diff --git a/migrations/v10-migration.md b/migrations/v10-migration.md index 61a1fc0062..0575d9eac0 100644 --- a/migrations/v10-migration.md +++ b/migrations/v10-migration.md @@ -8,6 +8,13 @@ This guide includes breaking changes grouped by release phase: +### 🚧 v10.0.0-beta.3 + +- [AttachmentPickerType](#-attachmentpickertype) +- [StreamAttachmentPickerOption](#-streamattachmentpickeroption) +- [showStreamAttachmentPickerModalBottomSheet](#-showstreamattachmentpickermodalbottomsheet) +- [AttachmentPickerBottomSheet](#-attachmentpickerbottomsheet) + ### 🚧 v10.0.0-beta.1 - [StreamReactionPicker](#-streamreactionpicker) @@ -17,6 +24,183 @@ This guide includes breaking changes grouped by release phase: --- +## 🧪 Migration for v10.0.0-beta.3 + +### 🛠 AttachmentPickerType + +#### Key Changes: + +- `AttachmentPickerType` enum replaced with sealed class hierarchy +- Now supports extensible custom types like contact and location pickers +- Use built-in types like `AttachmentPickerType.images` or define your own via `CustomAttachmentPickerType` + +#### Migration Steps: + +**Before:** +```dart +// Using enum-based attachment types +final attachmentType = AttachmentPickerType.images; +``` + +**After:** +```dart +// Using sealed class attachment types +final attachmentType = AttachmentPickerType.images; + +// For custom types +class LocationAttachmentPickerType extends CustomAttachmentPickerType { + const LocationAttachmentPickerType(); +} +``` + +> ⚠️ **Important:** +> The enum is now a sealed class, but the basic usage remains the same for built-in types. + +--- + +### 🛠 StreamAttachmentPickerOption + +#### Key Changes: + +- `StreamAttachmentPickerOption` replaced with two sealed classes: + - `SystemAttachmentPickerOption` for system pickers (camera, files) + - `TabbedAttachmentPickerOption` for tabbed pickers (gallery, polls, location) + +#### Migration Steps: + +**Before:** +```dart +final option = AttachmentPickerOption( + title: 'Gallery', + icon: Icon(Icons.photo_library), + supportedTypes: [AttachmentPickerType.images, AttachmentPickerType.videos], + optionViewBuilder: (context, controller) { + return GalleryPickerView(controller: controller); + }, +); + +final webOrDesktopOption = WebOrDesktopAttachmentPickerOption( + title: 'File Upload', + icon: Icon(Icons.upload_file), + type: AttachmentPickerType.files, +); +``` + +**After:** +```dart +// For custom UI pickers (gallery, polls) +final tabbedOption = TabbedAttachmentPickerOption( + title: 'Gallery', + icon: Icon(Icons.photo_library), + supportedTypes: [AttachmentPickerType.images, AttachmentPickerType.videos], + optionViewBuilder: (context, controller) { + return GalleryPickerView(controller: controller); + }, +); + +// For system pickers (camera, file dialogs) +final systemOption = SystemAttachmentPickerOption( + title: 'Camera', + icon: Icon(Icons.camera_alt), + supportedTypes: [AttachmentPickerType.images], + onTap: (context, controller) => pickFromCamera(), +); +``` + +> ⚠️ **Important:** +> - Use `SystemAttachmentPickerOption` for system pickers (camera, file dialogs) +> - Use `TabbedAttachmentPickerOption` for custom UI pickers (gallery, polls) + +--- + +### 🛠 showStreamAttachmentPickerModalBottomSheet + +#### Key Changes: + +- Now returns `StreamAttachmentPickerResult` instead of `AttachmentPickerValue` +- Improved type safety and clearer intent handling + +#### Migration Steps: + +**Before:** +```dart +final result = await showStreamAttachmentPickerModalBottomSheet( + context: context, + controller: controller, +); + +// result is AttachmentPickerValue +``` + +**After:** +```dart +final result = await showStreamAttachmentPickerModalBottomSheet( + context: context, + controller: controller, +); + +// result is StreamAttachmentPickerResult +switch (result) { + case AttachmentsPicked(): + // Handle picked attachments + case PollCreated(): + // Handle created poll + case AttachmentPickerError(): + // Handle error + case CustomAttachmentPickerResult(): + // Handle custom result +} +``` + +> ⚠️ **Important:** +> Always handle the new `StreamAttachmentPickerResult` return type with proper switch cases. + +--- + +### 🛠 AttachmentPickerBottomSheet + +#### Key Changes: + +- `StreamMobileAttachmentPickerBottomSheet` → `StreamTabbedAttachmentPickerBottomSheet` +- `StreamWebOrDesktopAttachmentPickerBottomSheet` → `StreamSystemAttachmentPickerBottomSheet` + +#### Migration Steps: + +**Before:** +```dart +StreamMobileAttachmentPickerBottomSheet( + context: context, + controller: controller, + customOptions: [option], +); + +StreamWebOrDesktopAttachmentPickerBottomSheet( + context: context, + controller: controller, + customOptions: [option], +); +``` + +**After:** +```dart +StreamTabbedAttachmentPickerBottomSheet( + context: context, + controller: controller, + customOptions: [tabbedOption], +); + +StreamSystemAttachmentPickerBottomSheet( + context: context, + controller: controller, + customOptions: [systemOption], +); +``` + +> ⚠️ **Important:** +> The new names better reflect their respective layouts and functionality. + +--- + ## 🧪 Migration for v10.0.0-beta.1 ### 🛠 StreamReactionPicker @@ -182,6 +366,12 @@ StreamMessageWidget( ## 🎉 You're Ready to Migrate! +### For v10.0.0-beta.3: +- ✅ Update attachment picker options to use `SystemAttachmentPickerOption` or `TabbedAttachmentPickerOption` +- ✅ Handle new `StreamAttachmentPickerResult` return type from attachment picker +- ✅ Use renamed bottom sheet classes (`StreamTabbedAttachmentPickerBottomSheet`, `StreamSystemAttachmentPickerBottomSheet`) + +### For v10.0.0-beta.1: - ✅ Use `StreamReactionPicker.builder` or supply `onReactionPicked` - ✅ Convert all `StreamMessageAction` instances to type-safe generic usage - ✅ Centralize handling with `onCustomActionTap` diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index afc8f5517b..c4a0e2d839 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -2,9 +2,19 @@ 🛑️ Breaking -- `PollMessage` widget has been removed and replaced with `PollAttachment` for better integration - with the attachment system. Polls can now be customized through `PollAttachmentBuilder` or by - creating custom poll attachment widgets via the attachment builder system. +- `PollMessage` widget has been removed and replaced with `PollAttachment` for better integration with the attachment system. Polls can now be customized through `PollAttachmentBuilder` or by creating custom poll attachment widgets via the attachment builder system. +- `AttachmentPickerType` enum has been replaced with a sealed class to support extensible custom types like contact and location pickers. Use built-in types like `AttachmentPickerType.images` or define your own via `CustomAttachmentPickerType`. +- `StreamAttachmentPickerOption` has been replaced with two sealed classes to support layout-specific picker options: `SystemAttachmentPickerOption` for system pickers (e.g. camera, files) and `TabbedAttachmentPickerOption` for tabbed pickers (e.g. gallery, polls, location). +- `showStreamAttachmentPickerModalBottomSheet` now returns a `StreamAttachmentPickerResult` instead of `AttachmentPickerValue` for improved type safety and clearer intent handling. +- `StreamMobileAttachmentPickerBottomSheet` has been renamed to `StreamTabbedAttachmentPickerBottomSheet`, and `StreamWebOrDesktopAttachmentPickerBottomSheet` has been renamed to `StreamSystemAttachmentPickerBottomSheet` to better reflect their respective layouts. + +For more details, please refer to the [migration guide](../../migrations/v10-migration.md). + +✅ Added + +- Added `extraData` field to `AttachmentPickerValue` to support storing and retrieving custom picker state (e.g. tab-specific config). +- Added `customAttachmentPickerOptions` to `StreamMessageInput` to allow injecting custom picker tabs like contact and location pickers. +- Added `onCustomAttachmentPickerResult` callback to `StreamMessageInput` to handle results returned by custom picker tabs. ## 10.0.0-beta.2 diff --git a/packages/stream_chat_flutter/lib/src/bottom_sheets/edit_message_sheet.dart b/packages/stream_chat_flutter/lib/src/bottom_sheets/edit_message_sheet.dart index b53db1f2cb..ced57b6ecc 100644 --- a/packages/stream_chat_flutter/lib/src/bottom_sheets/edit_message_sheet.dart +++ b/packages/stream_chat_flutter/lib/src/bottom_sheets/edit_message_sheet.dart @@ -115,10 +115,6 @@ class _EditMessageSheetState extends State { StreamMessageInput( elevation: 0, messageInputController: controller, - // Disallow editing poll for now as it's not supported. - allowedAttachmentPickerTypes: [ - ...AttachmentPickerType.values, - ]..remove(AttachmentPickerType.poll), preMessageSending: (m) { FocusScope.of(context).unfocus(); Navigator.of(context).pop(); diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart index 905df5f48c..c2914d2007 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_gallery_picker.dart @@ -6,6 +6,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:stream_chat_flutter/src/icons/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/message_input/attachment_picker/stream_attachment_picker.dart'; +import 'package:stream_chat_flutter/src/message_input/attachment_picker/stream_attachment_picker_controller.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; import 'package:stream_chat_flutter/src/scroll_view/photo_gallery/stream_photo_gallery.dart'; import 'package:stream_chat_flutter/src/scroll_view/photo_gallery/stream_photo_gallery_controller.dart'; @@ -14,7 +15,7 @@ import 'package:stream_chat_flutter/src/utils/utils.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// Max image resolution which can be resized by the CDN. -// Taken from https://getstream.io/chat/docs/flutter-dart/file_uploads/?language=dart#image-resizing +/// Taken from https://getstream.io/chat/docs/flutter-dart/file_uploads/?language=dart#image-resizing const maxCDNImageResolution = 16800000; /// Widget used to pick media from the device gallery. @@ -23,42 +24,23 @@ class StreamGalleryPicker extends StatefulWidget { const StreamGalleryPicker({ super.key, this.limit = 50, + GalleryPickerConfig? config, required this.selectedMediaItems, required this.onMediaItemSelected, - this.mediaThumbnailSize = const ThumbnailSize(400, 400), - this.mediaThumbnailFormat = ThumbnailFormat.jpeg, - this.mediaThumbnailQuality = 100, - this.mediaThumbnailScale = 1, - }); + }) : config = config ?? const GalleryPickerConfig(); /// Maximum number of media items that can be selected. final int limit; + /// Configuration for the gallery picker. + final GalleryPickerConfig config; + /// List of selected media items. final Iterable selectedMediaItems; /// Callback called when an media item is selected. final ValueSetter onMediaItemSelected; - /// Size of the attachment thumbnails. - /// - /// Defaults to (400, 400). - final ThumbnailSize mediaThumbnailSize; - - /// Format of the attachment thumbnails. - /// - /// Defaults to [ThumbnailFormat.jpeg]. - final ThumbnailFormat mediaThumbnailFormat; - - /// The quality value for the attachment thumbnails. - /// - /// Valid from 1 to 100. - /// Defaults to 100. - final int mediaThumbnailQuality; - - /// The scale to apply on the [attachmentThumbnailSize]. - final double mediaThumbnailScale; - @override State createState() => _StreamGalleryPickerState(); } @@ -159,10 +141,10 @@ class _StreamGalleryPickerState extends State { onMediaTap: widget.onMediaItemSelected, loadMoreTriggerIndex: 10, padding: const EdgeInsets.all(2), - thumbnailSize: widget.mediaThumbnailSize, - thumbnailFormat: widget.mediaThumbnailFormat, - thumbnailQuality: widget.mediaThumbnailQuality, - thumbnailScale: widget.mediaThumbnailScale, + thumbnailSize: widget.config.mediaThumbnailSize, + thumbnailFormat: widget.config.mediaThumbnailFormat, + thumbnailQuality: widget.config.mediaThumbnailQuality, + thumbnailScale: widget.config.mediaThumbnailScale, itemBuilder: (context, mediaItems, index, defaultWidget) { final media = mediaItems[index]; return defaultWidget.copyWith( @@ -178,6 +160,29 @@ class _StreamGalleryPickerState extends State { } } +/// Configuration for the [StreamGalleryPicker]. +class GalleryPickerConfig { + /// Creates a [GalleryPickerConfig] instance. + const GalleryPickerConfig({ + this.mediaThumbnailSize = const ThumbnailSize(400, 400), + this.mediaThumbnailFormat = ThumbnailFormat.jpeg, + this.mediaThumbnailQuality = 100, + this.mediaThumbnailScale = 1, + }); + + /// Size of the attachment thumbnails. + final ThumbnailSize mediaThumbnailSize; + + /// Format of the attachment thumbnails. + final ThumbnailFormat mediaThumbnailFormat; + + /// The quality value for the attachment thumbnails. + final int mediaThumbnailQuality; + + /// The scale to apply on the [mediaThumbnailSize]. + final double mediaThumbnailScale; +} + /// extension StreamImagePickerX on StreamAttachmentPickerController { /// diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker.dart index 97f78ae088..f408b628bc 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker.dart @@ -1,400 +1,64 @@ import 'dart:async'; -import 'package:collection/collection.dart'; +import 'package:file_picker/file_picker.dart' show FileType; import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/message_input/attachment_picker/options/options.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -/// The default maximum size for media attachments. -const kDefaultMaxAttachmentSize = 100 * 1024 * 1024; // 100MB in Bytes - -/// The default maximum number of media attachments. -const kDefaultMaxAttachmentCount = 10; - -/// Value class for [AttachmentPickerController]. -/// -/// This class holds the list of [Poll] and [Attachment] objects. -class AttachmentPickerValue { - /// Creates a new instance of [AttachmentPickerValue]. - const AttachmentPickerValue({ - this.poll, - this.attachments = const [], - }); - - /// The poll object. - final Poll? poll; - - /// The list of [Attachment] objects. - final List attachments; - - /// Returns a copy of this object with the provided values. - AttachmentPickerValue copyWith({ - Poll? poll, - List? attachments, - }) { - return AttachmentPickerValue( - poll: poll ?? this.poll, - attachments: attachments ?? this.attachments, - ); - } -} - -/// Controller class for [StreamAttachmentPicker]. -class StreamAttachmentPickerController - extends ValueNotifier { - /// Creates a new instance of [StreamAttachmentPickerController]. - StreamAttachmentPickerController({ - this.initialPoll, - this.initialAttachments, - this.maxAttachmentSize = kDefaultMaxAttachmentSize, - this.maxAttachmentCount = kDefaultMaxAttachmentCount, - }) : assert( - (initialAttachments?.length ?? 0) <= maxAttachmentCount, - '''The initial attachments count must be less than or equal to maxAttachmentCount''', - ), - super( - AttachmentPickerValue( - poll: initialPoll, - attachments: initialAttachments ?? const [], - ), - ); - - /// The max attachment size allowed in bytes. - final int maxAttachmentSize; - - /// The max attachment count allowed. - final int maxAttachmentCount; - - /// The initial poll. - final Poll? initialPoll; - - /// The initial attachments. - final List? initialAttachments; - - @override - set value(AttachmentPickerValue newValue) { - if (newValue.attachments.length > maxAttachmentCount) { - throw ArgumentError( - 'The maximum number of attachments is $maxAttachmentCount.', - ); - } - super.value = newValue; - } - - /// Adds a new [poll] to the message. - set poll(Poll poll) { - value = value.copyWith(poll: poll); - } - - Future _saveToCache(AttachmentFile file) async { - // Cache the attachment in a temporary file. - return StreamAttachmentHandler.instance.saveAttachmentFile( - attachmentFile: file, - ); - } - - Future _removeFromCache(AttachmentFile file) { - // Remove the cached attachment file. - return StreamAttachmentHandler.instance.deleteAttachmentFile( - attachmentFile: file, - ); - } - - /// Adds a new attachment to the message. - Future addAttachment(Attachment attachment) async { - assert(attachment.fileSize != null, ''); - if (attachment.fileSize! > maxAttachmentSize) { - throw ArgumentError( - 'The size of the attachment is ${attachment.fileSize} bytes, ' - 'but the maximum size allowed is $maxAttachmentSize bytes.', - ); - } - - final file = attachment.file; - final uploadState = attachment.uploadState; - - // No need to cache the attachment if it's already uploaded - // or we are on web. - if (file == null || uploadState.isSuccess || isWeb) { - value = value.copyWith(attachments: [...value.attachments, attachment]); - return; - } - - // Cache the attachment in a temporary file. - final tempFilePath = await _saveToCache(file); - - value = value.copyWith(attachments: [ - ...value.attachments, - attachment.copyWith( - file: file.copyWith( - path: tempFilePath, - ), - ), - ]); - } - - /// Removes the specified [attachment] from the message. - Future removeAttachment(Attachment attachment) async { - final file = attachment.file; - final uploadState = attachment.uploadState; - - if (file == null || uploadState.isSuccess || isWeb) { - final updatedAttachments = [...value.attachments]..remove(attachment); - value = value.copyWith(attachments: updatedAttachments); - return; - } - - // Remove the cached attachment file. - await _removeFromCache(file); - - final updatedAttachments = [...value.attachments]..remove(attachment); - value = value.copyWith(attachments: updatedAttachments); - } - - /// Remove the attachment with the given [attachmentId]. - void removeAttachmentById(String attachmentId) { - final attachment = value.attachments.firstWhereOrNull( - (attachment) => attachment.id == attachmentId, - ); - - if (attachment == null) return; - - removeAttachment(attachment); - } - - /// Clears all the attachments. - Future clear() async { - final attachments = [...value.attachments]; - for (final attachment in attachments) { - final file = attachment.file; - final uploadState = attachment.uploadState; - - if (file == null || uploadState.isSuccess || isWeb) continue; - - await _removeFromCache(file); - } - value = const AttachmentPickerValue(); - } - - /// Resets the controller to its initial state. - Future reset() async { - final attachments = [...value.attachments]; - for (final attachment in attachments) { - final file = attachment.file; - final uploadState = attachment.uploadState; - - if (file == null || uploadState.isSuccess || isWeb) continue; - - await _removeFromCache(file); - } - - value = AttachmentPickerValue( - poll: initialPoll, - attachments: initialAttachments ?? const [], - ); - } -} - -/// The possible picker types of the attachment picker. -enum AttachmentPickerType { - /// The attachment picker will only allow to pick images. - images, - - /// The attachment picker will only allow to pick videos. - videos, - - /// The attachment picker will only allow to pick audios. - audios, - - /// The attachment picker will only allow to pick files or documents. - files, - - /// The attachment picker will only allow to create poll. - poll, -} - -/// Function signature for building the attachment picker option view. -typedef AttachmentPickerOptionViewBuilder = Widget Function( - BuildContext context, - StreamAttachmentPickerController controller, -); - -/// Model class for the attachment picker options. -class AttachmentPickerOption { - /// Creates a new instance of [AttachmentPickerOption]. - const AttachmentPickerOption({ - this.key, - required this.supportedTypes, - required this.icon, - this.title, - this.optionViewBuilder, - }); - - /// A key to identify the option. - final String? key; - - /// The icon of the option. - final Widget icon; - - /// The title of the option. - final String? title; - - /// The supported types of the option. - final Iterable supportedTypes; - - /// The option view builder. - final AttachmentPickerOptionViewBuilder? optionViewBuilder; - - @override - bool operator ==(Object other) => - identical(this, other) || - other is AttachmentPickerOption && - runtimeType == other.runtimeType && - key == other.key && - const IterableEquality().equals(supportedTypes, other.supportedTypes); - - @override - int get hashCode => - key.hashCode ^ const IterableEquality().hash(supportedTypes); -} - -/// The attachment picker option for the web or desktop platforms. -class WebOrDesktopAttachmentPickerOption extends AttachmentPickerOption { - /// Creates a new instance of [WebOrDesktopAttachmentPickerOption]. - WebOrDesktopAttachmentPickerOption({ - super.key, - required AttachmentPickerType type, - required super.icon, - required super.title, - }) : super(supportedTypes: [type]); - - /// Creates a new instance of [WebOrDesktopAttachmentPickerOption] from - /// [option]. - factory WebOrDesktopAttachmentPickerOption.fromAttachmentPickerOption( - AttachmentPickerOption option, - ) { - return WebOrDesktopAttachmentPickerOption( - key: option.key, - type: option.supportedTypes.first, - icon: option.icon, - title: option.title, - ); - } - - @override - String get title => super.title!; - - /// Type of the option. - AttachmentPickerType get type => supportedTypes.first; -} - -/// Helpful extensions for [StreamAttachmentPickerController]. -extension AttachmentPickerOptionTypeX on StreamAttachmentPickerController { - /// Returns the list of available attachment picker options. - Set get currentAttachmentPickerTypes { - final attach = value.attachments; - final containsImage = attach.any((it) => it.type == AttachmentType.image); - final containsVideo = attach.any((it) => it.type == AttachmentType.video); - final containsAudio = attach.any((it) => it.type == AttachmentType.audio); - final containsFile = attach.any((it) => it.type == AttachmentType.file); - final containsPoll = value.poll != null; - - return { - if (containsImage) AttachmentPickerType.images, - if (containsVideo) AttachmentPickerType.videos, - if (containsAudio) AttachmentPickerType.audios, - if (containsFile) AttachmentPickerType.files, - if (containsPoll) AttachmentPickerType.poll, - }; - } - - /// Returns the list of enabled picker types. - Set filterEnabledTypes({ - required Iterable options, - }) { - final availableTypes = currentAttachmentPickerTypes; - final enabledTypes = {}; - for (final option in options) { - final supportedTypes = option.supportedTypes; - if (availableTypes.any(supportedTypes.contains)) { - enabledTypes.addAll(supportedTypes); - } - } - return enabledTypes; - } - - /// Returns true if the [initialAttachments] are changed. - bool get isValueChanged { - final isPollEqual = value.poll == initialPoll; - final areAttachmentsEqual = UnorderedIterableEquality( - EqualityBy((attachment) => attachment.id), - ).equals(value.attachments, initialAttachments); - - return !isPollEqual || !areAttachmentsEqual; - } -} - -/// Function signature for the callback when the web or desktop attachment -/// picker option gets tapped. -typedef OnWebOrDesktopAttachmentPickerOptionTap = void Function( - BuildContext context, - StreamAttachmentPickerController controller, - WebOrDesktopAttachmentPickerOption option, -); - -/// Bottom sheet widget for the web or desktop version of the attachment picker. -class StreamWebOrDesktopAttachmentPickerBottomSheet extends StatelessWidget { - /// Creates a new instance of [StreamWebOrDesktopAttachmentPickerBottomSheet]. - const StreamWebOrDesktopAttachmentPickerBottomSheet({ +/// Bottom sheet widget for the system attachment picker interface. +/// This is used when the attachment picker uses system integration, +/// typically on web/desktop or when useSystemAttachmentPicker is true. +class StreamSystemAttachmentPickerBottomSheet extends StatelessWidget { + /// Creates a new instance of [StreamSystemAttachmentPickerBottomSheet]. + const StreamSystemAttachmentPickerBottomSheet({ super.key, required this.options, required this.controller, - this.onOptionTap, }); /// The list of options. - final Set options; + final Set options; /// The controller of the attachment picker. final StreamAttachmentPickerController controller; - /// The callback when the option gets tapped. - final OnWebOrDesktopAttachmentPickerOptionTap? onOptionTap; - @override Widget build(BuildContext context) { - final enabledTypes = controller.filterEnabledTypes(options: options); - return ListView( - shrinkWrap: true, - children: [ - ...options.map((option) { - VoidCallback? onOptionTap; - if (this.onOptionTap != null) { - onOptionTap = () { - this.onOptionTap?.call(context, controller, option); - }; - } - - final enabled = enabledTypes.isEmpty || - enabledTypes.any((it) => it == option.type); - - return ListTile( - enabled: enabled, - leading: option.icon, - title: Text(option.title), - onTap: onOptionTap, - ); - }), - ], + return ValueListenableBuilder( + valueListenable: controller, + builder: (context, value, child) { + final enabledTypes = value.filterEnabledTypes(options: options); + + return ListView( + shrinkWrap: true, + children: [ + ...options.map( + (option) { + final supported = option.supportedTypes; + final isEnabled = enabledTypes.any(supported.contains); + + return ListTile( + enabled: isEnabled, + leading: option.icon, + title: Text(option.title), + onTap: () => option.onTap(context, controller), + ); + }, + ), + ], + ); + }, ); } } -/// Bottom sheet widget for the mobile version of the attachment picker. -class StreamMobileAttachmentPickerBottomSheet extends StatefulWidget { - /// Creates a new instance of [StreamMobileAttachmentPickerBottomSheet]. - const StreamMobileAttachmentPickerBottomSheet({ +/// Bottom sheet widget for the tabbed attachment picker interface. +/// This is used when the attachment picker displays a tabbed interface, +/// typically on mobile when useSystemAttachmentPicker is false. +class StreamTabbedAttachmentPickerBottomSheet extends StatefulWidget { + /// Creates a new instance of [StreamTabbedAttachmentPickerBottomSheet]. + const StreamTabbedAttachmentPickerBottomSheet({ super.key, required this.options, required this.controller, @@ -403,54 +67,49 @@ class StreamMobileAttachmentPickerBottomSheet extends StatefulWidget { }); /// The list of options. - final Set options; + final Set options; /// The initial option to be selected. - final AttachmentPickerOption? initialOption; + final TabbedAttachmentPickerOption? initialOption; /// The controller of the attachment picker. final StreamAttachmentPickerController controller; /// The callback when the send button gets tapped. - final ValueSetter? onSendValue; + final ValueSetter? onSendValue; @override - State createState() => - _StreamMobileAttachmentPickerBottomSheetState(); + State createState() => + _StreamTabbedAttachmentPickerBottomSheetState(); } -class _StreamMobileAttachmentPickerBottomSheetState - extends State { - late AttachmentPickerOption _currentOption; +class _StreamTabbedAttachmentPickerBottomSheetState + extends State { + // The current option selected in the tabbed attachment picker. + late var _currentOption = _calculateInitialOption(); + TabbedAttachmentPickerOption _calculateInitialOption() { + if (widget.initialOption case final option?) return option; - @override - void initState() { - super.initState(); - if (widget.initialOption == null) { - final enabledTypes = widget.controller.filterEnabledTypes( - options: widget.options, - ); - if (enabledTypes.isNotEmpty) { - _currentOption = widget.options.firstWhere((it) { - return it.supportedTypes.contains(enabledTypes.first); - }); - } else { - _currentOption = widget.options.first; - } - } else { - _currentOption = widget.initialOption!; - } + final options = widget.options; + final currentValue = widget.controller.value; + final enabledTypes = currentValue.filterEnabledTypes(options: options); + + if (enabledTypes.isEmpty) return options.first; + + return options.firstWhere( + (it) => enabledTypes.any(it.supportedTypes.contains), + ); } @override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: widget.controller, - builder: (context, attachments, _) { + builder: (context, value, _) { return Column( mainAxisSize: MainAxisSize.min, children: [ - _AttachmentPickerOptions( + _TabbedAttachmentPickerOptions( controller: widget.controller, options: widget.options, currentOption: _currentOption, @@ -460,9 +119,10 @@ class _StreamMobileAttachmentPickerBottomSheetState }, ), Expanded( - child: _currentOption.optionViewBuilder - ?.call(context, widget.controller) ?? - const Empty(), + child: _currentOption.optionViewBuilder( + context, + widget.controller, + ), ), ], ); @@ -471,8 +131,8 @@ class _StreamMobileAttachmentPickerBottomSheetState } } -class _AttachmentPickerOptions extends StatelessWidget { - const _AttachmentPickerOptions({ +class _TabbedAttachmentPickerOptions extends StatelessWidget { + const _TabbedAttachmentPickerOptions({ required this.options, required this.currentOption, required this.controller, @@ -480,19 +140,20 @@ class _AttachmentPickerOptions extends StatelessWidget { this.onSendValue, }); - final Iterable options; - final AttachmentPickerOption currentOption; + final Iterable options; + final TabbedAttachmentPickerOption currentOption; final StreamAttachmentPickerController controller; - final ValueSetter? onOptionSelected; - final ValueSetter? onSendValue; + final ValueSetter? onOptionSelected; + final ValueSetter? onSendValue; @override Widget build(BuildContext context) { final colorTheme = StreamChatTheme.of(context).colorTheme; return ValueListenableBuilder( valueListenable: controller, - builder: (context, attachments, __) { - final enabledTypes = controller.filterEnabledTypes(options: options); + builder: (context, value, __) { + final enabledTypes = value.filterEnabledTypes(options: options); + return Row( children: [ Expanded( @@ -502,18 +163,19 @@ class _AttachmentPickerOptions extends StatelessWidget { children: [ ...options.map( (option) { - final supportedTypes = option.supportedTypes; - + final supported = option.supportedTypes; + final isEnabled = enabledTypes.any(supported.contains); final isSelected = option == currentOption; - final isEnabled = enabledTypes.isEmpty || - enabledTypes.any(supportedTypes.contains); - final color = isSelected - ? colorTheme.accentPrimary - : colorTheme.textLowEmphasis; + final color = switch (isSelected) { + true => colorTheme.accentPrimary, + _ => colorTheme.textLowEmphasis, + }; - final onPressed = - isEnabled ? () => onOptionSelected!(option) : null; + final onPressed = switch (isEnabled) { + true => () => onOptionSelected?.call(option), + _ => null, + }; return IconButton( color: color, @@ -529,12 +191,18 @@ class _AttachmentPickerOptions extends StatelessWidget { ), Builder( builder: (context) { - final VoidCallback? onPressed; - if (onSendValue != null && controller.isValueChanged) { - onPressed = () => onSendValue!(attachments); - } else { - onPressed = null; - } + final initialValue = controller.initialValue; + final isValueChanged = value != initialValue; + + final onPressed = switch (onSendValue) { + final onSendValue? when isValueChanged => () { + final result = AttachmentsPicked( + attachments: value.attachments, + ); + return onSendValue(result); + }, + _ => null, + }; return IconButton( color: colorTheme.accentPrimary, @@ -744,42 +412,62 @@ class OptionDrawer extends StatelessWidget { } } -/// Returns the mobile version of the attachment picker. -Widget mobileAttachmentPickerBuilder({ +/// Builds a tabbed attachment picker with custom interfaces for different +/// attachment types. +/// +/// Shows horizontal tabs for gallery, files, camera, video, and polls. Each +/// tab displays a specialized interface for selecting that type of +/// attachment. Tabs get enabled or disabled based on what you've already +/// selected. +/// +/// This is the default interface for mobile platforms. Configure with +/// [customOptions], [galleryPickerConfig], [pollConfig], and +/// [allowedTypes]. +Widget tabbedAttachmentPickerBuilder({ required BuildContext context, required StreamAttachmentPickerController controller, - Poll? initialPoll, PollConfig? pollConfig, - Iterable? customOptions, + GalleryPickerConfig? galleryPickerConfig, + Iterable? customOptions, List allowedTypes = AttachmentPickerType.values, - ThumbnailSize attachmentThumbnailSize = const ThumbnailSize(400, 400), - ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg, - int attachmentThumbnailQuality = 100, - double attachmentThumbnailScale = 1, - ErrorListener? onError, }) { - return StreamMobileAttachmentPickerBottomSheet( + Future _handleSingePick( + StreamAttachmentPickerController controller, + Attachment? attachment, + ) async { + try { + if (attachment != null) await controller.addAttachment(attachment); + return AttachmentsPicked(attachments: controller.value.attachments); + } catch (error, stk) { + return AttachmentPickerError(error: error, stackTrace: stk); + } + } + + return StreamTabbedAttachmentPickerBottomSheet( controller: controller, onSendValue: Navigator.of(context).pop, options: { ...{ - if (customOptions != null) ...customOptions, - AttachmentPickerOption( + TabbedAttachmentPickerOption( key: 'gallery-picker', icon: const StreamSvgIcon(icon: StreamSvgIcons.pictures), supportedTypes: [ AttachmentPickerType.images, AttachmentPickerType.videos, ], + isEnabled: (value) { + // Enable if nothing has been selected yet. + if (value.isEmpty) return true; + + // Otherwise, enable only if there is at least a image or a video. + return value.attachments.any((it) => it.isImage || it.isVideo); + }, optionViewBuilder: (context, controller) { final attachment = controller.value.attachments; final selectedIds = attachment.map((it) => it.id); return StreamGalleryPicker( + config: galleryPickerConfig, selectedMediaItems: selectedIds, - mediaThumbnailSize: attachmentThumbnailSize, - mediaThumbnailFormat: attachmentThumbnailFormat, - mediaThumbnailQuality: attachmentThumbnailQuality, - mediaThumbnailScale: attachmentThumbnailScale, onMediaItemSelected: (media) async { try { if (selectedIds.contains(media.id)) { @@ -787,178 +475,186 @@ Widget mobileAttachmentPickerBuilder({ } return await controller.addAssetAttachment(media); } catch (e, stk) { - if (onError != null) return onError.call(e, stk); - rethrow; + final err = AttachmentPickerError(error: e, stackTrace: stk); + return Navigator.pop(context, err); } }, ); }, ), - AttachmentPickerOption( + TabbedAttachmentPickerOption( key: 'file-picker', icon: const StreamSvgIcon(icon: StreamSvgIcons.files), supportedTypes: [AttachmentPickerType.files], - optionViewBuilder: (context, controller) { - return StreamFilePicker( - onFilePicked: (file) async { - try { - if (file != null) await controller.addAttachment(file); - return Navigator.pop(context, controller.value); - } catch (e, stk) { - Navigator.pop(context, controller.value); - if (onError != null) return onError.call(e, stk); + isEnabled: (value) { + // Enable if nothing has been selected yet. + if (value.isEmpty) return true; - rethrow; - } - }, - ); + // Otherwise, enable only if there is at least a file. + return value.attachments.any((it) => it.isFile); }, + optionViewBuilder: (context, controller) => StreamFilePicker( + onFilePicked: (file) async { + final result = await _handleSingePick(controller, file); + return Navigator.pop(context, result); + }, + ), ), - AttachmentPickerOption( + TabbedAttachmentPickerOption( key: 'image-picker', icon: const StreamSvgIcon(icon: StreamSvgIcons.camera), supportedTypes: [AttachmentPickerType.images], - optionViewBuilder: (context, controller) { - return StreamImagePicker( - onImagePicked: (image) async { - try { - if (image != null) { - await controller.addAttachment(image); - } - return Navigator.pop(context, controller.value); - } catch (e, stk) { - Navigator.pop(context, controller.value); - if (onError != null) return onError.call(e, stk); + isEnabled: (value) { + // Enable if nothing has been selected yet. + if (value.isEmpty) return true; - rethrow; - } - }, - ); + // Otherwise, enable only if there is at least a image. + return value.attachments.any((it) => it.isImage); }, + optionViewBuilder: (context, controller) => StreamImagePicker( + onImagePicked: (image) async { + final result = await _handleSingePick(controller, image); + return Navigator.pop(context, result); + }, + ), ), - AttachmentPickerOption( + TabbedAttachmentPickerOption( key: 'video-picker', icon: const StreamSvgIcon(icon: StreamSvgIcons.record), supportedTypes: [AttachmentPickerType.videos], - optionViewBuilder: (context, controller) { - return StreamVideoPicker( - onVideoPicked: (video) async { - try { - if (video != null) { - await controller.addAttachment(video); - } - return Navigator.pop(context, controller.value); - } catch (e, stk) { - Navigator.pop(context, controller.value); - if (onError != null) return onError.call(e, stk); + isEnabled: (value) { + // Enable if nothing has been selected yet. + if (value.isEmpty) return true; - rethrow; - } - }, - ); + // Otherwise, enable only if there is at least a video. + return value.attachments.any((it) => it.isVideo); }, + optionViewBuilder: (context, controller) => StreamVideoPicker( + onVideoPicked: (video) async { + final result = await _handleSingePick(controller, video); + return Navigator.pop(context, result); + }, + ), ), - AttachmentPickerOption( + TabbedAttachmentPickerOption( key: 'poll-creator', icon: const StreamSvgIcon(icon: StreamSvgIcons.polls), supportedTypes: [AttachmentPickerType.poll], + isEnabled: (value) { + // Enable if nothing has been selected yet. + if (value.isEmpty) return true; + + // Otherwise, enable only if there is a poll. + return value.poll != null; + }, optionViewBuilder: (context, controller) { final initialPoll = controller.value.poll; return StreamPollCreator( poll: initialPoll, config: pollConfig, onPollCreated: (poll) { - try { - if (poll != null) controller.poll = poll; - return Navigator.pop(context, controller.value); - } catch (e, stk) { - Navigator.pop(context, controller.value); - if (onError != null) return onError.call(e, stk); + if (poll == null) return Navigator.pop(context); + controller.poll = poll; - rethrow; - } + final result = PollCreated(poll: poll); + return Navigator.pop(context, result); }, ); }, ), + ...?customOptions, }.where((option) => option.supportedTypes.every(allowedTypes.contains)), }, ); } -/// Returns the web or desktop version of the attachment picker. -Widget webOrDesktopAttachmentPickerBuilder({ +/// Builds a system attachment picker that opens native platform dialogs. +/// +/// Shows a simple list of options that immediately launch your device's +/// built-in file browser, camera app, or other native tools instead of +/// custom interfaces. +/// +/// This is the default for web and desktop platforms, and can be enabled on +/// mobile with `useSystemAttachmentPicker`. Configure with [customOptions], +/// [pollConfig], and [allowedTypes]. +Widget systemAttachmentPickerBuilder({ required BuildContext context, required StreamAttachmentPickerController controller, - Poll? initialPoll, - PollConfig? pollConfig, - Iterable? customOptions, + PollConfig? pollConfig = const PollConfig(), + GalleryPickerConfig? galleryPickerConfig = const GalleryPickerConfig(), + Iterable? customOptions, List allowedTypes = AttachmentPickerType.values, - ThumbnailSize attachmentThumbnailSize = const ThumbnailSize(400, 400), - ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg, - int attachmentThumbnailQuality = 100, - double attachmentThumbnailScale = 1, - ErrorListener? onError, }) { - return StreamWebOrDesktopAttachmentPickerBottomSheet( + Future _pickSystemFile( + StreamAttachmentPickerController controller, + FileType type, + ) async { + try { + final file = await StreamAttachmentHandler.instance.pickFile(type: type); + if (file != null) await controller.addAttachment(file); + + return AttachmentsPicked(attachments: controller.value.attachments); + } catch (error, stk) { + return AttachmentPickerError(error: error, stackTrace: stk); + } + } + + return StreamSystemAttachmentPickerBottomSheet( controller: controller, options: { ...{ - if (customOptions != null) ...customOptions, - WebOrDesktopAttachmentPickerOption( + SystemAttachmentPickerOption( key: 'image-picker', - type: AttachmentPickerType.images, + supportedTypes: [AttachmentPickerType.images], icon: const StreamSvgIcon(icon: StreamSvgIcons.pictures), title: context.translations.uploadAPhotoLabel, + onTap: (context, controller) async { + final result = await _pickSystemFile(controller, FileType.image); + return Navigator.pop(context, result); + }, ), - WebOrDesktopAttachmentPickerOption( + SystemAttachmentPickerOption( key: 'video-picker', - type: AttachmentPickerType.videos, + supportedTypes: [AttachmentPickerType.videos], icon: const StreamSvgIcon(icon: StreamSvgIcons.record), title: context.translations.uploadAVideoLabel, + onTap: (context, controller) async { + final result = await _pickSystemFile(controller, FileType.video); + return Navigator.pop(context, result); + }, ), - WebOrDesktopAttachmentPickerOption( + SystemAttachmentPickerOption( key: 'file-picker', - type: AttachmentPickerType.files, + supportedTypes: [AttachmentPickerType.files], icon: const StreamSvgIcon(icon: StreamSvgIcons.files), title: context.translations.uploadAFileLabel, + onTap: (context, controller) async { + final result = await _pickSystemFile(controller, FileType.any); + return Navigator.pop(context, result); + }, ), - WebOrDesktopAttachmentPickerOption( + SystemAttachmentPickerOption( key: 'poll-creator', - type: AttachmentPickerType.poll, + supportedTypes: [AttachmentPickerType.poll], icon: const StreamSvgIcon(icon: StreamSvgIcons.polls), title: context.translations.createPollLabel(isNew: true), - ), - }.where((option) => option.supportedTypes.every(allowedTypes.contains)), - }, - onOptionTap: (context, controller, option) async { - // Handle the polls type option separately - if (option.type case AttachmentPickerType.poll) { - final poll = await showStreamPollCreatorDialog( - context: context, - poll: initialPoll, - config: pollConfig, - ); - - if (poll != null) controller.poll = poll; - return Navigator.pop(context, controller.value); - } + onTap: (context, controller) async { + final initialPoll = controller.value.poll; + final poll = await showStreamPollCreatorDialog( + context: context, + poll: initialPoll, + config: pollConfig, + ); - // Handle the remaining option types. - try { - final attachment = await StreamAttachmentHandler.instance.pickFile( - type: option.type.fileType, - ); - if (attachment != null) { - await controller.addAttachment(attachment); - } - return Navigator.pop(context, controller.value); - } catch (e, stk) { - Navigator.pop(context, controller.value); - if (onError != null) return onError.call(e, stk); + if (poll == null) return Navigator.pop(context); + controller.poll = poll; - rethrow; - } + final result = PollCreated(poll: poll); + return Navigator.pop(context, result); + }, + ), + ...?customOptions, + }.where((option) => option.supportedTypes.every(allowedTypes.contains)), }, ); } diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart index cbd164120e..2313552a1b 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart @@ -1,76 +1,73 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/message_input/attachment_picker/options/stream_gallery_picker.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -/// Shows a modal material design bottom sheet. +/// Shows a modal bottom sheet with the Stream attachment picker. /// -/// A modal bottom sheet is an alternative to a menu or a dialog and prevents -/// the user from interacting with the rest of the app. +/// The picker supports two modes: /// -/// A closely related widget is a persistent bottom sheet, which shows -/// information that supplements the primary content of the app without -/// preventing the use from interacting with the app. Persistent bottom sheets -/// can be created and displayed with the [showBottomSheet] function or the -/// [ScaffoldState.showBottomSheet] method. +/// - **Tabbed interface**: Typically used on mobile platforms. Provide +/// [TabbedAttachmentPickerOption] values in [customOptions]. This mode is +/// active when [useSystemAttachmentPicker] is false (default). /// -/// The `context` argument is used to look up the [Navigator] and [Theme] for -/// the bottom sheet. It is only used when the method is called. Its -/// corresponding widget can be safely removed from the tree before the bottom -/// sheet is closed. +/// - **System integration**: Used on web, desktop, or when +/// [useSystemAttachmentPicker] is true. Provide +/// [SystemAttachmentPickerOption] values in [customOptions]. /// -/// The `isScrollControlled` parameter specifies whether this is a route for -/// a bottom sheet that will utilize [DraggableScrollableSheet]. If you wish -/// to have a bottom sheet that has a scrollable child such as a [ListView] or -/// a [GridView] and have the bottom sheet be draggable, you should set this -/// parameter to true. +/// When using the system picker, all [customOptions] must be +/// [SystemAttachmentPickerOption] instances. If any other type is included, +/// an [ArgumentError] is thrown. /// -/// The `useRootNavigator` parameter ensures that the root navigator is used to -/// display the [BottomSheet] when set to `true`. This is useful in the case -/// that a modal [BottomSheet] needs to be displayed above all other content -/// but the caller is inside another [Navigator]. +/// Example using the tabbed interface: +/// ```dart +/// showStreamAttachmentPickerModalBottomSheet( +/// context: context, +/// customOptions: [ +/// TabbedAttachmentPickerOption( +/// key: 'gallery', +/// icon: Icon(Icons.photo), +/// supportedTypes: [AttachmentPickerType.images], +/// optionViewBuilder: (context, controller) { +/// return CustomGalleryWidget(); +/// }, +/// ), +/// ], +/// ); +/// ``` /// -/// The [isDismissible] parameter specifies whether the bottom sheet will be -/// dismissed when user taps on the scrim. +/// Example using the system picker: +/// ```dart +/// showStreamAttachmentPickerModalBottomSheet( +/// context: context, +/// useSystemAttachmentPicker: true, +/// customOptions: [ +/// SystemAttachmentPickerOption( +/// key: 'upload', +/// type: AttachmentPickerType.files, +/// icon: Icon(Icons.upload_file), +/// title: 'Upload File', +/// onTap: (context, controller) async { +/// // Handle file picker +/// }, +/// ), +/// ], +/// ); +/// ``` /// -/// The [enableDrag] parameter specifies whether the bottom sheet can be -/// dragged up and down and dismissed by swiping downwards. -/// -/// The optional [backgroundColor], [elevation], [shape], [clipBehavior], -/// [constraints] and [transitionAnimationController] -/// parameters can be passed in to customize the appearance and behavior of -/// modal bottom sheets (see the documentation for these on [BottomSheet] -/// for more details). -/// -/// The [transitionAnimationController] controls the bottom sheet's entrance and -/// exit animations if provided. -/// -/// The optional `routeSettings` parameter sets the [RouteSettings] -/// of the modal bottom sheet sheet. -/// This is particularly useful in the case that a user wants to observe -/// [PopupRoute]s within a [NavigatorObserver]. -/// -/// Returns a `Future` that resolves to the value (if any) that was passed to -/// [Navigator.pop] when the modal bottom sheet was closed. -/// -/// See also: -/// -/// * [BottomSheet], which becomes the parent of the widget returned by the -/// function passed as the `builder` argument to [showModalBottomSheet]. -/// * [showBottomSheet] and [ScaffoldState.showBottomSheet], for showing -/// non-modal bottom sheets. -/// * [DraggableScrollableSheet], which allows you to create a bottom sheet -/// that grows and then becomes scrollable once it reaches its maximum size. -/// * +/// Returns a [Future] that completes with the value passed to [Navigator.pop], +/// or `null` if the sheet was dismissed. Future showStreamAttachmentPickerModalBottomSheet({ required BuildContext context, Iterable? customOptions, List allowedTypes = AttachmentPickerType.values, Poll? initialPoll, PollConfig? pollConfig, + GalleryPickerConfig? galleryPickerConfig, List? initialAttachments, + Map? initialExtraData, StreamAttachmentPickerController? controller, - ErrorListener? onError, Color? backgroundColor, double? elevation, BoxConstraints? constraints, @@ -86,15 +83,11 @@ Future showStreamAttachmentPickerModalBottomSheet({ AnimationController? transitionAnimationController, Clip? clipBehavior = Clip.hardEdge, ShapeBorder? shape, - ThumbnailSize attachmentThumbnailSize = const ThumbnailSize(400, 400), - ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg, - int attachmentThumbnailQuality = 100, - double attachmentThumbnailScale = 1, }) { final colorTheme = StreamChatTheme.of(context).colorTheme; final color = backgroundColor ?? colorTheme.inputBg; - return showModalBottomSheet( + return showModalBottomSheet( context: context, backgroundColor: color, elevation: elevation, @@ -109,53 +102,73 @@ Future showStreamAttachmentPickerModalBottomSheet({ routeSettings: routeSettings, transitionAnimationController: transitionAnimationController, builder: (BuildContext context) { - return StreamPlatformAttachmentPickerBottomSheetBuilder( + return StreamAttachmentPickerBottomSheetBuilder( controller: controller, initialPoll: initialPoll, initialAttachments: initialAttachments, + initialExtraData: initialExtraData, builder: (context, controller, child) { final isWebOrDesktop = switch (CurrentPlatform.type) { - PlatformType.web || - PlatformType.macOS || - PlatformType.linux || - PlatformType.windows => - true, - _ => false, + PlatformType.android || PlatformType.ios => false, + _ => true, }; - final useSystemPicker = useSystemAttachmentPicker || // - useNativeAttachmentPickerOnMobile; + final useSystemPicker = useSystemAttachmentPicker || isWebOrDesktop; + + if (useSystemPicker) { + final invalidOptions = []; + final customSystemOptions = []; + + for (final option in customOptions ?? []) { + if (option is SystemAttachmentPickerOption) { + customSystemOptions.add(option); + } else { + invalidOptions.add(option); + } + } + + if (invalidOptions.isNotEmpty) { + throw ArgumentError( + 'customOptions must be SystemAttachmentPickerOption when using ' + 'the attachment picker (enabled explicitly or on web/desktop).', + ); + } - if (useSystemPicker || isWebOrDesktop) { - return webOrDesktopAttachmentPickerBuilder.call( + return systemAttachmentPickerBuilder.call( context: context, - onError: onError, controller: controller, allowedTypes: allowedTypes, - customOptions: customOptions?.map( - WebOrDesktopAttachmentPickerOption.fromAttachmentPickerOption, - ), - initialPoll: initialPoll, + customOptions: customSystemOptions, pollConfig: pollConfig, - attachmentThumbnailSize: attachmentThumbnailSize, - attachmentThumbnailFormat: attachmentThumbnailFormat, - attachmentThumbnailQuality: attachmentThumbnailQuality, - attachmentThumbnailScale: attachmentThumbnailScale, + galleryPickerConfig: galleryPickerConfig, ); } - return mobileAttachmentPickerBuilder.call( + final invalidOptions = []; + final customTabbedOptions = []; + + for (final option in customOptions ?? []) { + if (option is TabbedAttachmentPickerOption) { + customTabbedOptions.add(option); + } else { + invalidOptions.add(option); + } + } + + if (invalidOptions.isNotEmpty == true) { + throw ArgumentError( + 'customOptions must be TabbedAttachmentPickerOption when using ' + 'the tabbed picker (default on mobile).', + ); + } + + return tabbedAttachmentPickerBuilder.call( context: context, - onError: onError, controller: controller, allowedTypes: allowedTypes, - customOptions: customOptions, - initialPoll: initialPoll, + customOptions: customTabbedOptions, pollConfig: pollConfig, - attachmentThumbnailSize: attachmentThumbnailSize, - attachmentThumbnailFormat: attachmentThumbnailFormat, - attachmentThumbnailQuality: attachmentThumbnailQuality, - attachmentThumbnailScale: attachmentThumbnailScale, + galleryPickerConfig: galleryPickerConfig, ); }, ); @@ -164,13 +177,13 @@ Future showStreamAttachmentPickerModalBottomSheet({ } /// Builds the attachment picker bottom sheet. -class StreamPlatformAttachmentPickerBottomSheetBuilder extends StatefulWidget { +class StreamAttachmentPickerBottomSheetBuilder extends StatefulWidget { /// Creates a new instance of the widget. - const StreamPlatformAttachmentPickerBottomSheetBuilder({ + const StreamAttachmentPickerBottomSheetBuilder({ super.key, - this.customOptions, this.initialPoll, this.initialAttachments, + this.initialExtraData, this.child, this.controller, required this.builder, @@ -186,25 +199,25 @@ class StreamPlatformAttachmentPickerBottomSheetBuilder extends StatefulWidget { Widget? child, ) builder; - /// The custom options to be displayed in the attachment picker. - final List? customOptions; - /// The initial poll. final Poll? initialPoll; /// The initial attachments. final List? initialAttachments; + /// The initial extra data for the attachment picker. + final Map? initialExtraData; + /// The controller. final StreamAttachmentPickerController? controller; @override - State createState() => - _StreamPlatformAttachmentPickerBottomSheetBuilderState(); + State createState() => + _StreamAttachmentPickerBottomSheetBuilderState(); } -class _StreamPlatformAttachmentPickerBottomSheetBuilderState - extends State { +class _StreamAttachmentPickerBottomSheetBuilderState + extends State { late StreamAttachmentPickerController _controller; @override @@ -214,6 +227,7 @@ class _StreamPlatformAttachmentPickerBottomSheetBuilderState StreamAttachmentPickerController( initialPoll: widget.initialPoll, initialAttachments: widget.initialAttachments, + initialExtraData: widget.initialExtraData, ); } @@ -231,6 +245,7 @@ class _StreamPlatformAttachmentPickerBottomSheetBuilderState _controller = StreamAttachmentPickerController( initialPoll: widget.initialPoll, initialAttachments: widget.initialAttachments, + initialExtraData: widget.initialExtraData, ); } else { _controller = current; @@ -239,7 +254,7 @@ class _StreamPlatformAttachmentPickerBottomSheetBuilderState @override void didUpdateWidget( - StreamPlatformAttachmentPickerBottomSheetBuilder oldWidget, + StreamAttachmentPickerBottomSheetBuilder oldWidget, ) { super.didUpdateWidget(oldWidget); _updateAttachmentPickerController( diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_controller.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_controller.dart new file mode 100644 index 0000000000..1353931a42 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_controller.dart @@ -0,0 +1,259 @@ +import 'package:collection/collection.dart'; +import 'package:flutter/foundation.dart'; +import 'package:stream_chat_flutter/src/attachment/handler/stream_attachment_handler.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// The default maximum size for media attachments. +const kDefaultMaxAttachmentSize = 100 * 1024 * 1024; // 100MB in Bytes + +/// The default maximum number of media attachments. +const kDefaultMaxAttachmentCount = 10; + +/// Controller class for [StreamAttachmentPicker]. +class StreamAttachmentPickerController + extends ValueNotifier { + /// Creates a new instance of [StreamAttachmentPickerController]. + factory StreamAttachmentPickerController({ + Poll? initialPoll, + List? initialAttachments, + Map? initialExtraData, + int maxAttachmentSize = kDefaultMaxAttachmentSize, + int maxAttachmentCount = kDefaultMaxAttachmentCount, + }) { + return StreamAttachmentPickerController._fromValue( + AttachmentPickerValue( + poll: initialPoll, + attachments: initialAttachments ?? const [], + extraData: initialExtraData ?? const {}, + ), + maxAttachmentSize: maxAttachmentSize, + maxAttachmentCount: maxAttachmentCount, + ); + } + + StreamAttachmentPickerController._fromValue( + this.initialValue, { + this.maxAttachmentSize = kDefaultMaxAttachmentSize, + this.maxAttachmentCount = kDefaultMaxAttachmentCount, + }) : assert( + (initialValue.attachments.length) <= maxAttachmentCount, + '''The initial attachments count must be less than or equal to maxAttachmentCount''', + ), + super(initialValue); + + /// Initial value for the controller. + final AttachmentPickerValue initialValue; + + /// The max attachment size allowed in bytes. + final int maxAttachmentSize; + + /// The max attachment count allowed. + final int maxAttachmentCount; + + @override + set value(AttachmentPickerValue newValue) { + if (newValue.attachments.length > maxAttachmentCount) { + throw ArgumentError( + 'The maximum number of attachments is $maxAttachmentCount.', + ); + } + super.value = newValue; + } + + /// Adds a new [poll] to the message. + set poll(Poll? poll) => value = value.copyWith(poll: poll); + + /// Sets the extra data value for the controller. + /// + /// This can be used to store custom attachment values in case a custom + /// attachment picker option is used. + set extraData(Map? extraData) { + value = value.copyWith(extraData: extraData); + } + + Future _saveToCache(AttachmentFile file) async { + // Cache the attachment in a temporary file. + return StreamAttachmentHandler.instance.saveAttachmentFile( + attachmentFile: file, + ); + } + + Future _removeFromCache(AttachmentFile file) { + // Remove the cached attachment file. + return StreamAttachmentHandler.instance.deleteAttachmentFile( + attachmentFile: file, + ); + } + + /// Adds a new attachment to the message. + Future addAttachment(Attachment attachment) async { + assert(attachment.fileSize != null, ''); + if (attachment.fileSize! > maxAttachmentSize) { + throw ArgumentError( + 'The size of the attachment is ${attachment.fileSize} bytes, ' + 'but the maximum size allowed is $maxAttachmentSize bytes.', + ); + } + + final file = attachment.file; + final uploadState = attachment.uploadState; + + // No need to cache the attachment if it's already uploaded + // or we are on web. + if (file == null || uploadState.isSuccess || CurrentPlatform.isWeb) { + value = value.copyWith(attachments: [...value.attachments, attachment]); + return; + } + + // Cache the attachment in a temporary file. + final tempFilePath = await _saveToCache(file); + + value = value.copyWith(attachments: [ + ...value.attachments, + attachment.copyWith( + file: file.copyWith( + path: tempFilePath, + ), + ), + ]); + } + + /// Removes the specified [attachment] from the message. + Future removeAttachment(Attachment attachment) async { + final file = attachment.file; + final uploadState = attachment.uploadState; + + if (file == null || uploadState.isSuccess || CurrentPlatform.isWeb) { + final updatedAttachments = [...value.attachments]..remove(attachment); + value = value.copyWith(attachments: updatedAttachments); + return; + } + + // Remove the cached attachment file. + await _removeFromCache(file); + + final updatedAttachments = [...value.attachments]..remove(attachment); + value = value.copyWith(attachments: updatedAttachments); + } + + /// Remove the attachment with the given [attachmentId]. + void removeAttachmentById(String attachmentId) { + final attachment = value.attachments.firstWhereOrNull( + (attachment) => attachment.id == attachmentId, + ); + + if (attachment == null) return; + + removeAttachment(attachment); + } + + /// Clears all the attachments. + Future clear() async { + final attachments = [...value.attachments]; + for (final attachment in attachments) { + final file = attachment.file; + final uploadState = attachment.uploadState; + + if (file == null || uploadState.isSuccess || CurrentPlatform.isWeb) { + continue; + } + + await _removeFromCache(file); + } + value = const AttachmentPickerValue(); + } + + /// Resets the controller to its initial state. + Future reset() async { + final attachments = [...value.attachments]; + for (final attachment in attachments) { + final file = attachment.file; + final uploadState = attachment.uploadState; + + if (file == null || uploadState.isSuccess || CurrentPlatform.isWeb) { + continue; + } + + await _removeFromCache(file); + } + + value = initialValue; + } +} + +/// Value class for [AttachmentPickerController]. +/// +/// This class holds the list of [Poll] and [Attachment] objects. +class AttachmentPickerValue { + /// Creates a new instance of [AttachmentPickerValue]. + const AttachmentPickerValue({ + this.poll, + this.attachments = const [], + this.extraData = const {}, + }); + + /// The poll object. + final Poll? poll; + + /// The list of [Attachment] objects. + final List attachments; + + /// Extra data that can be used to store custom attachment values. + final Map extraData; + + /// Returns true if the value is empty, meaning it has no poll, + /// no attachments and no extra data set. + bool get isEmpty { + if (poll != null) return false; + if (attachments.isNotEmpty) return false; + if (extraData.isNotEmpty) return false; + + return true; + } + + /// Returns a copy of this object with the provided values. + AttachmentPickerValue copyWith({ + Poll? poll, + List? attachments, + Map? extraData, + }) { + return AttachmentPickerValue( + poll: poll ?? this.poll, + attachments: attachments ?? this.attachments, + extraData: extraData ?? this.extraData, + ); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (other.runtimeType != runtimeType) return false; + if (other is! AttachmentPickerValue) return false; + + final isPollEqual = other.poll == poll; + + final areAttachmentsEqual = UnorderedIterableEquality( + EqualityBy((attachment) => attachment.id), + ).equals(other.attachments, attachments); + + final isExtraDataEqual = const DeepCollectionEquality.unordered().equals( + other.extraData, + extraData, + ); + + return isPollEqual && areAttachmentsEqual && isExtraDataEqual; + } + + @override + int get hashCode { + final attachmentsHash = UnorderedIterableEquality( + EqualityBy((attachment) => attachment.id), + ).hash(attachments); + + final extraDataHash = const DeepCollectionEquality.unordered().hash( + extraData, + ); + + return poll.hashCode ^ attachmentsHash ^ extraDataHash; + } +} diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_option.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_option.dart new file mode 100644 index 0000000000..1eec1d4638 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_option.dart @@ -0,0 +1,198 @@ +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/message_input/attachment_picker/stream_attachment_picker_controller.dart'; + +/// Function signature for building the attachment picker option view. +typedef AttachmentPickerOptionViewBuilder = Widget Function( + BuildContext context, + StreamAttachmentPickerController controller, +); + +/// Function signature for system attachment picker option callback. +typedef OnSystemAttachmentPickerOptionTap = Future Function( + BuildContext context, + StreamAttachmentPickerController controller, +); + +/// Base class for attachment picker options. +abstract class AttachmentPickerOption { + /// Creates a new instance of [AttachmentPickerOption]. + const AttachmentPickerOption({ + this.key, + required this.supportedTypes, + required this.icon, + this.title, + this.isEnabled = _defaultIsEnabled, + }); + + /// A key to identify the option. + final String? key; + + /// The icon of the option. + final Widget icon; + + /// The title of the option. + final String? title; + + /// The supported types of the option. + final Iterable supportedTypes; + + /// Determines if this option is enabled based on the current value. + /// + /// If not provided, defaults to always returning true. + final bool Function(AttachmentPickerValue value) isEnabled; + static bool _defaultIsEnabled(AttachmentPickerValue value) => true; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (other is! AttachmentPickerOption) return false; + if (runtimeType != other.runtimeType) return false; + + final areSupportedTypesEqual = const UnorderedIterableEquality().equals( + supportedTypes, + other.supportedTypes, + ); + + return key == other.key && areSupportedTypesEqual; + } + + @override + int get hashCode { + final supportedTypesHash = const UnorderedIterableEquality().hash( + supportedTypes, + ); + + return key.hashCode ^ supportedTypesHash; + } +} + +/// Attachment picker option that shows custom UI inside the attachment picker's +/// tabbed interface. Use this when you want to display your own custom +/// interface for selecting attachments. +/// +/// This option is used when the attachment picker displays a tabbed interface +/// (typically on mobile when useSystemAttachmentPicker is false). +class TabbedAttachmentPickerOption extends AttachmentPickerOption { + /// Creates a new instance of [TabbedAttachmentPickerOption]. + const TabbedAttachmentPickerOption({ + super.key, + required super.supportedTypes, + required super.icon, + required this.optionViewBuilder, + super.title, + super.isEnabled, + }); + + /// The option view builder for custom UI. + final AttachmentPickerOptionViewBuilder optionViewBuilder; +} + +/// Attachment picker option that uses system integration +/// (file dialogs, camera, etc.). +/// +/// Use this when you want to open system pickers or perform system actions. +class SystemAttachmentPickerOption extends AttachmentPickerOption { + /// Creates a new instance of [SystemAttachmentPickerOption]. + const SystemAttachmentPickerOption({ + super.key, + required super.supportedTypes, + required super.icon, + required this.title, + required this.onTap, + super.isEnabled, + }); + + @override + final String title; + + /// The callback that is called when the option is tapped. + final OnSystemAttachmentPickerOptionTap onTap; +} + +/// Helpful extensions for [StreamAttachmentPickerController]. +extension AttachmentPickerOptionTypeX on AttachmentPickerValue { + /// Returns the list of enabled picker types. + Set filterEnabledTypes({ + required Iterable options, + }) { + final enabledTypes = {}; + for (final option in options) { + if (option.isEnabled.call(this)) { + enabledTypes.addAll(option.supportedTypes); + } + } + return enabledTypes; + } +} + +/// {@template streamAttachmentPickerType} +/// A sealed class that represents different types of attachment which a picker +/// option can support. +/// {@endtemplate} +sealed class AttachmentPickerType { + const AttachmentPickerType(); + + /// The option will allow to pick images. + static const images = ImagesPickerType(); + + /// The option will allow to pick videos. + static const videos = VideosPickerType(); + + /// The option will allow to pick audios. + static const audios = AudiosPickerType(); + + /// The option will allow to pick files or documents. + static const files = FilesPickerType(); + + /// The option will allow to create a poll. + static const poll = PollPickerType(); + + /// A list of all predefined attachment picker types. + static const values = [images, videos, audios, files, poll]; +} + +/// A predefined attachment picker type that allows picking images. +final class ImagesPickerType extends AttachmentPickerType { + /// Creates a new images picker type. + const ImagesPickerType(); +} + +/// A predefined attachment picker type that allows picking videos. +final class VideosPickerType extends AttachmentPickerType { + /// Creates a new videos picker type. + const VideosPickerType(); +} + +/// A predefined attachment picker type that allows picking audios. +final class AudiosPickerType extends AttachmentPickerType { + /// Creates a new audios picker type. + const AudiosPickerType(); +} + +/// A predefined attachment picker type that allows picking files or documents. +final class FilesPickerType extends AttachmentPickerType { + /// Creates a new files picker type. + const FilesPickerType(); +} + +/// A predefined attachment picker type that allows creating polls. +final class PollPickerType extends AttachmentPickerType { + /// Creates a new poll picker type. + const PollPickerType(); +} + +/// A custom picker type that can be extended to support custom types of +/// attachments. This allows developers to create their own attachment picker +/// options for specialized content types. +/// +/// Example: +/// ```dart +/// class DocumentPickerType extends CustomAttachmentPickerType { +/// const DocumentPickerType(); +/// } +/// ``` +abstract class CustomAttachmentPickerType extends AttachmentPickerType { + /// Creates a new custom picker type. + const CustomAttachmentPickerType(); +} diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_result.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_result.dart new file mode 100644 index 0000000000..770fc4422b --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_result.dart @@ -0,0 +1,58 @@ +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; + +/// Signature for a function that is called when a custom attachment picker +/// result is received. +typedef OnCustomAttachmentPickerResult + = OnAttachmentPickerResult; + +/// Signature for a function that is called when a attachment picker result +/// is received. +typedef OnAttachmentPickerResult = void + Function(T result); + +/// {@template streamAttachmentPickerAction} +/// A sealed class that represents different results that can be returned +/// from the attachment picker. +/// {@endtemplate} +sealed class StreamAttachmentPickerResult { + const StreamAttachmentPickerResult(); +} + +/// A result indicating that the attachment picker was met with an error. +final class AttachmentPickerError extends StreamAttachmentPickerResult { + /// Create a new attachment picker error result + const AttachmentPickerError({required this.error, this.stackTrace}); + + /// The error that occurred in the attachment picker. + final Object error; + + /// The stack trace associated with the error, if available. + final StackTrace? stackTrace; +} + +/// A result indicating that some attachments were picked using the media +/// related options in the attachment picker (e.g., camera, gallery). +final class AttachmentsPicked extends StreamAttachmentPickerResult { + /// Create a new attachments picked result + const AttachmentsPicked({required this.attachments}); + + /// The list of attachments that were picked. + final List attachments; +} + +/// A result indicating that a poll was created using the create poll option +/// in the attachment picker. +final class PollCreated extends StreamAttachmentPickerResult { + /// Create a new poll created result + const PollCreated({required this.poll}); + + /// The poll that was created. + final Poll poll; +} + +/// A custom attachment picker result that can be extended to support +/// custom type of results from the attachment picker. +class CustomAttachmentPickerResult extends StreamAttachmentPickerResult { + /// Create a new custom attachment picker result + const CustomAttachmentPickerResult(); +} diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart index 52f723d324..7ae8d3a440 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart @@ -165,6 +165,8 @@ class StreamMessageInput extends StatefulWidget { ) bool useNativeAttachmentPickerOnMobile = false, this.pollConfig, + this.customAttachmentPickerOptions = const [], + this.onCustomAttachmentPickerResult, }) : assert( idleSendIcon == null || idleSendButton == null, 'idleSendIcon and idleSendButton cannot be used together', @@ -424,6 +426,16 @@ class StreamMessageInput extends StatefulWidget { /// If not provided, the default configuration is used. final PollConfig? pollConfig; + /// A list of custom attachment picker options that can be used to extend the + /// attachment picker functionality. + final List customAttachmentPickerOptions; + + /// Callback that is called when the custom attachment picker result is + /// received. + /// + /// This is used to handle the result of the custom attachment picker + final OnCustomAttachmentPickerResult? onCustomAttachmentPickerResult; + static String? _defaultHintGetter( BuildContext context, HintType type, @@ -946,39 +958,28 @@ class StreamMessageInputState extends State defaultButton; } - Future _sendPoll(Poll poll) { - final streamChannel = StreamChannel.of(context); - final channel = streamChannel.channel; - - return channel.sendPoll(poll); - } - - Future _updatePoll(Poll poll) { - final streamChannel = StreamChannel.of(context); - final channel = streamChannel.channel; - - return channel.updatePoll(poll); - } - - Future _deletePoll(Poll poll) { - final streamChannel = StreamChannel.of(context); - final channel = streamChannel.channel; - - return channel.deletePoll(poll); + Future _onPollCreated(Poll poll) async { + final channel = StreamChannel.of(context).channel; + return channel.sendPoll(poll).ignore(); } - Future _createOrUpdatePoll(Poll? old, Poll? current) async { - // If both are null or the same, return - if ((old == null && current == null) || old == current) return; + // Returns the list of allowed attachment picker types based on the + // current channel configuration and context. + List _getAllowedAttachmentPickerTypes() { + final allowedTypes = widget.allowedAttachmentPickerTypes.where((type) { + if (type != AttachmentPickerType.poll) return true; - // If old is null, i.e., there was no poll before, create the poll. - if (old == null) return _sendPoll(current!); + // We don't allow editing polls. + if (_isEditing) return false; + // We don't allow creating polls in threads. + if (_effectiveController.message.parentId != null) return false; - // If current is null, i.e., the poll is removed, delete the poll. - if (current == null) return _deletePoll(old); + // Otherwise, check if the user has the permission to send polls. + final channel = StreamChannel.of(context).channel; + return channel.config?.polls == true && channel.canSendPoll; + }); - // Otherwise, update the poll. - return _updatePoll(current); + return allowedTypes.toList(growable: false); } /// Handle the platform-specific logic for selecting files. @@ -989,40 +990,46 @@ class StreamMessageInputState extends State Future _onAttachmentButtonPressed() async { final initialPoll = _effectiveController.poll; final initialAttachments = _effectiveController.attachments; - - // Remove AttachmentPickerType.poll if the user doesn't have the permission - // to send a poll or if this is a thread message. - final allowedTypes = [...widget.allowedAttachmentPickerTypes] - ..removeWhere((it) { - if (it != AttachmentPickerType.poll) return false; - if (_effectiveController.message.parentId != null) return true; - final channel = StreamChannel.of(context).channel; - if (channel.config?.polls == true && channel.canSendPoll) return false; - - return true; - }); + final allowedTypes = _getAllowedAttachmentPickerTypes(); final messageInputTheme = StreamMessageInputTheme.of(context); final useSystemPicker = widget.useSystemAttachmentPicker || (messageInputTheme.useSystemAttachmentPicker ?? false); - final value = await showStreamAttachmentPickerModalBottomSheet( + final result = await showStreamAttachmentPickerModalBottomSheet( context: context, - onError: widget.onError, allowedTypes: allowedTypes, - pollConfig: widget.pollConfig, initialPoll: initialPoll, + pollConfig: widget.pollConfig, initialAttachments: initialAttachments, useSystemAttachmentPicker: useSystemPicker, + customOptions: widget.customAttachmentPickerOptions, ); - if (value == null || value is! AttachmentPickerValue) return; + if (result == null || result is! StreamAttachmentPickerResult) return; + + void _onAttachmentsPicked(List attachments) { + _effectiveController.attachments = attachments; + } - // Add the attachments to the controller. - _effectiveController.attachments = value.attachments; + void _onAttachmentPickerError(AttachmentPickerError error) { + return widget.onError?.call(error.error, error.stackTrace); + } - // Create or update the poll. - await _createOrUpdatePoll(initialPoll, value.poll); + void _onCustomAttachmentPickerResult(CustomAttachmentPickerResult result) { + return widget.onCustomAttachmentPickerResult?.call(result); + } + + return switch (result) { + // Add the attachments to the controller. + AttachmentsPicked() => _onAttachmentsPicked(result.attachments), + // Send the created poll in the channel. + PollCreated() => _onPollCreated(result.poll), + // Handle custom attachment picker results. + CustomAttachmentPickerResult() => _onCustomAttachmentPickerResult(result), + // Handle/Notify returned errors. + AttachmentPickerError() => _onAttachmentPickerError(result), + }; } Widget _buildTextInput(BuildContext context) { diff --git a/packages/stream_chat_flutter/lib/src/utils/extensions.dart b/packages/stream_chat_flutter/lib/src/utils/extensions.dart index f98af3526c..dfda73cc6a 100644 --- a/packages/stream_chat_flutter/lib/src/utils/extensions.dart +++ b/packages/stream_chat_flutter/lib/src/utils/extensions.dart @@ -472,18 +472,12 @@ extension TypeX on T? { extension FileTypeX on FileType { /// Converts the [FileType] to a [String]. String toAttachmentType() { - switch (this) { - case FileType.image: - return AttachmentType.image; - case FileType.video: - return AttachmentType.video; - case FileType.audio: - return AttachmentType.audio; - case FileType.any: - case FileType.media: - case FileType.custom: - return AttachmentType.file; - } + return switch (this) { + FileType.image => AttachmentType.image, + FileType.video => AttachmentType.video, + FileType.audio => AttachmentType.audio, + FileType.any || FileType.media || FileType.custom => AttachmentType.file, + }; } } @@ -491,18 +485,16 @@ extension FileTypeX on FileType { extension AttachmentPickerTypeX on AttachmentPickerType { /// Converts the [AttachmentPickerType] to a [FileType]. FileType get fileType { - switch (this) { - case AttachmentPickerType.images: - return FileType.image; - case AttachmentPickerType.videos: - return FileType.video; - case AttachmentPickerType.files: - return FileType.any; - case AttachmentPickerType.audios: - return FileType.audio; - case AttachmentPickerType.poll: - throw Exception('Polls do not have a file type'); - } + return switch (this) { + ImagesPickerType() => FileType.image, + VideosPickerType() => FileType.video, + AudiosPickerType() => FileType.audio, + FilesPickerType() => FileType.any, + _ => throw Exception( + 'Unsupported AttachmentPickerType: $this. ' + 'Only Images, Videos, Audios and Files are supported.', + ), + }; } } diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 0f47afb664..5471df1380 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -57,6 +57,9 @@ export 'src/message_action/message_action_item.dart'; export 'src/message_action/message_actions_builder.dart'; export 'src/message_input/attachment_picker/stream_attachment_picker.dart'; export 'src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart'; +export 'src/message_input/attachment_picker/stream_attachment_picker_controller.dart'; +export 'src/message_input/attachment_picker/stream_attachment_picker_option.dart'; +export 'src/message_input/attachment_picker/stream_attachment_picker_result.dart'; export 'src/message_input/audio_recorder/audio_recorder_controller.dart'; export 'src/message_input/audio_recorder/audio_recorder_state.dart'; export 'src/message_input/audio_recorder/stream_audio_recorder.dart'; From cc33ba3e9a3bac9b0d1f23ae225b3c2b3092499a Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 16 Jul 2025 15:27:31 +0200 Subject: [PATCH 15/34] chore(repo): remove deprecated classes, methods, and properties (#2306) --- packages/stream_chat/CHANGELOG.md | 10 + .../stream_chat/lib/src/client/channel.dart | 9 - .../stream_chat/lib/src/client/client.dart | 21 - .../lib/src/core/api/call_api.dart | 42 - .../lib/src/core/api/responses.dart | 32 - .../lib/src/core/api/responses.g.dart | 14 - .../lib/src/core/api/sort_order.dart | 19 +- .../lib/src/core/api/sort_order.g.dart | 7 - .../lib/src/core/api/stream_chat_api.dart | 7 - .../lib/src/core/models/call_payload.dart | 73 - .../lib/src/core/models/call_payload.g.dart | 27 - .../lib/src/core/models/message.dart | 61 +- .../lib/src/core/models/message.g.dart | 10 +- .../stream_chat/lib/src/permission_type.dart | 103 -- packages/stream_chat/lib/stream_chat.dart | 1 - .../stream_chat/test/fixtures/message.json | 12 +- .../test/src/core/api/call_api_test.dart | 67 - .../test/src/core/api/responses_test.dart | 32 - .../test/src/core/api/sort_order_test.dart | 7 - .../src/core/models/call_payload_test.dart | 39 - .../test/src/core/models/message_test.dart | 26 +- packages/stream_chat_flutter/CHANGELOG.md | 6 + .../builder/attachment_widget_builder.dart | 1 - .../stream_voice_recording_list_player.dart | 139 -- .../stream_voice_recording_loading.dart | 33 - .../stream_voice_recording_player.dart | 320 ----- .../stream_voice_recording_slider.dart | 239 ---- .../voice_recording_attachment_builder.dart | 35 - .../stream_attachment_handler_base.dart | 2 +- .../stream_attachment_handler_html.dart | 2 - .../handler/stream_attachment_handler_io.dart | 2 - .../lib/src/icons/stream_svg_icon.dart | 1233 +---------------- .../lib/src/indicators/unread_indicator.dart | 8 +- .../options/stream_file_picker.dart | 8 +- ...stream_attachment_picker_bottom_sheet.dart | 2 - .../lib/src/message_input/dm_checkbox.dart | 78 -- .../message_input/stream_message_input.dart | 42 +- .../stream_message_send_button.dart | 37 +- .../floating_date_divider.dart | 6 - .../lib/src/misc/back_button.dart | 2 +- .../lib/src/theme/stream_chat_theme.dart | 21 - .../lib/src/theme/themes.dart | 1 - .../lib/src/theme/voice_attachment_theme.dart | 466 ------- .../lib/src/utils/extensions.dart | 18 - .../lib/src/video/video_thumbnail_image.dart | 8 +- .../lib/stream_chat_flutter.dart | 5 - .../src/indicators/unread_indicator_test.dart | 2 +- .../src/message_input/dm_checkbox_test.dart | 134 -- .../test/src/utils/extension_test.dart | 120 -- .../pages/channel_file_display_screen.dart | 5 +- sample_app/lib/pages/channel_list_page.dart | 2 +- .../pages/channel_media_display_screen.dart | 5 +- sample_app/lib/pages/chat_info_screen.dart | 3 +- sample_app/lib/pages/group_info_screen.dart | 20 +- sample_app/lib/pages/new_chat_screen.dart | 5 +- .../lib/pages/pinned_messages_screen.dart | 5 +- 56 files changed, 97 insertions(+), 3537 deletions(-) delete mode 100644 packages/stream_chat/lib/src/core/api/call_api.dart delete mode 100644 packages/stream_chat/lib/src/core/models/call_payload.dart delete mode 100644 packages/stream_chat/lib/src/core/models/call_payload.g.dart delete mode 100644 packages/stream_chat/lib/src/permission_type.dart delete mode 100644 packages/stream_chat/test/src/core/api/call_api_test.dart delete mode 100644 packages/stream_chat/test/src/core/models/call_payload_test.dart delete mode 100644 packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player.dart delete mode 100644 packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading.dart delete mode 100644 packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart delete mode 100644 packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_slider.dart delete mode 100644 packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder.dart delete mode 100644 packages/stream_chat_flutter/lib/src/message_input/dm_checkbox.dart delete mode 100644 packages/stream_chat_flutter/lib/src/theme/voice_attachment_theme.dart delete mode 100644 packages/stream_chat_flutter/test/src/message_input/dm_checkbox_test.dart diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index b388c37cdc..fa5501b136 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,13 @@ +## Upcoming Beta + +🛑️ Breaking + +- **Deprecated API Cleanup**: Removed all deprecated classes, methods, and properties for the v10 major release: + - **Removed Classes**: `PermissionType` (use string constants like `'delete-channel'`, `'update-channel'`), `CallApi`, `CallPayload`, `CallTokenPayload`, `CreateCallPayload` + - **Removed Methods**: `cooldownStartedAt` getter from `Channel`, `getCallToken` and `createCall` from `StreamChatClient` + - **Removed Properties**: `reactionCounts` and `reactionScores` getters from `Message` (use `reactionGroups` instead), `call` property from `StreamChatApi` + - **Removed Files**: `permission_type.dart`, `call_api.dart`, `call_payload.dart` and their associated tests + ## Upcoming 🐞 Fixed diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 009047def6..6f42f2bbf8 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -306,15 +306,6 @@ class Channel { return math.max(0, cooldownDuration - elapsedTime); } - /// Stores time at which cooldown was started - @Deprecated( - "Use a combination of 'remainingCooldown' and 'currentUserLastMessageAt'", - ) - DateTime? get cooldownStartedAt { - if (getRemainingCooldown() <= 0) return null; - return currentUserLastMessageAt; - } - /// Channel creation date. DateTime? get createdAt { _checkInitialized(); diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index a55530ef8a..316d576391 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -695,27 +695,6 @@ class StreamChatClient { } } - /// Returns a token associated with the [callId]. - @Deprecated('Will be removed in the next major version') - Future getCallToken(String callId) async => - _chatApi.call.getCallToken(callId); - - /// Creates a new call. - @Deprecated('Will be removed in the next major version') - Future createCall({ - required String callId, - required String callType, - required String channelType, - required String channelId, - }) { - return _chatApi.call.createCall( - callId: callId, - callType: callType, - channelType: channelType, - channelId: channelId, - ); - } - /// Requests channels with a given query from the API. Future> queryChannelsOnline({ Filter? filter, diff --git a/packages/stream_chat/lib/src/core/api/call_api.dart b/packages/stream_chat/lib/src/core/api/call_api.dart deleted file mode 100644 index 4981cb0a93..0000000000 --- a/packages/stream_chat/lib/src/core/api/call_api.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:stream_chat/src/core/api/responses.dart'; -import 'package:stream_chat/src/core/http/stream_http_client.dart'; - -/// Defines the api dedicated to call operations. -@Deprecated('Will be removed in the next major version') -class CallApi { - /// Initialize a new call api - CallApi(this._client); - - final StreamHttpClient _client; - - /// Returns a token dedicated to the [callId] - Future getCallToken(String callId) async { - final response = await _client.post( - '/calls/$callId', - data: {}, - ); - // return response.data; - return CallTokenPayload.fromJson(response.data); - } - - /// Creates a new call - Future createCall({ - required String callId, - required String callType, - required String channelType, - required String channelId, - }) async { - final response = await _client.post( - _getChannelUrl(channelId, channelType), - data: { - 'id': callId, - 'type': callType, - }, - ); - // return response.data; - return CreateCallPayload.fromJson(response.data); - } - - String _getChannelUrl(String channelId, String channelType) => - '/channels/$channelType/$channelId/call'; -} diff --git a/packages/stream_chat/lib/src/core/api/responses.dart b/packages/stream_chat/lib/src/core/api/responses.dart index 0602e71f35..128adf4bdb 100644 --- a/packages/stream_chat/lib/src/core/api/responses.dart +++ b/packages/stream_chat/lib/src/core/api/responses.dart @@ -1,9 +1,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:stream_chat/src/client/client.dart'; -import 'package:stream_chat/src/core/api/call_api.dart'; import 'package:stream_chat/src/core/error/error.dart'; import 'package:stream_chat/src/core/models/banned_user.dart'; -import 'package:stream_chat/src/core/models/call_payload.dart'; import 'package:stream_chat/src/core/models/channel_model.dart'; import 'package:stream_chat/src/core/models/channel_state.dart'; import 'package:stream_chat/src/core/models/device.dart'; @@ -513,36 +511,6 @@ class OGAttachmentResponse extends _BaseResponse { _$OGAttachmentResponseFromJson(json); } -/// The response to [CallApi.getCallToken] -@Deprecated('Will be removed in the next major version') -@JsonSerializable(createToJson: false) -class CallTokenPayload extends _BaseResponse { - /// Create a new instance from a [json]. - static CallTokenPayload fromJson(Map json) => - _$CallTokenPayloadFromJson(json); - - /// The token to use for the call. - String? token; - - /// The user id specific to Agora. - int? agoraUid; - - /// The appId specific to Agora. - String? agoraAppId; -} - -/// The response to [CallApi.createCall] -@Deprecated('Will be removed in the next major version') -@JsonSerializable(createToJson: false) -class CreateCallPayload extends _BaseResponse { - /// Create a new instance from a [json]. - static CreateCallPayload fromJson(Map json) => - _$CreateCallPayloadFromJson(json); - - /// The call object. - CallPayload? call; -} - /// Contains information about a [User] that was banned from a [Channel] or App. @JsonSerializable(createToJson: false) class UserBlockResponse extends _BaseResponse { diff --git a/packages/stream_chat/lib/src/core/api/responses.g.dart b/packages/stream_chat/lib/src/core/api/responses.g.dart index 75dcc1595e..345cb45481 100644 --- a/packages/stream_chat/lib/src/core/api/responses.g.dart +++ b/packages/stream_chat/lib/src/core/api/responses.g.dart @@ -307,20 +307,6 @@ OGAttachmentResponse _$OGAttachmentResponseFromJson( ..titleLink = json['title_link'] as String? ..type = json['type'] as String?; -CallTokenPayload _$CallTokenPayloadFromJson(Map json) => - CallTokenPayload() - ..duration = json['duration'] as String? - ..token = json['token'] as String? - ..agoraUid = (json['agora_uid'] as num?)?.toInt() - ..agoraAppId = json['agora_app_id'] as String?; - -CreateCallPayload _$CreateCallPayloadFromJson(Map json) => - CreateCallPayload() - ..duration = json['duration'] as String? - ..call = json['call'] == null - ? null - : CallPayload.fromJson(json['call'] as Map); - UserBlockResponse _$UserBlockResponseFromJson(Map json) => UserBlockResponse() ..duration = json['duration'] as String? diff --git a/packages/stream_chat/lib/src/core/api/sort_order.dart b/packages/stream_chat/lib/src/core/api/sort_order.dart index e37fd445e3..e04ca10264 100644 --- a/packages/stream_chat/lib/src/core/api/sort_order.dart +++ b/packages/stream_chat/lib/src/core/api/sort_order.dart @@ -34,21 +34,8 @@ enum NullOrdering { /// // Sort channels by last message date in descending order /// final sort = SortOption("last_message_at"); /// ``` -@JsonSerializable(includeIfNull: false) +@JsonSerializable(createFactory: false, includeIfNull: false) class SortOption { - /// Creates a new SortOption instance with the specified field and direction. - /// - /// ```dart - /// final sorting = SortOption("last_message_at") // Default: descending order - /// ``` - @Deprecated('Use SortOption.desc or SortOption.asc instead') - const SortOption( - this.field, { - this.direction = SortOption.DESC, - this.nullOrdering = NullOrdering.nullsFirst, - Comparator? comparator, - }) : _comparator = comparator; - /// Creates a SortOption for descending order sorting by the specified field. /// /// Example: @@ -77,10 +64,6 @@ class SortOption { }) : direction = SortOption.ASC, _comparator = comparator; - /// Create a new instance from JSON. - factory SortOption.fromJson(Map json) => - _$SortOptionFromJson(json); - /// Ascending order (1) static const ASC = 1; diff --git a/packages/stream_chat/lib/src/core/api/sort_order.g.dart b/packages/stream_chat/lib/src/core/api/sort_order.g.dart index 1a4e70f1fe..31f18e61c9 100644 --- a/packages/stream_chat/lib/src/core/api/sort_order.g.dart +++ b/packages/stream_chat/lib/src/core/api/sort_order.g.dart @@ -6,13 +6,6 @@ part of 'sort_order.dart'; // JsonSerializableGenerator // ************************************************************************** -SortOption _$SortOptionFromJson( - Map json) => - SortOption( - json['field'] as String, - direction: (json['direction'] as num?)?.toInt() ?? SortOption.DESC, - ); - Map _$SortOptionToJson( SortOption instance) => { diff --git a/packages/stream_chat/lib/src/core/api/stream_chat_api.dart b/packages/stream_chat/lib/src/core/api/stream_chat_api.dart index 1f94ffe77a..85cbf4aa7e 100644 --- a/packages/stream_chat/lib/src/core/api/stream_chat_api.dart +++ b/packages/stream_chat/lib/src/core/api/stream_chat_api.dart @@ -1,7 +1,6 @@ import 'package:dio/dio.dart'; import 'package:logging/logging.dart'; import 'package:stream_chat/src/core/api/attachment_file_uploader.dart'; -import 'package:stream_chat/src/core/api/call_api.dart'; import 'package:stream_chat/src/core/api/channel_api.dart'; import 'package:stream_chat/src/core/api/device_api.dart'; import 'package:stream_chat/src/core/api/general_api.dart'; @@ -70,12 +69,6 @@ class StreamChatApi { ThreadsApi get threads => _threads ??= ThreadsApi(_client); ThreadsApi? _threads; - /// Api dedicated to call operations - @Deprecated('Will be removed in the next major version') - CallApi get call => _call ??= CallApi(_client); - @Deprecated('Will be removed in the next major version') - CallApi? _call; - /// Api dedicated to channel operations ChannelApi get channel => _channel ??= ChannelApi(_client); ChannelApi? _channel; diff --git a/packages/stream_chat/lib/src/core/models/call_payload.dart b/packages/stream_chat/lib/src/core/models/call_payload.dart deleted file mode 100644 index 2f1fdf206b..0000000000 --- a/packages/stream_chat/lib/src/core/models/call_payload.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'call_payload.g.dart'; - -/// Model containing the information about a call. -@JsonSerializable(createToJson: false) -@Deprecated('Will be removed in the next major version') -class CallPayload extends Equatable { - /// Create a new instance. - const CallPayload({ - required this.id, - required this.provider, - this.agora, - this.hms, - }); - - /// Create a new instance from a [json]. - factory CallPayload.fromJson(Map json) => - _$CallPayloadFromJson(json); - - /// The call id. - final String id; - - /// The call provider. - final String provider; - - /// The payload specific to Agora. - final AgoraPayload? agora; - - /// The payload specific to 100ms. - final HMSPayload? hms; - - @override - List get props => [id, provider, agora, hms]; -} - -/// Payload for Agora call. -@JsonSerializable(createToJson: false) -class AgoraPayload extends Equatable { - /// Create a new instance. - const AgoraPayload({required this.channel}); - - /// Create a new instance from a [json]. - factory AgoraPayload.fromJson(Map json) => - _$AgoraPayloadFromJson(json); - - /// The Agora channel. - final String channel; - - @override - List get props => [channel]; -} - -/// Payload for 100ms call. -@JsonSerializable(createToJson: false) -class HMSPayload extends Equatable { - /// Create a new instance. - const HMSPayload({required this.roomId, required this.roomName}); - - /// Create a new instance from a [json]. - factory HMSPayload.fromJson(Map json) => - _$HMSPayloadFromJson(json); - - /// The id of the 100ms room. - final String roomId; - - /// The name of the 100ms room. - final String roomName; - - @override - List get props => [roomId, roomName]; -} diff --git a/packages/stream_chat/lib/src/core/models/call_payload.g.dart b/packages/stream_chat/lib/src/core/models/call_payload.g.dart deleted file mode 100644 index bc786cc5db..0000000000 --- a/packages/stream_chat/lib/src/core/models/call_payload.g.dart +++ /dev/null @@ -1,27 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'call_payload.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -CallPayload _$CallPayloadFromJson(Map json) => CallPayload( - id: json['id'] as String, - provider: json['provider'] as String, - agora: json['agora'] == null - ? null - : AgoraPayload.fromJson(json['agora'] as Map), - hms: json['hms'] == null - ? null - : HMSPayload.fromJson(json['hms'] as Map), - ); - -AgoraPayload _$AgoraPayloadFromJson(Map json) => AgoraPayload( - channel: json['channel'] as String, - ); - -HMSPayload _$HMSPayloadFromJson(Map json) => HMSPayload( - roomId: json['room_id'] as String, - roomName: json['room_name'] as String, - ); diff --git a/packages/stream_chat/lib/src/core/models/message.dart b/packages/stream_chat/lib/src/core/models/message.dart index 93847c11af..de5143b242 100644 --- a/packages/stream_chat/lib/src/core/models/message.dart +++ b/packages/stream_chat/lib/src/core/models/message.dart @@ -34,11 +34,7 @@ class Message extends Equatable implements ComparableFieldProvider { this.mentionedUsers = const [], this.silent = false, this.shadowed = false, - @Deprecated("Use 'reactionGroups' instead") - Map? reactionCounts, - @Deprecated("Use 'reactionGroups' instead") - Map? reactionScores, - Map? reactionGroups, + this.reactionGroups, this.latestReactions, this.ownReactions, this.parentId, @@ -75,11 +71,6 @@ class Message extends Equatable implements ComparableFieldProvider { remoteCreatedAt = createdAt, remoteUpdatedAt = updatedAt, remoteDeletedAt = deletedAt, - reactionGroups = _maybeGetReactionGroups( - reactionGroups: reactionGroups, - reactionCounts: reactionCounts, - reactionScores: reactionScores, - ), _quotedMessageId = quotedMessageId, _pollId = pollId; @@ -127,45 +118,40 @@ class Message extends Equatable implements ComparableFieldProvider { @JsonKey(toJson: User.toIds) final List mentionedUsers; - /// A map describing the count of number of every reaction. - @JsonKey(includeToJson: false) - @Deprecated("Use 'reactionGroups' instead") - Map? get reactionCounts { - return reactionGroups?.map((type, it) => MapEntry(type, it.count)); - } - - /// A map describing the count of score of every reaction. - @JsonKey(includeToJson: false) - @Deprecated("Use 'reactionGroups' instead") - Map? get reactionScores { - return reactionGroups?.map((type, it) => MapEntry(type, it.sumScores)); - } - - static Map? _maybeGetReactionGroups({ - Map? reactionGroups, - Map? reactionCounts, - Map? reactionScores, - }) { + static Object? _reactionGroupsReadValue( + Map json, + String key, + ) { + final reactionGroups = json[key] as Map?; if (reactionGroups != null) return reactionGroups; + + final reactionCounts = json['reaction_counts'] as Map?; + final reactionScores = json['reaction_scores'] as Map?; if (reactionCounts == null && reactionScores == null) return null; final reactionTypes = {...?reactionCounts?.keys, ...?reactionScores?.keys}; if (reactionTypes.isEmpty) return null; - final groups = {}; + final groups = {}; for (final type in reactionTypes) { final count = reactionCounts?[type] ?? 0; final sumScores = reactionScores?[type] ?? 0; if (count == 0 || sumScores == 0) continue; - groups[type] = ReactionGroup(count: count, sumScores: sumScores); + final now = DateTime.timestamp(); + groups[type] = { + 'count': count, + 'sum_scores': sumScores, + 'first_reaction_at': now.toIso8601String(), + 'last_reaction_at': now.toIso8601String(), + }; } return groups; } /// A map of reaction types and their corresponding reaction groups. - @JsonKey(includeToJson: false) + @JsonKey(includeToJson: false, readValue: _reactionGroupsReadValue) final Map? reactionGroups; /// The latest reactions to the message created by any user. @@ -389,10 +375,6 @@ class Message extends Equatable implements ComparableFieldProvider { List? mentionedUsers, bool? silent, bool? shadowed, - @Deprecated("Use 'reactionGroups' instead") - Map? reactionCounts, - @Deprecated("Use 'reactionGroups' instead") - Map? reactionScores, Map? reactionGroups, List? latestReactions, List? ownReactions, @@ -464,12 +446,7 @@ class Message extends Equatable implements ComparableFieldProvider { mentionedUsers: mentionedUsers ?? this.mentionedUsers, silent: silent ?? this.silent, shadowed: shadowed ?? this.shadowed, - reactionGroups: _maybeGetReactionGroups( - reactionGroups: reactionGroups, - reactionCounts: reactionCounts, - reactionScores: reactionScores, - ) ?? - this.reactionGroups, + reactionGroups: reactionGroups ?? this.reactionGroups, latestReactions: latestReactions ?? this.latestReactions, ownReactions: ownReactions ?? this.ownReactions, parentId: parentId ?? this.parentId, diff --git a/packages/stream_chat/lib/src/core/models/message.g.dart b/packages/stream_chat/lib/src/core/models/message.g.dart index cc90809bd9..2d2165b60a 100644 --- a/packages/stream_chat/lib/src/core/models/message.g.dart +++ b/packages/stream_chat/lib/src/core/models/message.g.dart @@ -22,13 +22,9 @@ Message _$MessageFromJson(Map json) => Message( const [], silent: json['silent'] as bool? ?? false, shadowed: json['shadowed'] as bool? ?? false, - reactionCounts: (json['reaction_counts'] as Map?)?.map( - (k, e) => MapEntry(k, (e as num).toInt()), - ), - reactionScores: (json['reaction_scores'] as Map?)?.map( - (k, e) => MapEntry(k, (e as num).toInt()), - ), - reactionGroups: (json['reaction_groups'] as Map?)?.map( + reactionGroups: (Message._reactionGroupsReadValue(json, 'reaction_groups') + as Map?) + ?.map( (k, e) => MapEntry(k, ReactionGroup.fromJson(e as Map)), ), diff --git a/packages/stream_chat/lib/src/permission_type.dart b/packages/stream_chat/lib/src/permission_type.dart deleted file mode 100644 index dcf0c5ef49..0000000000 --- a/packages/stream_chat/lib/src/permission_type.dart +++ /dev/null @@ -1,103 +0,0 @@ -/// Describes capabilities of a user vis-a-vis a channel -@Deprecated("Use 'ChannelCapability' instead") -class PermissionType { - /// Capability required to send a message in the channel - /// Channel is not frozen (or user has UseFrozenChannel permission) - /// and user has CreateMessage permission. - static const String sendMessage = 'send-message'; - - /// Capability required to receive connect events in the channel - static const String connectEvents = 'connect-events'; - - /// Capability required to send a message - /// Reactions are enabled for the channel, channel is not frozen - /// (or user has UseFrozenChannel permission) and user has - /// CreateReaction permission - static const String sendReaction = 'send-reaction'; - - /// Capability required to send links in a channel - /// send-message + user has AddLinks permission - static const String sendLinks = 'send-links'; - - /// Capability required to send thread reply - /// send-message + channel has replies enabled - static const String sendReply = 'send-reply'; - - /// Capability to freeze a channel - /// User has UpdateChannelFrozen permission. - /// The name implies freezing, - /// but unfreezing is also allowed when this capability is present - static const String freezeChannel = 'freeze-channel'; - - /// User has UpdateChannelCooldown permission. - /// Allows to enable/disable slow mode in the channel - static const String setChannelCooldown = 'set-channel-cooldown'; - - /// User has the ability to skip slow mode when it's active. - static const String skipSlowMode = 'skip-slow-mode'; - - /// User has RemoveOwnChannelMembership or UpdateChannelMembers permission - static const String leaveChannel = 'leave-channel'; - - /// User can mute channel - static const String muteChannel = 'mute-channel'; - - /// Ability to receive read events - static const String readEvents = 'read-events'; - - /// Capability required to pin a message in a channel - /// Corresponds to PinMessage permission - static const String pinMessage = 'pin-message'; - - /// Capability required to quote a message in a channel - static const String quoteMessage = 'quote-message'; - - /// Capability required to flag a message in a channel - static const String flagMessage = 'flag-message'; - - /// User has ability to delete any message in the channel - /// User has DeleteMessage permission - /// which applies to any message in the channel - static const String deleteAnyMessage = 'delete-any-message'; - - /// User has ability to delete their own message in the channel - /// User has DeleteMessage permission which applies only to owned messages - static const String deleteOwnMessage = 'delete-own-message'; - - /// User has ability to update/edit any message in the channel - /// User has UpdateMessage permission which - /// applies to any message in the channel - static const String updateAnyMessage = 'update-any-message'; - - /// User has ability to update/edit their own message in the channel - /// User has UpdateMessage permission which applies only to owned messages - static const String updateOwnMessage = 'update-own-message'; - - /// User can search for message in a channel - /// Search feature is enabled (it will also have - /// permission check in the future) - static const String searchMessages = 'search-messages'; - - /// Capability required to send typing events in a channel - /// (Typing events are enabled) - static const String sendTypingEvents = 'send-typing-events'; - - /// Capability required to upload a file in a channel - /// Uploads are enabled and user has UploadAttachment - static const String uploadFile = 'upload-file'; - - /// Capability required to delete channel - /// User has DeleteChannel permission - static const String deleteChannel = 'delete-channel'; - - /// Capability required update/edit channel info - /// User has UpdateChannel permission - static const String updateChannel = 'update-channel'; - - /// Capability required to update/edit channel members - /// Channel is not distinct and user has UpdateChannelMembers permission - static const String updateChannelMembers = 'update-channel-members'; - - /// Capability required to send a poll in a channel. - static const String sendPoll = 'send-poll'; -} diff --git a/packages/stream_chat/lib/stream_chat.dart b/packages/stream_chat/lib/stream_chat.dart index ea60b484b8..76bcdc056b 100644 --- a/packages/stream_chat/lib/stream_chat.dart +++ b/packages/stream_chat/lib/stream_chat.dart @@ -64,6 +64,5 @@ export 'src/core/platform_detector/platform_detector.dart'; export 'src/core/util/extension.dart'; export 'src/db/chat_persistence_client.dart'; export 'src/event_type.dart'; -export 'src/permission_type.dart'; export 'src/system_environment.dart'; export 'src/ws/connection_status.dart'; diff --git a/packages/stream_chat/test/fixtures/message.json b/packages/stream_chat/test/fixtures/message.json index 6b99f2fbc1..8e52ea2390 100644 --- a/packages/stream_chat/test/fixtures/message.json +++ b/packages/stream_chat/test/fixtures/message.json @@ -48,11 +48,13 @@ } ], "own_reactions": [], - "reaction_counts": { - "love": 1 - }, - "reaction_scores": { - "love": 1 + "reaction_groups": { + "love": { + "count": 1, + "sum_scores": 1, + "first_reaction_at": "2020-01-28T22:17:31.107978Z", + "last_reaction_at": "2020-01-28T22:17:31.107978Z" + } }, "pinned": false, "pinned_at": null, diff --git a/packages/stream_chat/test/src/core/api/call_api_test.dart b/packages/stream_chat/test/src/core/api/call_api_test.dart deleted file mode 100644 index 60c0c24adb..0000000000 --- a/packages/stream_chat/test/src/core/api/call_api_test.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:dio/dio.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:stream_chat/src/core/api/call_api.dart'; -import 'package:test/test.dart'; - -import '../../mocks.dart'; - -@Deprecated('Will be removed in the next major version') -void main() { - Response successResponse(String path, {Object? data}) => Response( - data: data, - requestOptions: RequestOptions(path: path), - statusCode: 200, - ); - - late final client = MockHttpClient(); - late CallApi callApi; - - setUp(() { - callApi = CallApi(client); - }); - - test('getCallToken should work', () async { - const callId = 'test-call-id'; - const path = '/calls/$callId'; - - when(() => client.post(path, data: {})).thenAnswer( - (_) async => successResponse(path, data: {})); - - final res = await callApi.getCallToken(callId); - - expect(res, isNotNull); - - verify(() => client.post(path, data: any(named: 'data'))).called(1); - verifyNoMoreInteractions(client); - }); - - test('createCall should work', () async { - const callId = 'test-call-id'; - const callType = 'test-call-type'; - const channelType = 'test-channel-type'; - const channelId = 'test-channel-id'; - const path = '/channels/$channelType/$channelId/call'; - - when(() => client.post( - path, - data: { - 'id': callId, - 'type': callType, - }, - )) - .thenAnswer( - (_) async => successResponse(path, data: {})); - - final res = await callApi.createCall( - callId: callId, - callType: callType, - channelType: channelType, - channelId: channelId, - ); - - expect(res, isNotNull); - - verify(() => client.post(path, data: any(named: 'data'))).called(1); - verifyNoMoreInteractions(client); - }); -} diff --git a/packages/stream_chat/test/src/core/api/responses_test.dart b/packages/stream_chat/test/src/core/api/responses_test.dart index b1e1e9efcd..ae4bad09d9 100644 --- a/packages/stream_chat/test/src/core/api/responses_test.dart +++ b/packages/stream_chat/test/src/core/api/responses_test.dart @@ -1,6 +1,5 @@ import 'dart:convert'; -import 'package:stream_chat/src/core/models/call_payload.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:test/test.dart'; @@ -4364,37 +4363,6 @@ void main() { expect(response.message, isA()); }); - test('CallTokenPayload', () { - const jsonExample = ''' - {"duration": "3ms", - "agora_app_id":"test", - "agora_uid": 12, - "token": "token"} - '''; - - // ignore: deprecated_member_use_from_same_package - final response = CallTokenPayload.fromJson(json.decode(jsonExample)); - expect(response.agoraAppId, isA()); - expect(response.agoraUid, isA()); - expect(response.token, isA()); - }, skip: 'Deprecated, Will be removed in the next major version'); - - test('CreateCallPayload', () { - const jsonExample = ''' - {"call": - {"id":"test", - "provider": "test", - "agora": {"channel":"test"}, - "hms":{"room_id":"test", "room_name":"test"} - }} - '''; - - // ignore: deprecated_member_use_from_same_package - final response = CreateCallPayload.fromJson(json.decode(jsonExample)); - // ignore: deprecated_member_use_from_same_package - expect(response.call, isA()); - }, skip: 'Deprecated, Will be removed in the next major version'); - test('UserBlockResponse', () { const jsonExample = ''' { diff --git a/packages/stream_chat/test/src/core/api/sort_order_test.dart b/packages/stream_chat/test/src/core/api/sort_order_test.dart index ac1200621d..6dc5d91473 100644 --- a/packages/stream_chat/test/src/core/api/sort_order_test.dart +++ b/packages/stream_chat/test/src/core/api/sort_order_test.dart @@ -64,13 +64,6 @@ void main() { expect(option.field, 'age'); expect(option.direction, SortOption.DESC); }); - - test('should correctly deserialize from JSON', () { - final json = {'field': 'age', 'direction': 1}; - final option = SortOption.fromJson(json); - expect(option.field, 'age'); - expect(option.direction, SortOption.ASC); - }); }); group('SortOption single field', () { diff --git a/packages/stream_chat/test/src/core/models/call_payload_test.dart b/packages/stream_chat/test/src/core/models/call_payload_test.dart deleted file mode 100644 index c369122e91..0000000000 --- a/packages/stream_chat/test/src/core/models/call_payload_test.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'dart:convert'; - -import 'package:stream_chat/src/core/models/call_payload.dart'; -import 'package:test/test.dart'; - -@Deprecated('Will be removed in the next major version') -void main() { - test('CallPayload', () { - const jsonExample = ''' - {"id":"test", - "provider": "test", - "agora": {"channel":"test"}, - "hms":{"room_id":"test", "room_name":"test"} - } - '''; - final response = CallPayload.fromJson(json.decode(jsonExample)); - expect(response.agora, isA()); - expect(response.hms, isA()); - expect(response.id, isA()); - expect(response.provider, isA()); - }); - - test('AgoraPayload', () { - const jsonExample = ''' - {"channel":"test"} - '''; - final response = AgoraPayload.fromJson(json.decode(jsonExample)); - expect(response.channel, isA()); - }); - - test('HMSPayload', () { - const jsonExample = ''' - {"room_id":"test", "room_name":"test"} - '''; - final response = HMSPayload.fromJson(json.decode(jsonExample)); - expect(response.roomId, isA()); - expect(response.roomName, isA()); - }); -} diff --git a/packages/stream_chat/test/src/core/models/message_test.dart b/packages/stream_chat/test/src/core/models/message_test.dart index 8365d7fdce..0e27a2d561 100644 --- a/packages/stream_chat/test/src/core/models/message_test.dart +++ b/packages/stream_chat/test/src/core/models/message_test.dart @@ -23,11 +23,9 @@ void main() { expect(message.attachments, isA>()); expect(message.latestReactions, isA>()); expect(message.ownReactions, isA>()); - // ignore: deprecated_member_use_from_same_package - expect(message.reactionCounts, {'love': 1}); - // ignore: deprecated_member_use_from_same_package - expect(message.reactionScores, {'love': 1}); expect(message.reactionGroups, isA>()); + expect(message.reactionGroups?['love']?.count, 1); + expect(message.reactionGroups?['love']?.sumScores, 1); expect(message.createdAt, DateTime.parse('2020-01-28T22:17:31.107978Z')); expect(message.updatedAt, DateTime.parse('2020-01-28T22:17:31.130506Z')); expect(message.mentionedUsers, isA>()); @@ -289,13 +287,23 @@ void main() { }); test( - 'is derived from reactionCounts and reactionScores if not provided directly in constructor', + 'uses reactionGroups when provided directly in constructor', () { final message = Message( - // ignore: deprecated_member_use_from_same_package - reactionCounts: const {'like': 1, 'love': 2}, - // ignore: deprecated_member_use_from_same_package - reactionScores: const {'like': 1, 'love': 5}, + reactionGroups: { + 'like': ReactionGroup( + count: 1, + sumScores: 1, + firstReactionAt: DateTime.now(), + lastReactionAt: DateTime.now(), + ), + 'love': ReactionGroup( + count: 2, + sumScores: 5, + firstReactionAt: DateTime.now(), + lastReactionAt: DateTime.now(), + ), + }, ); expect(message.reactionGroups, isNotNull); diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index c4a0e2d839..33a1d1a186 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -2,6 +2,12 @@ 🛑️ Breaking +- **Deprecated API Cleanup**: Removed all deprecated classes, methods, and properties for the v10 major release: + - **Removed Classes**: `DmCheckbox` (use `DmCheckboxListTile`), `StreamIconThemeSvgIcon` (use `StreamSvgIcon`), `StreamVoiceRecordingThemeData` (use `StreamVoiceRecordingAttachmentThemeData`), `StreamVoiceRecordingLoading`, `StreamVoiceRecordingSlider` (use `StreamAudioWaveformSlider`), `StreamVoiceRecordingPlayer` (use `StreamVoiceRecordingAttachment`), `StreamVoiceRecordingListPlayer` (use `StreamVoiceRecordingAttachmentPlaylist`) + - **Removed Properties**: `reactionIcons` and `voiceRecordingTheme` from `StreamChatTheme`, `isThreadConversation` from `FloatingDateDivider`, `idleSendButton` and `activeSendButton` from `StreamMessageInput`, `isCommandEnabled` and `isEditEnabled` from `StreamMessageSendButton`, `assetName`, `width`, and `height` from `StreamSvgIcon` + - **Removed Constructor Parameters**: `useNativeAttachmentPickerOnMobile` from various components, `allowCompression` from `StreamAttachmentHandler.pickFile()` and `StreamFilePicker` (use `compressionQuality` instead), `cid` from `StreamUnreadIndicator` constructor + - **Removed Methods**: `lastUnreadMessage()` from message list extensions (use `StreamChannel.getFirstUnreadMessage`), `loadBuffer()` and `_loadAsync()` from `StreamVideoThumbnailImage` + - **StreamSvgIcon Refactoring**: Removed 80+ deprecated factory constructors. Use `StreamSvgIcon(icon: StreamSvgIcons.iconName)` instead of factory constructors like `StreamSvgIcon.add()` - `PollMessage` widget has been removed and replaced with `PollAttachment` for better integration with the attachment system. Polls can now be customized through `PollAttachmentBuilder` or by creating custom poll attachment widgets via the attachment builder system. - `AttachmentPickerType` enum has been replaced with a sealed class to support extensible custom types like contact and location pickers. Use built-in types like `AttachmentPickerType.images` or define your own via `CustomAttachmentPickerType`. - `StreamAttachmentPickerOption` has been replaced with two sealed classes to support layout-specific picker options: `SystemAttachmentPickerOption` for system pickers (e.g. camera, files) and `TabbedAttachmentPickerOption` for tabbed pickers (e.g. gallery, polls, location). diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart index 64382b2d28..24c1df2a5e 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/builder/attachment_widget_builder.dart @@ -11,7 +11,6 @@ part 'mixed_attachment_builder.dart'; part 'url_attachment_builder.dart'; part 'video_attachment_builder.dart'; part 'voice_recording_attachment_playlist_builder.dart'; -part 'voice_recording_attachment_builder/voice_recording_attachment_builder.dart'; part 'poll_attachment_builder.dart'; /// {@template streamAttachmentWidgetTapCallback} diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player.dart deleted file mode 100644 index d13e2ec620..0000000000 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player.dart +++ /dev/null @@ -1,139 +0,0 @@ -// coverage:ignore-file - -import 'dart:async'; - -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:just_audio/just_audio.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template StreamVoiceRecordingListPlayer} -/// Display many audios and displays a list of AudioPlayerMessage. -/// {@endtemplate} -@Deprecated('Use StreamVoiceRecordingAttachmentPlaylist instead') -class StreamVoiceRecordingListPlayer extends StatefulWidget { - /// {@macro StreamVoiceRecordingListPlayer} - const StreamVoiceRecordingListPlayer({ - super.key, - required this.playList, - this.attachmentBorderRadiusGeometry, - this.constraints, - }); - - /// List of audio attachments. - final List playList; - - /// The border radius of each audio. - final BorderRadiusGeometry? attachmentBorderRadiusGeometry; - - /// Constraints of audio attachments - final BoxConstraints? constraints; - - @override - State createState() => - _StreamVoiceRecordingListPlayerState(); -} - -@Deprecated("Use 'StreamVoiceRecordingAttachmentPlaylist' instead") -class _StreamVoiceRecordingListPlayerState - extends State { - final _player = AudioPlayer(); - late StreamSubscription _playerStateChangedSubscription; - - Widget _createAudioPlayer(int index, PlayListItem item) { - final url = item.assetUrl; - Widget child; - - if (url == null) { - child = const StreamVoiceRecordingLoading(); - } else { - child = StreamVoiceRecordingPlayer( - player: _player, - duration: item.duration, - waveBars: item.waveForm, - index: index, - ); - } - - final theme = - StreamChatTheme.of(context).voiceRecordingTheme.listPlayerTheme; - - return Container( - margin: theme.margin, - constraints: widget.constraints, - decoration: BoxDecoration( - color: theme.backgroundColor, - border: Border.all( - color: theme.borderColor!, - ), - borderRadius: - widget.attachmentBorderRadiusGeometry ?? theme.borderRadius, - ), - child: child, - ); - } - - void _playerStateListener(PlayerState state) async { - if (state.processingState == ProcessingState.completed) { - await _player.stop(); - await _player.seek(Duration.zero, index: 0); - } - } - - @override - void initState() { - super.initState(); - - _playerStateChangedSubscription = - _player.playerStateStream.listen(_playerStateListener); - } - - @override - void dispose() { - super.dispose(); - - _playerStateChangedSubscription.cancel(); - _player.dispose(); - } - - @override - Widget build(BuildContext context) { - final playList = widget.playList - .where((attachment) => attachment.assetUrl != null) - .map((attachment) => AudioSource.uri(Uri.parse(attachment.assetUrl!))) - .toList(); - - final audioSource = ConcatenatingAudioSource(children: playList); - - _player - ..setShuffleModeEnabled(false) - ..setLoopMode(LoopMode.off) - ..setAudioSource(audioSource, preload: false); - - return Column( - children: widget.playList.mapIndexed(_createAudioPlayer).toList(), - ); - } -} - -/// {@template PlayListItem} -/// Represents an audio attachment meta data. -/// {@endtemplate} -@Deprecated("Use 'PlaylistTrack' instead") -class PlayListItem { - /// {@macro PlayListItem} - const PlayListItem({ - this.assetUrl, - required this.duration, - required this.waveForm, - }); - - /// The url of the audio. - final String? assetUrl; - - /// The duration of the audio. - final Duration duration; - - /// The wave form of the audio. - final List waveForm; -} diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading.dart deleted file mode 100644 index 7f26f1b6ff..0000000000 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading.dart +++ /dev/null @@ -1,33 +0,0 @@ -// coverage:ignore-file - -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template StreamVoiceRecordingLoading} -/// Loading widget for audio message. Use this when the url from the audio -/// message is still not available. One use situation in when the audio is -/// still being uploaded. -/// {@endtemplate} -@Deprecated('Will be removed in the next major version') -class StreamVoiceRecordingLoading extends StatelessWidget { - /// {@macro StreamVoiceRecordingLoading} - const StreamVoiceRecordingLoading({super.key}); - - @override - Widget build(BuildContext context) { - final theme = StreamChatTheme.of(context).voiceRecordingTheme.loadingTheme; - - return Padding( - padding: theme.padding!, - child: SizedBox( - height: theme.size!.height, - width: theme.size!.width, - child: CircularProgressIndicator( - // ignore: unnecessary_null_checks - strokeWidth: theme.strokeWidth!, - color: theme.color, - ), - ), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart deleted file mode 100644 index 0136fd3f81..0000000000 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart +++ /dev/null @@ -1,320 +0,0 @@ -// coverage:ignore-file - -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:just_audio/just_audio.dart'; -import 'package:rxdart/rxdart.dart'; -import 'package:stream_chat_flutter/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_slider.dart'; -import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template StreamVoiceRecordingPlayer} -/// Embedded player for audio messages. It displays the data for the audio -/// message and allow the user to interact with the player providing buttons -/// to play/pause, seek the audio and change the speed of reproduction. -/// -/// When waveBars are not provided they are shown as 0 bars. -/// {@endtemplate} -@Deprecated("Use 'StreamVoiceRecordingAttachment' instead") -class StreamVoiceRecordingPlayer extends StatefulWidget { - /// {@macro StreamVoiceRecordingPlayer} - const StreamVoiceRecordingPlayer({ - super.key, - required this.player, - required this.duration, - this.waveBars, - this.index = 0, - this.fileSize, - this.actionButton, - }); - - /// The player of the audio. - final AudioPlayer player; - - /// The wave bars of the recorded audio from 0 to 1. When not provided - /// this Widget shows then as small dots. - final List? waveBars; - - /// The duration of the audio. - final Duration duration; - - /// The index of the audio inside the play list. If not provided, this is - /// assumed to be zero. - final int index; - - /// The file size in bits. - final int? fileSize; - - /// An action button to be used. - final Widget? actionButton; - - @override - _StreamVoiceRecordingPlayerState createState() => - _StreamVoiceRecordingPlayerState(); -} - -@Deprecated("Use 'StreamVoiceRecordingAttachment' instead") -class _StreamVoiceRecordingPlayerState - extends State { - var _seeking = false; - - @override - void dispose() { - super.dispose(); - - widget.player.dispose(); - } - - @override - Widget build(BuildContext context) { - if (widget.duration != Duration.zero) { - return _content(widget.duration); - } else { - return StreamBuilder( - stream: widget.player.durationStream, - builder: (context, snapshot) { - if (snapshot.hasData) { - return _content(snapshot.data!); - } else if (snapshot.hasError) { - return const Center(child: Text('Error!!')); - } else { - return const StreamVoiceRecordingLoading(); - } - }, - ); - } - } - - Widget _content(Duration totalDuration) { - return Container( - padding: const EdgeInsets.all(8), - height: 60, - child: Row( - children: [ - SizedBox( - width: 36, - height: 36, - child: _controlButton(), - ), - Padding( - padding: const EdgeInsets.only(left: 8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - _timer(totalDuration), - _fileSizeWidget(widget.fileSize), - ], - ), - ), - _audioWaveSlider(totalDuration), - _speedAndActionButton(), - ], - ), - ); - } - - Widget _controlButton() { - final theme = StreamChatTheme.of(context).voiceRecordingTheme.playerTheme; - - return StreamBuilder( - initialData: false, - stream: _playingThisStream(), - builder: (context, snapshot) { - final playingThis = snapshot.data == true; - - final icon = playingThis ? theme.pauseIcon : theme.playIcon; - - final processingState = widget.player.playerStateStream - .map((event) => event.processingState); - - return StreamBuilder( - stream: processingState, - initialData: ProcessingState.idle, - builder: (context, snapshot) { - final state = snapshot.data ?? ProcessingState.idle; - if (state == ProcessingState.ready || - state == ProcessingState.idle || - !playingThis) { - return ElevatedButton( - style: ElevatedButton.styleFrom( - elevation: theme.buttonElevation, - padding: theme.buttonPadding, - backgroundColor: theme.buttonBackgroundColor, - shape: theme.buttonShape, - ), - child: Icon(icon, color: theme.iconColor), - onPressed: () { - if (playingThis) { - _pause(); - } else { - _play(); - } - }, - ); - } else { - return const CircularProgressIndicator(strokeWidth: 3); - } - }, - ); - }, - ); - } - - Widget _speedAndActionButton() { - final theme = StreamChatTheme.of(context).voiceRecordingTheme.playerTheme; - - final speedStream = _playingThisStream().flatMap((showSpeed) => - widget.player.speedStream.map((speed) => showSpeed ? speed : -1.0)); - - return StreamBuilder( - initialData: -1, - stream: speedStream, - builder: (context, snapshot) { - if (snapshot.hasData && snapshot.data! > 0) { - final speed = snapshot.data!; - return SizedBox( - width: theme.speedButtonSize!.width, - height: theme.speedButtonSize!.height, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - elevation: theme.speedButtonElevation, - backgroundColor: theme.speedButtonBackgroundColor, - padding: theme.speedButtonPadding, - shape: theme.speedButtonShape, - ), - child: Text( - '${speed}x', - style: theme.speedButtonTextStyle, - ), - onPressed: () { - setState(() { - if (speed == 2) { - widget.player.setSpeed(1); - } else { - widget.player.setSpeed(speed + 0.5); - } - }); - }, - ), - ); - } else { - if (widget.actionButton != null) { - return widget.actionButton!; - } else { - return SizedBox( - width: theme.speedButtonSize!.width, - height: theme.speedButtonSize!.height, - child: theme.fileTypeIcon, - ); - } - } - }, - ); - } - - Widget _fileSizeWidget(int? fileSize) { - final theme = StreamChatTheme.of(context).voiceRecordingTheme.playerTheme; - - if (fileSize != null) { - return Text( - fileSize.toHumanReadableSize(), - style: theme.fileSizeTextStyle, - ); - } else { - return const Empty(); - } - } - - Widget _timer(Duration totalDuration) { - final theme = StreamChatTheme.of(context).voiceRecordingTheme.playerTheme; - - return StreamBuilder( - stream: widget.player.positionStream, - builder: (context, snapshot) { - if (snapshot.hasData && - (widget.player.currentIndex == widget.index && - (widget.player.playing || - snapshot.data!.inMilliseconds > 0 || - _seeking))) { - return Text( - snapshot.data!.toMinutesAndSeconds(), - style: theme.timerTextStyle, - ); - } else { - return Text( - totalDuration.toMinutesAndSeconds(), - style: theme.timerTextStyle, - ); - } - }, - ); - } - - Widget _audioWaveSlider(Duration totalDuration) { - final positionStream = widget.player.currentIndexStream.flatMap( - (index) => widget.player.positionStream.map((duration) => _sliderValue( - duration, - totalDuration, - index, - )), - ); - - return Expanded( - child: StreamVoiceRecordingSlider( - waves: widget.waveBars ?? List.filled(50, 0), - progressStream: positionStream, - onChangeStart: (val) { - setState(() { - _seeking = true; - }); - }, - onChanged: (val) { - widget.player.pause(); - widget.player.seek( - totalDuration * val, - index: widget.index, - ); - }, - onChangeEnd: () { - setState(() { - _seeking = false; - }); - }, - ), - ); - } - - double _sliderValue( - Duration duration, - Duration totalDuration, - int? currentIndex, - ) { - if (widget.index != currentIndex) { - return 0; - } else { - return min(duration.inMicroseconds / totalDuration.inMicroseconds, 1); - } - } - - Stream _playingThisStream() { - return widget.player.playingStream.flatMap((playing) { - return widget.player.currentIndexStream.map( - (index) => playing && index == widget.index, - ); - }); - } - - Future _play() async { - if (widget.index != widget.player.currentIndex) { - widget.player.seek(Duration.zero, index: widget.index); - } - - widget.player.play(); - } - - Future _pause() { - return widget.player.pause(); - } -} diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_slider.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_slider.dart deleted file mode 100644 index a3ed7ddbbb..0000000000 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_slider.dart +++ /dev/null @@ -1,239 +0,0 @@ -// coverage:ignore-file - -import 'dart:math'; - -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template StreamVoiceRecordingSlider} -/// A Widget that draws the audio wave bars for an audio inside a Slider. -/// This Widget is indeed to be used to control the position of an audio message -/// and to get feedback of the position. -/// {@endtemplate} -@Deprecated("Use 'StreamAudioWaveformSlider' instead") -class StreamVoiceRecordingSlider extends StatefulWidget { - /// {@macro StreamVoiceRecordingSlider} - const StreamVoiceRecordingSlider({ - super.key, - required this.waves, - required this.progressStream, - this.onChangeStart, - this.onChanged, - this.onChangeEnd, - this.customSliderButton, - this.customSliderButtonWidth, - }); - - /// The audio bars from 0.0 to 1.0. - final List waves; - - /// The progress of the audio. - final Stream progressStream; - - /// Callback called when Slider drag starts. - final Function(double)? onChangeStart; - - /// Callback called when Slider drag updates. - final Function(double)? onChanged; - - /// Callback called when Slider drag ends. - final Function()? onChangeEnd; - - /// A custom Slider button. Use this to substitute the default rounded - /// rectangle. - final Widget? customSliderButton; - - /// The width of the customSliderButton. This should match the width of the - /// provided Widget. - final double? customSliderButtonWidth; - - @override - _StreamVoiceRecordingSliderState createState() => - _StreamVoiceRecordingSliderState(); -} - -@Deprecated("Use 'StreamAudioWaveformSlider' instead") -class _StreamVoiceRecordingSliderState - extends State { - var _dragging = false; - final _initialWidth = 7.0; - final _finalWidth = 14.0; - final _initialHeight = 30.0; - final _finalHeight = 35.0; - - Duration get animationDuration => - _dragging ? Duration.zero : const Duration(milliseconds: 300); - - double get _currentWidth { - if (widget.customSliderButtonWidth != null) { - return widget.customSliderButtonWidth!; - } else { - return _dragging ? _finalWidth : _initialWidth; - } - } - - double get _currentHeight => _dragging ? _finalHeight : _initialHeight; - - double _progressToWidth( - BoxConstraints constraints, double progress, double horizontalPadding) { - final availableWidth = constraints.maxWidth - horizontalPadding * 2; - - return availableWidth * progress - _currentWidth / 2 + horizontalPadding; - } - - @override - Widget build(BuildContext context) { - final theme = StreamChatTheme.of(context).voiceRecordingTheme.sliderTheme; - - return StreamBuilder( - initialData: 0, - stream: widget.progressStream, - builder: (context, snapshot) { - final progress = snapshot.data ?? 0; - - final sliderButton = widget.customSliderButton ?? - Container( - width: _currentWidth, - height: _currentHeight, - decoration: BoxDecoration( - color: theme.buttonColor, - boxShadow: [ - theme.buttonShadow!, - ], - border: Border.all( - color: theme.buttonBorderColor!, - width: theme.buttonBorderWidth!, - ), - borderRadius: theme.buttonBorderRadius, - ), - ); - - return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return Stack( - alignment: Alignment.center, - children: [ - CustomPaint( - size: Size(constraints.maxWidth, constraints.maxHeight), - painter: _AudioBarsPainter( - bars: widget.waves, - spacingRatio: theme.spacingRatio, - barHeightRatio: theme.waveHeightRatio, - colorLeft: theme.waveColorPlayed!, - colorRight: theme.waveColorUnplayed!, - progressPercentage: progress, - padding: theme.horizontalPadding, - ), - ), - AnimatedPositioned( - duration: animationDuration, - left: _progressToWidth( - constraints, progress, theme.horizontalPadding), - curve: const ElasticOutCurve(1.05), - child: sliderButton, - ), - GestureDetector( - onHorizontalDragStart: (details) { - widget.onChangeStart - ?.call(details.localPosition.dx / constraints.maxWidth); - - setState(() { - _dragging = true; - }); - }, - onHorizontalDragEnd: (details) { - widget.onChangeEnd?.call(); - - setState(() { - _dragging = false; - }); - }, - onHorizontalDragUpdate: (details) { - widget.onChanged?.call( - min( - max(details.localPosition.dx / constraints.maxWidth, 0), - 1, - ), - ); - }, - ), - ], - ); - }, - ); - }, - ); - } -} - -class _AudioBarsPainter extends CustomPainter { - _AudioBarsPainter({ - required this.bars, - required this.progressPercentage, - this.colorLeft = Colors.blueAccent, - this.colorRight = Colors.grey, - this.spacingRatio = 0.01, - this.barHeightRatio = 1, - this.padding = 20, - }); - - final List bars; - final double progressPercentage; - final Color colorRight; - final Color colorLeft; - final double spacingRatio; - final double barHeightRatio; - final double padding; - - /// barWidth should include spacing, not only the width of the bar. - /// progressX should be the middle of the moving button of the slider, not - /// initial X position. - Color _barColor(double buttonCenter, double progressX) { - return (progressX > buttonCenter) ? colorLeft : colorRight; - } - - double _barHeight(double barValue, totalHeight) { - return max(barValue * totalHeight * barHeightRatio, 2); - } - - double _progressToWidth(double totalWidth, double progress) { - final availableWidth = totalWidth; - - return availableWidth * progress + padding; - } - - @override - void paint(Canvas canvas, Size size) { - final totalWidth = size.width - padding * 2; - - final spacingWidth = totalWidth * spacingRatio; - final totalBarWidth = totalWidth - spacingWidth * (bars.length - 1); - final barWidth = totalBarWidth / bars.length; - final barY = size.height / 2; - - bars.forEachIndexed((i, barValue) { - final barHeight = _barHeight(barValue, size.height); - final barX = i * (barWidth + spacingWidth) + barWidth / 2 + padding; - - final rect = RRect.fromRectAndRadius( - Rect.fromCenter( - center: Offset(barX, barY), - width: barWidth, - height: barHeight, - ), - const Radius.circular(50), - ); - - final paint = Paint() - ..color = _barColor( - barX + barWidth / 2, - _progressToWidth(totalWidth, progressPercentage), - ); - canvas.drawRRect(rect, paint); - }); - } - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) => true; -} diff --git a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder.dart b/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder.dart deleted file mode 100644 index 412b653cc0..0000000000 --- a/packages/stream_chat_flutter/lib/src/attachment/builder/voice_recording_attachment_builder/voice_recording_attachment_builder.dart +++ /dev/null @@ -1,35 +0,0 @@ -// coverage:ignore-file - -part of '../attachment_widget_builder.dart'; - -/// The default attachment builder for voice recordings -@Deprecated("Use 'VoiceRecordingAttachmentPlaylistBuilder' instead") -class VoiceRecordingAttachmentBuilder extends StreamAttachmentWidgetBuilder { - @override - bool canHandle(Message message, Map> attachments) { - final recordings = attachments[AttachmentType.voiceRecording]; - if (recordings != null && recordings.length == 1) return true; - - return false; - } - - @override - Widget build(BuildContext context, Message message, - Map> attachments) { - final recordings = attachments[AttachmentType.voiceRecording]!; - - return StreamVoiceRecordingListPlayer( - playList: recordings - .map( - (r) => PlayListItem( - assetUrl: r.assetUrl, - duration: r.duration, - waveForm: r.waveform, - ), - ) - .toList(), - attachmentBorderRadiusGeometry: BorderRadius.circular(16), - constraints: const BoxConstraints.tightFor(width: 400), - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_base.dart b/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_base.dart index 7879f63644..4f4605c677 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_base.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_base.dart @@ -31,7 +31,7 @@ abstract class StreamAttachmentHandlerBase { FileType type = FileType.any, List? allowedExtensions, Function(FilePickerStatus)? onFileLoading, - bool allowCompression = true, + int compressionQuality = 0, bool withData = true, bool withReadStream = false, bool lockParentWindow = true, diff --git a/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_html.dart b/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_html.dart index 0c351f0326..3a9de9dde3 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_html.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_html.dart @@ -23,8 +23,6 @@ class StreamAttachmentHandler extends StreamAttachmentHandlerBase { FileType type = FileType.any, List? allowedExtensions, Function(FilePickerStatus)? onFileLoading, - @Deprecated('Has no effect, Use compressionQuality instead.') - bool allowCompression = true, int compressionQuality = 0, bool withData = true, bool withReadStream = false, diff --git a/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_io.dart b/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_io.dart index 9d920d547f..5268922298 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_io.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/handler/stream_attachment_handler_io.dart @@ -111,8 +111,6 @@ class StreamAttachmentHandler extends StreamAttachmentHandlerBase { FileType type = FileType.any, List? allowedExtensions, Function(FilePickerStatus)? onFileLoading, - @Deprecated('Has no effect, Use compressionQuality instead.') - bool allowCompression = true, int compressionQuality = 0, bool withData = true, bool withReadStream = false, diff --git a/packages/stream_chat_flutter/lib/src/icons/stream_svg_icon.dart b/packages/stream_chat_flutter/lib/src/icons/stream_svg_icon.dart index 03138b891e..46acd43a8d 100644 --- a/packages/stream_chat_flutter/lib/src/icons/stream_svg_icon.dart +++ b/packages/stream_chat_flutter/lib/src/icons/stream_svg_icon.dart @@ -1,5 +1,3 @@ -// ignore_for_file: deprecated_member_use_from_same_package - import 'package:flutter/material.dart'; import 'package:svg_icon_widget/svg_icon_widget.dart'; @@ -18,1150 +16,12 @@ class StreamSvgIcon extends StatelessWidget { const StreamSvgIcon({ super.key, this.icon, - @Deprecated("Use 'icon' instead") this.assetName, this.color, - double? size, - @Deprecated("Use 'size' instead") this.width, - @Deprecated("Use 'size' instead") this.height, + this.size, this.textDirection, this.semanticLabel, this.applyTextScaling, - }) : assert( - size == null || (width == null && height == null), - 'Cannot provide both a size and a width or height', - ), - size = size ?? width ?? height; - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.settings({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.settings, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.down({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.down, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.up({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.up, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.attach({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.attach, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.loveReaction({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.loveReaction, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.thumbsUpReaction({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.thumbsUpReaction, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.thumbsDownReaction({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.thumbsDownReaction, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.lolReaction({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.lolReaction, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.wutReaction({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.wutReaction, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.smile({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.smile, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.mentions({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.mentions, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.record({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.record, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.camera({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.camera, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.files({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.files, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.polls({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.polls, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.send({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.send, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.pictures({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.pictures, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.left({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.left, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.user({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.user, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.userAdd({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.userAdd, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.check({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.check, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.checkAll({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.checkAll, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.checkSend({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.checkSend, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.penWrite({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.penWrite, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.contacts({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.contacts, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.close({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.close, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.search({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.search, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.right({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.right, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.mute({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.mute, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.userRemove({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.userRemove, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.lightning({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.lightning, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.emptyCircleLeft({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.emptyCircleRight, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.message({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.message, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.messageUnread({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.messageUnread, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.thread({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.threadReply, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.reply({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.reply, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.edit({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.edit, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.download({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.download, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.cloudDownload({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.cloudDownload, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.copy({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.copy, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.delete({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.delete, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.eye({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.eye, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.arrowRight({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.arrowRight, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.closeSmall({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.closeSmall, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconCurveLineLeftUp({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.reply, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconMoon({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.moon, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconShare({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.share, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconGrid({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.grid, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconSendMessage({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.sendMessage, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconMenuPoint({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.menuPoint, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconSave({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.save, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.shareArrow({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.shareArrow, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeAac({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeAudioAac, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetype7z({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeCompression7z, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeCsv({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeCodeCsv, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeDoc({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeTextDoc, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeDocx({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeTextDocx, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeGeneric({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeOtherStandard, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeHtml({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeCodeHtml, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeMd({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeCodeMd, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeOdt({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeTextOdt, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypePdf({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeOtherPdf, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypePpt({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypePresentationPpt, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypePptx({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypePresentationPptx, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeRar({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeCompressionRar, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeRtf({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeTextRtf, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeTar({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeCodeTar, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeTxt({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeTextTxt, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeXls({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeSpreadsheetXls, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeXlsx({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeSpreadsheetXlsx, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.filetypeZip({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.filetypeCompressionZip, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconGroup({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.group, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconNotification({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.notification, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconUserDelete({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.userDelete, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.error({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.error, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.circleUp({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.circleUp, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconUserSettings({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.userSettings, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.giphyIcon({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.giphy, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.imgur({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.imgur, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.volumeUp({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.volumeUp, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.flag({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.flag, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.iconFlag({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.flag, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.retry({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.retry, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.pin({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.pin, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.videoCall({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.videoCall, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.award({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.award, - color: color, - size: size, - ); - } - - /// [StreamSvgIcon] type - @Deprecated("Use regular 'StreamSvgIcon' with 'icon' instead") - factory StreamSvgIcon.reload({ - double? size, - Color? color, - }) { - return StreamSvgIcon( - icon: StreamSvgIcons.reload, - color: color, - size: size, - ); - } + }); /// The icon to display. /// @@ -1169,21 +29,6 @@ class StreamSvgIcon extends StatelessWidget { /// space of the specified [size]. final StreamSvgIconData? icon; - /// The asset to display. - /// - /// The asset can be null, in which case the widget will render as an empty - /// space of the specified [size]. - @Deprecated("Use 'icon' instead") - final String? assetName; - - /// Width of icon - @Deprecated("Use 'size' instead") - final double? width; - - /// Height of icon - @Deprecated("Use 'size' instead") - final double? height; - /// The size of the icon in logical pixels. /// /// Icons occupy a square with width and height equal to size. @@ -1254,25 +99,8 @@ class StreamSvgIcon extends StatelessWidget { @override Widget build(BuildContext context) { - assert( - icon == null || assetName == null, - 'Cannot provide both an icon and an assetName', - ); - - const iconPackage = 'stream_chat_flutter'; - final iconData = switch (icon) { - final icon? => icon, - null => switch (assetName) { - final name? => SvgIconData( - 'lib/svgs/$name', - package: iconPackage, - ), - _ => null, - }, - }; - return SvgIcon( - iconData, + icon, size: size, color: color, textDirection: textDirection, @@ -1281,58 +109,3 @@ class StreamSvgIcon extends StatelessWidget { ); } } - -/// Alternative of [StreamSvgIcon] which follows the [IconTheme]. -@Deprecated("Use regular 'StreamSvgIcon' instead") -class StreamIconThemeSvgIcon extends StatelessWidget { - /// Creates a [StreamIconThemeSvgIcon]. - @Deprecated("Use regular 'StreamSvgIcon' instead") - const StreamIconThemeSvgIcon({ - super.key, - this.assetName, - this.width, - this.height, - this.color, - }); - - /// Factory constructor to create [StreamIconThemeSvgIcon] - /// from [StreamSvgIcon]. - @Deprecated("Use regular 'StreamSvgIcon' instead") - factory StreamIconThemeSvgIcon.fromSvgIcon( - StreamSvgIcon streamSvgIcon, - ) { - return StreamIconThemeSvgIcon( - assetName: streamSvgIcon.assetName, - width: streamSvgIcon.width, - height: streamSvgIcon.height, - color: streamSvgIcon.color, - ); - } - - /// Name of icon asset - final String? assetName; - - /// Width of icon - final double? width; - - /// Height of icon - final double? height; - - /// Color of icon - final Color? color; - - @override - Widget build(BuildContext context) { - final iconTheme = IconTheme.of(context); - final color = this.color ?? iconTheme.color; - final width = this.width ?? iconTheme.size; - final height = this.height ?? iconTheme.size; - - return StreamSvgIcon( - assetName: assetName, - width: width, - height: height, - color: color, - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/indicators/unread_indicator.dart b/packages/stream_chat_flutter/lib/src/indicators/unread_indicator.dart index 728d54f659..f035edb700 100644 --- a/packages/stream_chat_flutter/lib/src/indicators/unread_indicator.dart +++ b/packages/stream_chat_flutter/lib/src/indicators/unread_indicator.dart @@ -7,13 +7,9 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// {@endtemplate} class StreamUnreadIndicator extends StatelessWidget { /// Displays the total unread count. - StreamUnreadIndicator({ + const StreamUnreadIndicator({ super.key, - @Deprecated('Use StreamUnreadIndicator.channels instead') String? cid, - }) : _unreadType = switch (cid) { - final cid? => _UnreadChannels(cid: cid), - _ => const _TotalUnreadCount(), - }; + }) : _unreadType = const _TotalUnreadCount(); /// Displays the unreadChannel count. /// diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart index c410532d2d..396af5ace3 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/options/stream_file_picker.dart @@ -19,7 +19,7 @@ class StreamFilePicker extends StatelessWidget { this.type = FileType.any, this.allowedExtensions, this.onFileLoading, - this.allowCompression = true, + this.compressionQuality = 0, this.withData = false, this.withReadStream = false, this.lockParentWindow = false, @@ -43,8 +43,8 @@ class StreamFilePicker extends StatelessWidget { /// Callback called when the file picker is loading a file. final Function(FilePickerStatus)? onFileLoading; - /// Whether to allow compression of the file. - final bool allowCompression; + /// The compression quality for the file. + final int compressionQuality; /// Whether to include the file data in the [Attachment]. final bool withData; @@ -73,7 +73,7 @@ class StreamFilePicker extends StatelessWidget { type: type, allowedExtensions: allowedExtensions, onFileLoading: onFileLoading, - allowCompression: allowCompression, + compressionQuality: compressionQuality, withData: withData, withReadStream: withReadStream, lockParentWindow: lockParentWindow, diff --git a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart index 2313552a1b..5ddb5e7df5 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/attachment_picker/stream_attachment_picker_bottom_sheet.dart @@ -77,8 +77,6 @@ Future showStreamAttachmentPickerModalBottomSheet({ bool isDismissible = true, bool enableDrag = true, bool useSystemAttachmentPicker = false, - @Deprecated("Use 'useSystemAttachmentPicker' instead.") - bool useNativeAttachmentPickerOnMobile = false, RouteSettings? routeSettings, AnimationController? transitionAnimationController, Clip? clipBehavior = Clip.hardEdge, diff --git a/packages/stream_chat_flutter/lib/src/message_input/dm_checkbox.dart b/packages/stream_chat_flutter/lib/src/message_input/dm_checkbox.dart deleted file mode 100644 index 0a69b8d5fe..0000000000 --- a/packages/stream_chat_flutter/lib/src/message_input/dm_checkbox.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template dmCheckbox} -/// Prompts the user to send a reply to a message thread as a DM. -/// {@endtemplate} -@Deprecated("Use 'DmCheckboxListTile' instead.") -class DmCheckbox extends StatelessWidget { - /// {@macro dmCheckbox} - const DmCheckbox({ - super.key, - required this.foregroundDecoration, - required this.color, - required this.onTap, - required this.crossFadeState, - }); - - /// The decoration to use for the button's foreground. - final BoxDecoration foregroundDecoration; - - /// The color to use for the button. - final Color color; - - /// The action to perform when the button is tapped or clicked. - final VoidCallback onTap; - - /// The [CrossFadeState] of the animation. - final CrossFadeState crossFadeState; - - @override - Widget build(BuildContext context) { - final _streamChatTheme = StreamChatTheme.of(context); - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - height: 16, - width: 16, - foregroundDecoration: foregroundDecoration, - child: Center( - child: Material( - borderRadius: BorderRadius.circular(3), - color: color, - child: InkWell( - onTap: onTap, - child: AnimatedCrossFade( - duration: const Duration(milliseconds: 300), - reverseDuration: const Duration(milliseconds: 300), - crossFadeState: crossFadeState, - firstChild: StreamSvgIcon( - size: 16, - icon: StreamSvgIcons.check, - color: _streamChatTheme.colorTheme.barsBg, - ), - secondChild: const SizedBox( - height: 16, - width: 16, - ), - ), - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Text( - context.translations.alsoSendAsDirectMessageLabel, - style: _streamChatTheme.textTheme.footnote.copyWith( - color: - // ignore: deprecated_member_use - _streamChatTheme.colorTheme.textHighEmphasis.withOpacity(0.5), - ), - ), - ), - ], - ); - } -} diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart index 7ae8d3a440..cb1a686a01 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_input.dart @@ -124,10 +124,8 @@ class StreamMessageInput extends StatefulWidget { this.hideSendAsDm = false, this.enableVoiceRecording = false, this.sendVoiceRecordingAutomatically = false, - Widget? idleSendIcon, - @Deprecated("Use 'idleSendIcon' instead") Widget? idleSendButton, - Widget? activeSendIcon, - @Deprecated("Use 'activeSendIcon' instead") Widget? activeSendButton, + this.idleSendIcon, + this.activeSendIcon, this.showCommandsButton = true, this.userMentionsTileBuilder, this.maxAttachmentSize = kDefaultMaxAttachmentSize, @@ -158,27 +156,11 @@ class StreamMessageInput extends StatefulWidget { this.ogPreviewFilter = _defaultOgPreviewFilter, this.hintGetter = _defaultHintGetter, this.contentInsertionConfiguration, - bool useSystemAttachmentPicker = false, - @Deprecated( - 'Use useSystemAttachmentPicker instead. ' - 'This feature was deprecated after v9.4.0', - ) - bool useNativeAttachmentPickerOnMobile = false, + this.useSystemAttachmentPicker = false, this.pollConfig, this.customAttachmentPickerOptions = const [], this.onCustomAttachmentPickerResult, - }) : assert( - idleSendIcon == null || idleSendButton == null, - 'idleSendIcon and idleSendButton cannot be used together', - ), - idleSendIcon = idleSendIcon ?? idleSendButton, - assert( - activeSendIcon == null || activeSendButton == null, - 'activeSendIcon and activeSendButton cannot be used together', - ), - activeSendIcon = activeSendIcon ?? activeSendButton, - useSystemAttachmentPicker = useSystemAttachmentPicker || // - useNativeAttachmentPickerOnMobile; + }); /// The predicate used to send a message on desktop/web final KeyEventPredicate sendMessageKeyPredicate; @@ -307,17 +289,9 @@ class StreamMessageInput extends StatefulWidget { /// Send button widget in an idle state final Widget? idleSendIcon; - /// Send button widget in an idle state - @Deprecated("Use 'idleSendIcon' instead") - Widget? get idleSendButton => idleSendIcon; - /// Send button widget in an active state final Widget? activeSendIcon; - /// Send button widget in an active state - @Deprecated("Use 'activeSendIcon' instead") - Widget? get activeSendButton => activeSendIcon; - /// Customize the tile for the mentions overlay. final UserMentionTileBuilder? userMentionsTileBuilder; @@ -413,14 +387,6 @@ class StreamMessageInput extends StatefulWidget { /// functionality of the system media picker. final bool useSystemAttachmentPicker; - /// Forces use of native attachment picker on mobile instead of the custom - /// Stream attachment picker. - @Deprecated( - 'Use useSystemAttachmentPicker instead. ' - 'This feature was deprecated after v9.4.0', - ) - bool get useNativeAttachmentPickerOnMobile => useSystemAttachmentPicker; - /// The configuration to use while creating a poll. /// /// If not provided, the default configuration is used. diff --git a/packages/stream_chat_flutter/lib/src/message_input/stream_message_send_button.dart b/packages/stream_chat_flutter/lib/src/message_input/stream_message_send_button.dart index ac38e761b6..742846c694 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/stream_message_send_button.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/stream_message_send_button.dart @@ -11,25 +11,10 @@ class StreamMessageSendButton extends StatelessWidget { super.key, this.timeOut = 0, this.isIdle = true, - @Deprecated('Will be removed in the next major version') - this.isCommandEnabled = false, - @Deprecated('Will be removed in the next major version') - this.isEditEnabled = false, - Widget? idleSendIcon, - @Deprecated("Use 'idleSendIcon' instead") Widget? idleSendButton, - Widget? activeSendIcon, - @Deprecated("Use 'activeSendIcon' instead") Widget? activeSendButton, + this.idleSendIcon, + this.activeSendIcon, required this.onSendMessage, - }) : assert( - idleSendIcon == null || idleSendButton == null, - 'idleSendIcon and idleSendButton cannot be used together', - ), - idleSendIcon = idleSendIcon ?? idleSendButton, - assert( - activeSendIcon == null || activeSendButton == null, - 'activeSendIcon and activeSendButton cannot be used together', - ), - activeSendIcon = activeSendIcon ?? activeSendButton; + }); /// Time out related to slow mode. final int timeOut; @@ -37,28 +22,12 @@ class StreamMessageSendButton extends StatelessWidget { /// If true the button will be disabled. final bool isIdle; - /// True if a command is being sent. - @Deprecated('It will be removed in the next major version') - final bool isCommandEnabled; - - /// True if in editing mode. - @Deprecated('It will be removed in the next major version') - final bool isEditEnabled; - /// The icon to display when the button is idle. final Widget? idleSendIcon; - /// The widget to display when the button is disabled. - @Deprecated("Use 'idleSendIcon' instead") - Widget? get idleSendButton => idleSendIcon; - /// The icon to display when the button is active. final Widget? activeSendIcon; - /// The widget to display when the button is enabled. - @Deprecated("Use 'activeSendIcon' instead") - Widget? get activeSendButton => activeSendIcon; - /// The callback to call when the button is pressed. final VoidCallback onSendMessage; diff --git a/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart b/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart index 9802da666a..6b9b2b381e 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart @@ -16,15 +16,9 @@ class FloatingDateDivider extends StatelessWidget { required this.reverse, required this.messages, required this.itemCount, - @Deprecated('No longer used, Will be removed in future versions.') - this.isThreadConversation = false, this.dateDividerBuilder, }); - /// true if this is a thread conversation - @Deprecated('No longer used, Will be removed in future versions.') - final bool isThreadConversation; - /// A [ValueListenable] that provides the positions of items in the list view. final ValueListenable> itemPositionListener; diff --git a/packages/stream_chat_flutter/lib/src/misc/back_button.dart b/packages/stream_chat_flutter/lib/src/misc/back_button.dart index a589a5921d..d2c11d003c 100644 --- a/packages/stream_chat_flutter/lib/src/misc/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/misc/back_button.dart @@ -42,7 +42,7 @@ class StreamBackButton extends StatelessWidget { start: 12, child: switch (channelId) { final cid? => StreamUnreadIndicator.channels(cid: cid), - _ => StreamUnreadIndicator(), + _ => const StreamUnreadIndicator(), }, ), ], diff --git a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart index 2a1a22e028..28c3ffa996 100644 --- a/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/stream_chat_theme.dart @@ -53,14 +53,9 @@ class StreamChatThemeData { Widget Function(BuildContext, User)? defaultUserImage, PlaceholderUserImage? placeholderUserImage, IconThemeData? primaryIconTheme, - @Deprecated('Use StreamChatConfigurationData.reactionIcons instead') - List? reactionIcons, StreamGalleryHeaderThemeData? imageHeaderTheme, StreamGalleryFooterThemeData? imageFooterTheme, StreamMessageListViewThemeData? messageListViewTheme, - @Deprecated( - "Use 'StreamChatThemeData.voiceRecordingAttachmentTheme' instead") - StreamVoiceRecordingThemeData? voiceRecordingTheme, StreamPollCreatorThemeData? pollCreatorTheme, StreamPollInteractorThemeData? pollInteractorTheme, StreamPollOptionsDialogThemeData? pollOptionsDialogTheme, @@ -92,11 +87,9 @@ class StreamChatThemeData { defaultUserImage: defaultUserImage, placeholderUserImage: placeholderUserImage, primaryIconTheme: primaryIconTheme, - reactionIcons: reactionIcons, galleryHeaderTheme: imageHeaderTheme, galleryFooterTheme: imageFooterTheme, messageListViewTheme: messageListViewTheme, - voiceRecordingTheme: voiceRecordingTheme, pollCreatorTheme: pollCreatorTheme, pollInteractorTheme: pollInteractorTheme, pollOptionsDialogTheme: pollOptionsDialogTheme, @@ -135,7 +128,6 @@ class StreamChatThemeData { required this.galleryHeaderTheme, required this.galleryFooterTheme, required this.messageListViewTheme, - required this.voiceRecordingTheme, required this.pollCreatorTheme, required this.pollInteractorTheme, required this.pollResultsDialogTheme, @@ -591,9 +583,6 @@ class StreamChatThemeData { ), audioWaveformSliderTheme: audioWaveformSliderTheme, ), - voiceRecordingTheme: colorTheme.brightness == Brightness.dark - ? StreamVoiceRecordingThemeData.dark() - : StreamVoiceRecordingThemeData.light(), ); } @@ -635,10 +624,6 @@ class StreamChatThemeData { /// Theme configuration for the [StreamMessageListView] widget. final StreamMessageListViewThemeData messageListViewTheme; - /// Theme configuration for the [StreamVoiceRecordingListPLayer] widget. - @Deprecated("Use 'StreamChatThemeData.voiceRecordingAttachmentTheme' instead") - final StreamVoiceRecordingThemeData voiceRecordingTheme; - /// Theme configuration for the [StreamPollCreatorWidget] widget. final StreamPollCreatorThemeData pollCreatorTheme; @@ -695,13 +680,9 @@ class StreamChatThemeData { PlaceholderUserImage? placeholderUserImage, IconThemeData? primaryIconTheme, StreamChannelListHeaderThemeData? channelListHeaderTheme, - @Deprecated('Use StreamChatConfigurationData.reactionIcons instead') - List? reactionIcons, StreamGalleryHeaderThemeData? galleryHeaderTheme, StreamGalleryFooterThemeData? galleryFooterTheme, StreamMessageListViewThemeData? messageListViewTheme, - @Deprecated("Use 'voiceRecordingAttachmentTheme' instead") - StreamVoiceRecordingThemeData? voiceRecordingTheme, StreamPollCreatorThemeData? pollCreatorTheme, StreamPollInteractorThemeData? pollInteractorTheme, StreamPollResultsDialogThemeData? pollResultsDialogTheme, @@ -729,7 +710,6 @@ class StreamChatThemeData { galleryHeaderTheme: galleryHeaderTheme ?? this.galleryHeaderTheme, galleryFooterTheme: galleryFooterTheme ?? this.galleryFooterTheme, messageListViewTheme: messageListViewTheme ?? this.messageListViewTheme, - voiceRecordingTheme: voiceRecordingTheme ?? this.voiceRecordingTheme, pollCreatorTheme: pollCreatorTheme ?? this.pollCreatorTheme, pollInteractorTheme: pollInteractorTheme ?? this.pollInteractorTheme, pollResultsDialogTheme: @@ -767,7 +747,6 @@ class StreamChatThemeData { galleryFooterTheme: galleryFooterTheme.merge(other.galleryFooterTheme), messageListViewTheme: messageListViewTheme.merge(other.messageListViewTheme), - voiceRecordingTheme: voiceRecordingTheme.merge(other.voiceRecordingTheme), pollCreatorTheme: pollCreatorTheme.merge(other.pollCreatorTheme), pollInteractorTheme: pollInteractorTheme.merge(other.pollInteractorTheme), pollResultsDialogTheme: diff --git a/packages/stream_chat_flutter/lib/src/theme/themes.dart b/packages/stream_chat_flutter/lib/src/theme/themes.dart index 9e41282aa6..867033b09e 100644 --- a/packages/stream_chat_flutter/lib/src/theme/themes.dart +++ b/packages/stream_chat_flutter/lib/src/theme/themes.dart @@ -18,5 +18,4 @@ export 'poll_options_dialog_theme.dart'; export 'poll_results_dialog_theme.dart'; export 'text_theme.dart'; export 'thread_list_tile_theme.dart'; -export 'voice_attachment_theme.dart'; export 'voice_recording_attachment_theme.dart'; diff --git a/packages/stream_chat_flutter/lib/src/theme/voice_attachment_theme.dart b/packages/stream_chat_flutter/lib/src/theme/voice_attachment_theme.dart deleted file mode 100644 index db1ed7db65..0000000000 --- a/packages/stream_chat_flutter/lib/src/theme/voice_attachment_theme.dart +++ /dev/null @@ -1,466 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -/// {@template StreamVoiceRecordingThemeData} -/// The theme data for the voice recording attachment builder. -/// {@endtemplate} -@Deprecated("Use 'StreamVoiceRecordingAttachmentThemeData' instead.") -class StreamVoiceRecordingThemeData with Diagnosticable { - /// {@macro StreamVoiceRecordingThemeData} - const StreamVoiceRecordingThemeData({ - required this.loadingTheme, - required this.sliderTheme, - required this.listPlayerTheme, - required this.playerTheme, - }); - - /// {@template ThemeDataLight} - /// Creates a theme data with light values. - /// {@endtemplate} - factory StreamVoiceRecordingThemeData.light() { - return StreamVoiceRecordingThemeData( - loadingTheme: StreamVoiceRecordingLoadingThemeData.light(), - sliderTheme: StreamVoiceRecordingSliderTheme.light(), - listPlayerTheme: StreamVoiceRecordingListPlayerThemeData.light(), - playerTheme: StreamVoiceRecordingPlayerThemeData.light(), - ); - } - - /// {@template ThemeDataDark} - /// Creates a theme data with dark values. - /// {@endtemplate} - factory StreamVoiceRecordingThemeData.dark() { - return StreamVoiceRecordingThemeData( - loadingTheme: StreamVoiceRecordingLoadingThemeData.dark(), - sliderTheme: StreamVoiceRecordingSliderTheme.dark(), - listPlayerTheme: StreamVoiceRecordingListPlayerThemeData.dark(), - playerTheme: StreamVoiceRecordingPlayerThemeData.dark(), - ); - } - - /// The theme for the loading widget. - final StreamVoiceRecordingLoadingThemeData loadingTheme; - - /// The theme for the slider widget. - final StreamVoiceRecordingSliderTheme sliderTheme; - - /// The theme for the list player widget. - final StreamVoiceRecordingListPlayerThemeData listPlayerTheme; - - /// The theme for the player widget. - final StreamVoiceRecordingPlayerThemeData playerTheme; - - /// {@template ThemeDataMerge} - /// Used to merge the values of another theme data object into this. - /// {@endtemplate} - StreamVoiceRecordingThemeData merge(StreamVoiceRecordingThemeData? other) { - if (other == null) return this; - return StreamVoiceRecordingThemeData( - loadingTheme: loadingTheme.merge(other.loadingTheme), - sliderTheme: sliderTheme.merge(other.sliderTheme), - listPlayerTheme: listPlayerTheme.merge(other.listPlayerTheme), - playerTheme: playerTheme.merge(other.playerTheme), - ); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('loadingTheme', loadingTheme)) - ..add(DiagnosticsProperty('sliderTheme', sliderTheme)) - ..add(DiagnosticsProperty('listPlayerTheme', listPlayerTheme)) - ..add(DiagnosticsProperty('playerTheme', playerTheme)); - } -} - -/// {@template StreamAudioPlayerLoadingTheme} -/// The theme data for the voice recording attachment builder -/// loading widget [StreamVoiceRecordingLoading]. -/// {@endtemplate} -@Deprecated("Use 'StreamVoiceRecordingAttachmentThemeData' instead.") -class StreamVoiceRecordingLoadingThemeData with Diagnosticable { - /// {@macro StreamAudioPlayerLoadingTheme} - const StreamVoiceRecordingLoadingThemeData({ - this.size, - this.strokeWidth, - this.color, - this.padding, - }); - - /// {@macro ThemeDataLight} - factory StreamVoiceRecordingLoadingThemeData.light() { - return const StreamVoiceRecordingLoadingThemeData( - size: Size(20, 20), - strokeWidth: 2, - color: Color(0xFF005FFF), - padding: EdgeInsets.all(8), - ); - } - - /// {@macro ThemeDataDark} - factory StreamVoiceRecordingLoadingThemeData.dark() { - return const StreamVoiceRecordingLoadingThemeData( - size: Size(20, 20), - strokeWidth: 2, - color: Color(0xFF005FFF), - padding: EdgeInsets.all(8), - ); - } - - /// The size of the loading indicator. - final Size? size; - - /// The stroke width of the loading indicator. - final double? strokeWidth; - - /// The color of the loading indicator. - final Color? color; - - /// The padding around the loading indicator. - final EdgeInsets? padding; - - /// {@macro ThemeDataMerge} - StreamVoiceRecordingLoadingThemeData merge( - StreamVoiceRecordingLoadingThemeData? other) { - if (other == null) return this; - return StreamVoiceRecordingLoadingThemeData( - size: other.size, - strokeWidth: other.strokeWidth, - color: other.color, - padding: other.padding, - ); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('size', size)) - ..add(DiagnosticsProperty('strokeWidth', strokeWidth)) - ..add(ColorProperty('color', color)) - ..add(DiagnosticsProperty('padding', padding)); - } -} - -/// {@template StreamAudioPlayerSliderTheme} -/// The theme data for the voice recording attachment builder audio player -/// slider [StreamVoiceRecordingSlider]. -/// {@endtemplate} -@Deprecated("Use 'StreamVoiceRecordingAttachmentThemeData' instead.") -class StreamVoiceRecordingSliderTheme with Diagnosticable { - /// {@macro StreamAudioPlayerSliderTheme} - const StreamVoiceRecordingSliderTheme({ - this.horizontalPadding = 10, - this.spacingRatio = 0.007, - this.waveHeightRatio = 1, - this.buttonBorderRadius = const BorderRadius.all(Radius.circular(8)), - this.buttonColor, - this.buttonBorderColor, - this.buttonBorderWidth = 1, - this.waveColorPlayed, - this.waveColorUnplayed, - this.buttonShadow = const BoxShadow( - color: Color(0x33000000), - blurRadius: 4, - offset: Offset(0, 2), - ), - }); - - /// {@macro ThemeDataLight} - factory StreamVoiceRecordingSliderTheme.light() { - return const StreamVoiceRecordingSliderTheme( - buttonColor: Color(0xFFFFFFFF), - buttonBorderColor: Color(0x3308070733), - waveColorPlayed: Color(0xFF005DFF), - waveColorUnplayed: Color(0xFF7E828B), - ); - } - - /// {@macro ThemeDataDark} - factory StreamVoiceRecordingSliderTheme.dark() { - return const StreamVoiceRecordingSliderTheme( - buttonColor: Color(0xFF005FFF), - buttonBorderColor: Color(0x3308070766), - waveColorPlayed: Color(0xFF337EFF), - waveColorUnplayed: Color(0xFF7E828B), - ); - } - - /// The color of the slider button. - final Color? buttonColor; - - /// The color of the border of the slider button. - final Color? buttonBorderColor; - - /// The width of the border of the slider button. - final double? buttonBorderWidth; - - /// The shadow of the slider button. - final BoxShadow? buttonShadow; - - /// The border radius of the slider button. - final BorderRadius buttonBorderRadius; - - /// The horizontal padding of the slider. - final double horizontalPadding; - - /// Spacing ratios. This is the percentage that the space takes from the whole - /// available space. Typically this value should be between 0.003 to 0.02. - /// Default = 0.01 - final double spacingRatio; - - /// The percentage maximum value of waves. This can be used to reduce the - /// height of bars. Default = 1; - final double waveHeightRatio; - - /// Color of the waves to the left side of the slider button. - final Color? waveColorPlayed; - - /// Color of the waves to the right side of the slider button. - final Color? waveColorUnplayed; - - /// {@macro ThemeDataMerge} - StreamVoiceRecordingSliderTheme merge( - StreamVoiceRecordingSliderTheme? other) { - if (other == null) return this; - return StreamVoiceRecordingSliderTheme( - buttonColor: other.buttonColor, - buttonBorderColor: other.buttonBorderColor, - buttonBorderRadius: other.buttonBorderRadius, - horizontalPadding: other.horizontalPadding, - spacingRatio: other.spacingRatio, - waveHeightRatio: other.waveHeightRatio, - waveColorPlayed: other.waveColorPlayed, - waveColorUnplayed: other.waveColorUnplayed, - ); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(ColorProperty('buttonColor', buttonColor)) - ..add(ColorProperty('buttonBorderColor', buttonBorderColor)) - ..add(DiagnosticsProperty('buttonBorderRadius', buttonBorderRadius)) - ..add(DoubleProperty('horizontalPadding', horizontalPadding)) - ..add(DoubleProperty('spacingRatio', spacingRatio)) - ..add(DoubleProperty('waveHeightRatio', waveHeightRatio)) - ..add(ColorProperty('waveColorPlayed', waveColorPlayed)) - ..add(ColorProperty('waveColorUnplayed', waveColorUnplayed)); - } -} - -/// {@template StreamAudioListPlayerTheme} -/// The theme data for the voice recording attachment builder audio player -/// [StreamVoiceRecordingListPlayer]. -/// {@endtemplate} -@Deprecated("Use 'StreamVoiceRecordingAttachmentThemeData' instead.") -class StreamVoiceRecordingListPlayerThemeData with Diagnosticable { - /// {@macro StreamAudioListPlayerTheme} - const StreamVoiceRecordingListPlayerThemeData({ - this.backgroundColor, - this.borderColor, - this.borderRadius, - this.margin, - }); - - /// {@macro ThemeDataLight} - factory StreamVoiceRecordingListPlayerThemeData.light() { - return StreamVoiceRecordingListPlayerThemeData( - backgroundColor: const Color(0xFFFFFFFF), - borderColor: const Color(0xFFDBDDE1), - borderRadius: BorderRadius.circular(14), - margin: const EdgeInsets.all(4), - ); - } - - /// {@macro ThemeDataDark} - factory StreamVoiceRecordingListPlayerThemeData.dark() { - return StreamVoiceRecordingListPlayerThemeData( - backgroundColor: const Color(0xFF17191C), - borderColor: const Color(0xFF272A30), - borderRadius: BorderRadius.circular(14), - margin: const EdgeInsets.all(4), - ); - } - - /// The background color of the list. - final Color? backgroundColor; - - /// The border color of the list. - final Color? borderColor; - - /// The border radius of the list. - final BorderRadius? borderRadius; - - /// The margin of the list. - final EdgeInsets? margin; - - /// {@macro ThemeDataMerge} - StreamVoiceRecordingListPlayerThemeData merge( - StreamVoiceRecordingListPlayerThemeData? other) { - if (other == null) return this; - return StreamVoiceRecordingListPlayerThemeData( - backgroundColor: other.backgroundColor, - borderColor: other.borderColor, - borderRadius: other.borderRadius, - margin: other.margin, - ); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(ColorProperty('backgroundColor', backgroundColor)) - ..add(ColorProperty('borderColor', borderColor)) - ..add(DiagnosticsProperty('borderRadius', borderRadius)) - ..add(DiagnosticsProperty('margin', margin)); - } -} - -/// {@template StreamVoiceRecordingPlayerTheme} -/// The theme data for the voice recording attachment builder audio player -/// {@endtemplate} -@Deprecated("Use 'StreamVoiceRecordingAttachmentThemeData' instead.") -class StreamVoiceRecordingPlayerThemeData with Diagnosticable { - /// {@macro StreamVoiceRecordingPlayerTheme} - const StreamVoiceRecordingPlayerThemeData({ - this.playIcon = Icons.play_arrow, - this.pauseIcon = Icons.pause, - this.iconColor, - this.buttonBackgroundColor, - this.buttonPadding = const EdgeInsets.symmetric(horizontal: 6), - this.buttonShape = const CircleBorder(), - this.buttonElevation = 2, - this.speedButtonSize = const Size(44, 36), - this.speedButtonElevation = 2, - this.speedButtonPadding = const EdgeInsets.symmetric(horizontal: 8), - this.speedButtonBackgroundColor = const Color(0xFFFFFFFF), - this.speedButtonShape = const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(50)), - ), - this.speedButtonTextStyle = const TextStyle( - fontSize: 12, - color: Color(0xFF080707), - ), - this.fileTypeIcon = const StreamSvgIcon( - icon: StreamSvgIcons.filetypeAudioAac, - ), - this.fileSizeTextStyle = const TextStyle(fontSize: 10), - this.timerTextStyle, - }); - - /// {@macro ThemeDataLight} - factory StreamVoiceRecordingPlayerThemeData.light() { - return const StreamVoiceRecordingPlayerThemeData( - iconColor: Color(0xFF080707), - buttonBackgroundColor: Color(0xFFFFFFFF), - ); - } - - /// {@macro ThemeDataDark} - factory StreamVoiceRecordingPlayerThemeData.dark() { - return const StreamVoiceRecordingPlayerThemeData( - iconColor: Color(0xFF080707), - buttonBackgroundColor: Color(0xFFFFFFFF), - ); - } - - /// The icon to display when the player is paused/stopped. - final IconData playIcon; - - /// The icon to display when the player is playing. - final IconData pauseIcon; - - /// The color of the icons. - final Color? iconColor; - - /// The background color of the buttons. - final Color? buttonBackgroundColor; - - /// The padding of the buttons. - final EdgeInsets? buttonPadding; - - /// The shape of the buttons. - final OutlinedBorder? buttonShape; - - /// The elevation of the buttons. - final double? buttonElevation; - - /// The size of the speed button. - final Size? speedButtonSize; - - /// The elevation of the speed button. - final double? speedButtonElevation; - - /// The padding of the speed button. - final EdgeInsets? speedButtonPadding; - - /// The background color of the speed button. - final Color? speedButtonBackgroundColor; - - /// The shape of the speed button. - final OutlinedBorder? speedButtonShape; - - /// The text style of the speed button. - final TextStyle? speedButtonTextStyle; - - /// The icon to display for the file type. - final Widget? fileTypeIcon; - - /// The text style of the file size. - final TextStyle? fileSizeTextStyle; - - /// The text style of the timer. - final TextStyle? timerTextStyle; - - /// {@macro ThemeDataMerge} - StreamVoiceRecordingPlayerThemeData merge( - StreamVoiceRecordingPlayerThemeData? other) { - if (other == null) return this; - return StreamVoiceRecordingPlayerThemeData( - playIcon: other.playIcon, - pauseIcon: other.pauseIcon, - iconColor: other.iconColor, - buttonBackgroundColor: other.buttonBackgroundColor, - buttonPadding: other.buttonPadding, - buttonShape: other.buttonShape, - buttonElevation: other.buttonElevation, - speedButtonSize: other.speedButtonSize, - speedButtonElevation: other.speedButtonElevation, - speedButtonPadding: other.speedButtonPadding, - speedButtonBackgroundColor: other.speedButtonBackgroundColor, - speedButtonShape: other.speedButtonShape, - speedButtonTextStyle: other.speedButtonTextStyle, - fileTypeIcon: other.fileTypeIcon, - fileSizeTextStyle: other.fileSizeTextStyle, - timerTextStyle: other.timerTextStyle, - ); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('playIcon', playIcon)) - ..add(DiagnosticsProperty('pauseIcon', pauseIcon)) - ..add(ColorProperty('iconColor', iconColor)) - ..add(ColorProperty('buttonBackgroundColor', buttonBackgroundColor)) - ..add(DiagnosticsProperty('buttonPadding', buttonPadding)) - ..add(DiagnosticsProperty('buttonShape', buttonShape)) - ..add(DoubleProperty('buttonElevation', buttonElevation)) - ..add(DiagnosticsProperty('speedButtonSize', speedButtonSize)) - ..add(DoubleProperty('speedButtonElevation', speedButtonElevation)) - ..add(DiagnosticsProperty('speedButtonPadding', speedButtonPadding)) - ..add(ColorProperty( - 'speedButtonBackgroundColor', speedButtonBackgroundColor)) - ..add(DiagnosticsProperty('speedButtonShape', speedButtonShape)) - ..add(DiagnosticsProperty('speedButtonTextStyle', speedButtonTextStyle)) - ..add(DiagnosticsProperty('fileTypeIcon', fileTypeIcon)) - ..add(DiagnosticsProperty('fileSizeTextStyle', fileSizeTextStyle)) - ..add(DiagnosticsProperty('timerTextStyle', timerTextStyle)); - } -} diff --git a/packages/stream_chat_flutter/lib/src/utils/extensions.dart b/packages/stream_chat_flutter/lib/src/utils/extensions.dart index dfda73cc6a..ac638ca579 100644 --- a/packages/stream_chat_flutter/lib/src/utils/extensions.dart +++ b/packages/stream_chat_flutter/lib/src/utils/extensions.dart @@ -561,24 +561,6 @@ extension MessageListX on Iterable { /// /// The [userRead] is the last read message by the user. /// - /// The last unread message is the last message in the list that is not - /// sent by the current user and is sent after the last read message. - @Deprecated("Use 'StreamChannel.getFirstUnreadMessage' instead.") - Message? lastUnreadMessage(Read? userRead) { - if (isEmpty || userRead == null) return null; - - if (first.createdAt.isAfter(userRead.lastRead) && - last.createdAt.isBefore(userRead.lastRead)) { - return lastWhereOrNull( - (it) => - it.user?.id != userRead.user.id && - it.id != userRead.lastReadMessageId && - it.createdAt.compareTo(userRead.lastRead) > 0, - ); - } - - return null; - } } /// Useful extensions on [ChannelModel]. diff --git a/packages/stream_chat_flutter/lib/src/video/video_thumbnail_image.dart b/packages/stream_chat_flutter/lib/src/video/video_thumbnail_image.dart index 21018113fc..b53f6ebe86 100644 --- a/packages/stream_chat_flutter/lib/src/video/video_thumbnail_image.dart +++ b/packages/stream_chat_flutter/lib/src/video/video_thumbnail_image.dart @@ -87,10 +87,9 @@ class StreamVideoThumbnailImage } @override - @Deprecated('Will get replaced by loadImage in the next major version.') - ImageStreamCompleter loadBuffer( + ImageStreamCompleter loadImage( StreamVideoThumbnailImage key, - DecoderBufferCallback decode, + ImageDecoderCallback decode, ) { return MultiFrameImageStreamCompleter( codec: _loadAsync(key, decode), @@ -103,10 +102,9 @@ class StreamVideoThumbnailImage ); } - @Deprecated('Will get replaced by loadImage in the next major version.') Future _loadAsync( StreamVideoThumbnailImage key, - DecoderBufferCallback decode, + ImageDecoderCallback decode, ) async { assert(key == this, '$key is not $this'); diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 5471df1380..7aeeffb15d 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -8,9 +8,6 @@ export 'src/ai_assistant/stream_typewriter_builder.dart'; export 'src/ai_assistant/streaming_message_view.dart'; export 'src/attachment/attachment.dart'; export 'src/attachment/builder/attachment_widget_builder.dart'; -export 'src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_list_player.dart'; -export 'src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_loading.dart'; -export 'src/attachment/builder/voice_recording_attachment_builder/stream_voice_recording_player.dart'; export 'src/attachment/gallery_attachment.dart'; export 'src/attachment/handler/stream_attachment_handler.dart'; export 'src/attachment/image_attachment.dart'; @@ -144,5 +141,3 @@ export 'src/utils/device_segmentation.dart'; export 'src/utils/extensions.dart'; export 'src/utils/helpers.dart'; export 'src/utils/typedefs.dart'; -// TODO: Remove this in favor of StreamVideoAttachmentThumbnail. -export 'src/video/video_thumbnail_image.dart'; diff --git a/packages/stream_chat_flutter/test/src/indicators/unread_indicator_test.dart b/packages/stream_chat_flutter/test/src/indicators/unread_indicator_test.dart index 61cf5b941a..71f91c0235 100644 --- a/packages/stream_chat_flutter/test/src/indicators/unread_indicator_test.dart +++ b/packages/stream_chat_flutter/test/src/indicators/unread_indicator_test.dart @@ -38,7 +38,7 @@ void main() { client: client, child: StreamChannel( channel: channel, - child: Scaffold( + child: const Scaffold( body: StreamUnreadIndicator(), ), ), diff --git a/packages/stream_chat_flutter/test/src/message_input/dm_checkbox_test.dart b/packages/stream_chat_flutter/test/src/message_input/dm_checkbox_test.dart deleted file mode 100644 index 36e67a15e6..0000000000 --- a/packages/stream_chat_flutter/test/src/message_input/dm_checkbox_test.dart +++ /dev/null @@ -1,134 +0,0 @@ -import 'package:alchemist/alchemist.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:stream_chat_flutter/src/message_input/dm_checkbox.dart'; -import 'package:stream_chat_flutter/stream_chat_flutter.dart'; - -import '../material_app_wrapper.dart'; - -@Deprecated('') -void main() { - testWidgets('DmCheckbox onTap works', (tester) async { - var count = 0; - await tester.pumpWidget( - MaterialApp( - home: StreamChatTheme( - data: StreamChatThemeData.light(), - child: Scaffold( - body: Center( - child: DmCheckbox( - foregroundDecoration: BoxDecoration( - border: Border.all( - color: StreamChatThemeData.light() - .colorTheme - .textHighEmphasis - // ignore: deprecated_member_use - .withOpacity(0.5), - width: 2, - ), - borderRadius: BorderRadius.circular(3), - ), - color: StreamChatThemeData.light().colorTheme.accentPrimary, - onTap: () { - count++; - }, - crossFadeState: CrossFadeState.showFirst, - ), - ), - ), - ), - ), - ); - - expect(find.byType(AnimatedCrossFade), findsOneWidget); - final checkbox = find.byType(InkWell); - await tester.tap(checkbox); - await tester.pumpAndSettle(); - expect(count, 1); - }); - - goldenTest( - 'golden test for checked DmCheckbox with border', - fileName: 'dm_checkbox_0', - constraints: const BoxConstraints.tightFor(width: 200, height: 50), - builder: () => MaterialAppWrapper( - home: StreamChatTheme( - data: StreamChatThemeData.light(), - child: Scaffold( - body: Center( - child: DmCheckbox( - foregroundDecoration: BoxDecoration( - border: Border.all( - color: StreamChatThemeData.light() - .colorTheme - .textHighEmphasis - // ignore: deprecated_member_use - .withOpacity(0.5), - width: 2, - ), - borderRadius: BorderRadius.circular(3), - ), - color: StreamChatThemeData.light().colorTheme.accentPrimary, - onTap: () {}, - crossFadeState: CrossFadeState.showFirst, - ), - ), - ), - ), - ), - ); - - goldenTest( - 'golden test for checked DmCheckbox without border', - fileName: 'dm_checkbox_1', - constraints: const BoxConstraints.tightFor(width: 200, height: 50), - builder: () => MaterialAppWrapper( - home: StreamChatTheme( - data: StreamChatThemeData.light(), - child: Scaffold( - body: Center( - child: DmCheckbox( - foregroundDecoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - ), - color: StreamChatThemeData.light().colorTheme.accentPrimary, - onTap: () {}, - crossFadeState: CrossFadeState.showFirst, - ), - ), - ), - ), - ), - ); - - goldenTest( - 'golden test for unchecked DmCheckbox with border', - fileName: 'dm_checkbox_2', - constraints: const BoxConstraints.tightFor(width: 200, height: 50), - builder: () => MaterialAppWrapper( - home: StreamChatTheme( - data: StreamChatThemeData.light(), - child: Scaffold( - body: Center( - child: DmCheckbox( - foregroundDecoration: BoxDecoration( - border: Border.all( - color: StreamChatThemeData.light() - .colorTheme - .textHighEmphasis - // ignore: deprecated_member_use - .withOpacity(0.5), - width: 2, - ), - borderRadius: BorderRadius.circular(3), - ), - color: StreamChatThemeData.light().colorTheme.barsBg, - onTap: () {}, - crossFadeState: CrossFadeState.showSecond, - ), - ), - ), - ), - ), - ); -} diff --git a/packages/stream_chat_flutter/test/src/utils/extension_test.dart b/packages/stream_chat_flutter/test/src/utils/extension_test.dart index 4536611fbe..18f157a436 100644 --- a/packages/stream_chat_flutter/test/src/utils/extension_test.dart +++ b/packages/stream_chat_flutter/test/src/utils/extension_test.dart @@ -272,124 +272,4 @@ void main() { expect(modifiedMessage.text, isNot(contains('@Alice'))); }); }); - - group('Message List Extension Tests', () { - group('lastUnreadMessage', () { - test('should return null when list is empty', () { - final messages = []; - final userRead = Read( - lastRead: DateTime.now(), - user: User(id: 'user1'), - ); - expect(messages.lastUnreadMessage(userRead), isNull); - }); - - test('should return null when userRead is null', () { - final messages = [ - Message(id: '1'), - Message(id: '2'), - ]; - expect(messages.lastUnreadMessage(null), isNull); - }); - - test('should return null when all messages are read', () { - final lastRead = DateTime.now(); - final messages = [ - Message( - id: '1', - createdAt: lastRead.subtract(const Duration(seconds: 1))), - Message(id: '2', createdAt: lastRead), - ]; - final userRead = Read( - lastRead: lastRead, - user: User(id: 'user1'), - ); - expect(messages.lastUnreadMessage(userRead), isNull); - }); - - test('should return null when all messages are mine', () { - final lastRead = DateTime.now(); - final userRead = Read( - lastRead: lastRead, - user: User(id: 'user1'), - ); - final messages = [ - Message( - id: '1', - user: userRead.user, - createdAt: lastRead.add(const Duration(seconds: 1))), - Message(id: '2', user: userRead.user, createdAt: lastRead), - ]; - expect(messages.lastUnreadMessage(userRead), isNull); - }); - - test('should return the message', () { - final lastRead = DateTime.now(); - final otherUser = User(id: 'user2'); - final userRead = Read( - lastRead: lastRead, - user: User(id: 'user1'), - ); - - final messages = [ - Message( - id: '1', - user: otherUser, - createdAt: lastRead.add(const Duration(seconds: 2)), - ), - Message( - id: '2', - user: otherUser, - createdAt: lastRead.add(const Duration(seconds: 1)), - ), - Message( - id: '3', - user: otherUser, - createdAt: lastRead.subtract(const Duration(seconds: 1)), - ), - ]; - - final lastUnreadMessage = messages.lastUnreadMessage(userRead); - expect(lastUnreadMessage, isNotNull); - expect(lastUnreadMessage!.id, '2'); - }); - - test('should not return the last message read', () { - final lastRead = DateTime.timestamp(); - final otherUser = User(id: 'user2'); - final userRead = Read( - lastRead: lastRead, - user: User(id: 'user1'), - lastReadMessageId: '3', - ); - - final messages = [ - Message( - id: '1', - user: otherUser, - createdAt: lastRead.add(const Duration(seconds: 2)), - ), - Message( - id: '2', - user: otherUser, - createdAt: lastRead.add(const Duration(milliseconds: 1)), - ), - Message( - id: '3', - user: otherUser, - createdAt: lastRead.add(const Duration(microseconds: 1)), - ), - Message( - id: '4', - user: otherUser, - createdAt: lastRead.subtract(const Duration(seconds: 1)), - ), - ]; - - final lastUnreadMessage = messages.lastUnreadMessage(userRead); - expect(lastUnreadMessage, isNotNull); - expect(lastUnreadMessage!.id, '2'); - }); - }); - }); } diff --git a/sample_app/lib/pages/channel_file_display_screen.dart b/sample_app/lib/pages/channel_file_display_screen.dart index 727dd6bb87..a3228ca68f 100644 --- a/sample_app/lib/pages/channel_file_display_screen.dart +++ b/sample_app/lib/pages/channel_file_display_screen.dart @@ -31,10 +31,7 @@ class _ChannelFileDisplayScreenState extends State { const ['file'], ), sort: [ - const SortOption( - 'created_at', - direction: SortOption.ASC, - ), + const SortOption.asc('created_at'), ], limit: 20, ); diff --git a/sample_app/lib/pages/channel_list_page.dart b/sample_app/lib/pages/channel_list_page.dart index 6084a038fa..63613c0c8b 100644 --- a/sample_app/lib/pages/channel_list_page.dart +++ b/sample_app/lib/pages/channel_list_page.dart @@ -47,7 +47,7 @@ class _ChannelListPageState extends State { ? StreamChatTheme.of(context).colorTheme.textHighEmphasis : Colors.grey, ), - PositionedDirectional( + const PositionedDirectional( top: -4, start: 12, child: StreamUnreadIndicator(), diff --git a/sample_app/lib/pages/channel_media_display_screen.dart b/sample_app/lib/pages/channel_media_display_screen.dart index d7b7a472d1..2504e3ae00 100644 --- a/sample_app/lib/pages/channel_media_display_screen.dart +++ b/sample_app/lib/pages/channel_media_display_screen.dart @@ -33,10 +33,7 @@ class _ChannelMediaDisplayScreenState extends State { const ['image', 'video'], ), sort: [ - const SortOption( - 'created_at', - direction: SortOption.ASC, - ), + const SortOption.asc('created_at'), ], limit: 20, ); diff --git a/sample_app/lib/pages/chat_info_screen.dart b/sample_app/lib/pages/chat_info_screen.dart index 6caacbdfc4..81ac6dbfe5 100644 --- a/sample_app/lib/pages/chat_info_screen.dart +++ b/sample_app/lib/pages/chat_info_screen.dart @@ -51,8 +51,7 @@ class _ChatInfoScreenState extends State { height: 8, color: StreamChatTheme.of(context).colorTheme.disabled, ), - if (channel.ownCapabilities.contains(PermissionType.deleteChannel)) - _buildDeleteListTile(), + if (channel.canDeleteChannel) _buildDeleteListTile(), ], ), ); diff --git a/sample_app/lib/pages/group_info_screen.dart b/sample_app/lib/pages/group_info_screen.dart index a3ffef7d48..1a5e6997ad 100644 --- a/sample_app/lib/pages/group_info_screen.dart +++ b/sample_app/lib/pages/group_info_screen.dart @@ -105,10 +105,7 @@ class _GroupInfoScreenState extends State { ], ), sort: [ - const SortOption( - 'name', - direction: 1, - ), + const SortOption.asc(UserSortKey.name), ], ); super.didChangeDependencies(); @@ -194,8 +191,7 @@ class _GroupInfoScreenState extends State { ), centerTitle: true, actions: [ - if (channel.ownCapabilities - .contains(PermissionType.updateChannelMembers)) + if (channel.canUpdateChannelMembers) StreamNeumorphicButton( child: InkWell( onTap: () { @@ -220,9 +216,7 @@ class _GroupInfoScreenState extends State { height: 8, color: StreamChatTheme.of(context).colorTheme.disabled, ), - if (channel.ownCapabilities - .contains(PermissionType.updateChannel)) - _buildNameTile(), + if (channel.canUpdateChannel) _buildNameTile(), _buildOptionListTiles(), ], ), @@ -415,8 +409,7 @@ class _GroupInfoScreenState extends State { ), Expanded( child: TextField( - enabled: channel.ownCapabilities - .contains(PermissionType.updateChannel), + enabled: channel.canUpdateChannel, focusNode: _focusNode, controller: _nameController, cursorColor: @@ -482,7 +475,7 @@ class _GroupInfoScreenState extends State { Widget _buildOptionListTiles() { return Column( children: [ - if (channel.ownCapabilities.contains(PermissionType.muteChannel)) + if (channel.canMuteChannel) _GroupInfoToggle( title: AppLocalizations.of(context).muteGroup, icon: StreamSvgIcons.mute, @@ -568,8 +561,7 @@ class _GroupInfoScreenState extends State { ); }, ), - if (!channel.isDistinct && - channel.ownCapabilities.contains(PermissionType.leaveChannel)) + if (!channel.isDistinct && channel.canLeaveChannel) StreamOptionListTile( tileColor: StreamChatTheme.of(context).colorTheme.appBg, separatorColor: StreamChatTheme.of(context).colorTheme.disabled, diff --git a/sample_app/lib/pages/new_chat_screen.dart b/sample_app/lib/pages/new_chat_screen.dart index dfa5daaaf0..fa162f28aa 100644 --- a/sample_app/lib/pages/new_chat_screen.dart +++ b/sample_app/lib/pages/new_chat_screen.dart @@ -29,10 +29,7 @@ class _NewChatScreenState extends State { Filter.notEqual('id', StreamChat.of(context).currentUser!.id), ]), sort: [ - const SortOption( - 'name', - direction: 1, - ), + const SortOption.asc(UserSortKey.name), ], ); diff --git a/sample_app/lib/pages/pinned_messages_screen.dart b/sample_app/lib/pages/pinned_messages_screen.dart index 2bcc792fc6..01c9ac5075 100644 --- a/sample_app/lib/pages/pinned_messages_screen.dart +++ b/sample_app/lib/pages/pinned_messages_screen.dart @@ -25,10 +25,7 @@ class _PinnedMessagesScreenState extends State { true, ), sort: [ - const SortOption( - 'created_at', - direction: SortOption.ASC, - ), + const SortOption.asc('created_at'), ], limit: 20, ); From 3e95d5cd170bbcea14d0cc5c404ddc8f2a246b67 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 17 Jul 2025 14:36:31 +0200 Subject: [PATCH 16/34] chore(repo): release v10.0.0-beta.3 (#2310) --- melos.yaml | 10 +++++----- packages/stream_chat/CHANGELOG.md | 12 +++++++----- packages/stream_chat/example/pubspec.yaml | 2 +- packages/stream_chat/lib/version.dart | 2 +- packages/stream_chat/pubspec.yaml | 2 +- packages/stream_chat_flutter/CHANGELOG.md | 4 +++- packages/stream_chat_flutter/example/pubspec.yaml | 6 +++--- packages/stream_chat_flutter/pubspec.yaml | 4 ++-- packages/stream_chat_flutter_core/CHANGELOG.md | 4 ++++ .../stream_chat_flutter_core/example/pubspec.yaml | 2 +- packages/stream_chat_flutter_core/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/CHANGELOG.md | 4 ++++ .../stream_chat_localizations/example/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/CHANGELOG.md | 4 ++++ .../stream_chat_persistence/example/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/pubspec.yaml | 4 ++-- sample_app/pubspec.yaml | 6 +++--- 18 files changed, 49 insertions(+), 33 deletions(-) diff --git a/melos.yaml b/melos.yaml index b3abdab213..a081ebd3e3 100644 --- a/melos.yaml +++ b/melos.yaml @@ -80,11 +80,11 @@ command: share_plus: ^11.0.0 shimmer: ^3.0.0 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.2 - stream_chat_flutter: ^10.0.0-beta.2 - stream_chat_flutter_core: ^10.0.0-beta.2 - stream_chat_localizations: ^10.0.0-beta.2 - stream_chat_persistence: ^10.0.0-beta.2 + stream_chat: ^10.0.0-beta.3 + stream_chat_flutter: ^10.0.0-beta.3 + stream_chat_flutter_core: ^10.0.0-beta.3 + stream_chat_localizations: ^10.0.0-beta.3 + stream_chat_persistence: ^10.0.0-beta.3 streaming_shared_preferences: ^2.0.0 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 4546857581..b804568124 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,12 +1,14 @@ -## Upcoming Beta +## 10.0.0-beta.3 🛑️ Breaking - **Deprecated API Cleanup**: Removed all deprecated classes, methods, and properties for the v10 major release: - - **Removed Classes**: `PermissionType` (use string constants like `'delete-channel'`, `'update-channel'`), `CallApi`, `CallPayload`, `CallTokenPayload`, `CreateCallPayload` - - **Removed Methods**: `cooldownStartedAt` getter from `Channel`, `getCallToken` and `createCall` from `StreamChatClient` - - **Removed Properties**: `reactionCounts` and `reactionScores` getters from `Message` (use `reactionGroups` instead), `call` property from `StreamChatApi` - - **Removed Files**: `permission_type.dart`, `call_api.dart`, `call_payload.dart` and their associated tests + - **Removed Classes**: `PermissionType` (use string constants like `'delete-channel'`, `'update-channel'`), `CallApi`, `CallPayload`, `CallTokenPayload`, `CreateCallPayload` + - **Removed Methods**: `cooldownStartedAt` getter from `Channel`, `getCallToken` and `createCall` from `StreamChatClient` + - **Removed Properties**: `reactionCounts` and `reactionScores` getters from `Message` (use `reactionGroups` instead), `call` property from `StreamChatApi` + - **Removed Files**: `permission_type.dart`, `call_api.dart`, `call_payload.dart` and their associated tests + +- Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat/changelog). ## 9.14.0 diff --git a/packages/stream_chat/example/pubspec.yaml b/packages/stream_chat/example/pubspec.yaml index 2dac7f5e7c..6a8d248238 100644 --- a/packages/stream_chat/example/pubspec.yaml +++ b/packages/stream_chat/example/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.2 + stream_chat: ^10.0.0-beta.3 flutter: uses-material-design: true diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index 77fc35ca06..fe07491c67 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -9,4 +9,4 @@ /// Current package version /// Used in [SystemEnvironmentManager] to build the `x-stream-client` header -const PACKAGE_VERSION = '10.0.0-beta.2'; +const PACKAGE_VERSION = '10.0.0-beta.3'; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index fcdee2bc68..3d38890367 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat homepage: https://getstream.io/ description: The official Dart client for Stream Chat, a service for building chat applications. -version: 10.0.0-beta.2 +version: 10.0.0-beta.3 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 7fedf6ba7d..09ddcbe7e9 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.3 🛑️ Breaking @@ -22,6 +22,8 @@ For more details, please refer to the [migration guide](../../migrations/v10-mig - Added `customAttachmentPickerOptions` to `StreamMessageInput` to allow injecting custom picker tabs like contact and location pickers. - Added `onCustomAttachmentPickerResult` callback to `StreamMessageInput` to handle results returned by custom picker tabs. +- Included the changes from version [`9.14.0`](https://pub.dev/packages/stream_chat_flutter/changelog). + ## 9.14.0 🐞 Fixed diff --git a/packages/stream_chat_flutter/example/pubspec.yaml b/packages/stream_chat_flutter/example/pubspec.yaml index 41ac689903..470b719249 100644 --- a/packages/stream_chat_flutter/example/pubspec.yaml +++ b/packages/stream_chat_flutter/example/pubspec.yaml @@ -25,9 +25,9 @@ dependencies: flutter: sdk: flutter responsive_builder: ^0.7.0 - stream_chat_flutter: ^10.0.0-beta.2 - stream_chat_localizations: ^10.0.0-beta.2 - stream_chat_persistence: ^10.0.0-beta.2 + stream_chat_flutter: ^10.0.0-beta.3 + stream_chat_localizations: ^10.0.0-beta.3 + stream_chat_persistence: ^10.0.0-beta.3 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index b8459010a0..ec6309a9f0 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.2 +version: 10.0.0-beta.3 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -56,7 +56,7 @@ dependencies: rxdart: ^0.28.0 share_plus: ^11.0.0 shimmer: ^3.0.0 - stream_chat_flutter_core: ^10.0.0-beta.2 + stream_chat_flutter_core: ^10.0.0-beta.3 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index c2cee46e2b..c51d837c32 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.3 + +- Included the changes from version [`9.14.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog). + ## 9.14.0 🐞 Fixed diff --git a/packages/stream_chat_flutter_core/example/pubspec.yaml b/packages/stream_chat_flutter_core/example/pubspec.yaml index 0abb614d50..a67a1bd2ea 100644 --- a/packages/stream_chat_flutter_core/example/pubspec.yaml +++ b/packages/stream_chat_flutter_core/example/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter_core: ^10.0.0-beta.2 + stream_chat_flutter_core: ^10.0.0-beta.3 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index d39763cc79..cfec662493 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter_core homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.2 +version: 10.0.0-beta.3 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -31,7 +31,7 @@ dependencies: meta: ^1.9.1 package_info_plus: ^8.3.0 rxdart: ^0.28.0 - stream_chat: ^10.0.0-beta.2 + stream_chat: ^10.0.0-beta.3 dev_dependencies: build_runner: ^2.4.9 diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 35514672f3..0e85fffd66 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.3 + +- Included the changes from version [`9.14.0`](https://pub.dev/packages/stream_chat_localizations/changelog). + ## 9.14.0 - Updated `stream_chat_flutter` dependency to [`9.14.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_localizations/example/pubspec.yaml b/packages/stream_chat_localizations/example/pubspec.yaml index 298679e12e..df4dcc5f33 100644 --- a/packages/stream_chat_localizations/example/pubspec.yaml +++ b/packages/stream_chat_localizations/example/pubspec.yaml @@ -24,8 +24,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.2 - stream_chat_localizations: ^10.0.0-beta.2 + stream_chat_flutter: ^10.0.0-beta.3 + stream_chat_localizations: ^10.0.0-beta.3 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_localizations/pubspec.yaml b/packages/stream_chat_localizations/pubspec.yaml index 93d68bd522..a5d76a1201 100644 --- a/packages/stream_chat_localizations/pubspec.yaml +++ b/packages/stream_chat_localizations/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_chat_localizations description: The Official localizations for Stream Chat Flutter, a service for building chat applications -version: 10.0.0-beta.2 +version: 10.0.0-beta.3 homepage: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -26,7 +26,7 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.2 + stream_chat_flutter: ^10.0.0-beta.3 dev_dependencies: flutter_test: diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 993f8a8845..1a3e3bff99 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.3 + +- Included the changes from version [`9.14.0`](https://pub.dev/packages/stream_chat_persistence/changelog). + ## 9.14.0 - Updated `stream_chat` dependency to [`9.14.0`](https://pub.dev/packages/stream_chat/changelog). diff --git a/packages/stream_chat_persistence/example/pubspec.yaml b/packages/stream_chat_persistence/example/pubspec.yaml index 0b52b8f1fa..d34f53885c 100644 --- a/packages/stream_chat_persistence/example/pubspec.yaml +++ b/packages/stream_chat_persistence/example/pubspec.yaml @@ -23,8 +23,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.2 - stream_chat_persistence: ^10.0.0-beta.2 + stream_chat: ^10.0.0-beta.3 + stream_chat_persistence: ^10.0.0-beta.3 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index 800a1a0923..1ff8a0a8f8 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_persistence homepage: https://github.com/GetStream/stream-chat-flutter description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.2 +version: 10.0.0-beta.3 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -30,7 +30,7 @@ dependencies: path: ^1.8.3 path_provider: ^2.1.3 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.2 + stream_chat: ^10.0.0-beta.3 dev_dependencies: build_runner: ^2.4.9 diff --git a/sample_app/pubspec.yaml b/sample_app/pubspec.yaml index 960ae43812..3cbf74a632 100644 --- a/sample_app/pubspec.yaml +++ b/sample_app/pubspec.yaml @@ -34,9 +34,9 @@ dependencies: lottie: ^3.1.2 provider: ^6.0.5 sentry_flutter: ^8.3.0 - stream_chat_flutter: ^10.0.0-beta.2 - stream_chat_localizations: ^10.0.0-beta.2 - stream_chat_persistence: ^10.0.0-beta.2 + stream_chat_flutter: ^10.0.0-beta.3 + stream_chat_localizations: ^10.0.0-beta.3 + stream_chat_persistence: ^10.0.0-beta.3 streaming_shared_preferences: ^2.0.0 uuid: ^4.4.0 video_player: ^2.8.7 From 86d3220c18aaacb581db6893b978b68eb38b56cf Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Sun, 20 Jul 2025 17:11:36 +0200 Subject: [PATCH 17/34] chore(ui): hide reaction picker bubble border and mask (#2316) Co-authored-by: xsahil03x <25670178+xsahil03x@users.noreply.github.com> --- .../reaction_picker_bubble_overlay.dart | 4 ++-- ...ons_modal_reversed_with_reactions_dark.png | Bin 8601 -> 8499 bytes ...ns_modal_reversed_with_reactions_light.png | Bin 9431 -> 9053 bytes ...sage_actions_modal_with_reactions_dark.png | Bin 8330 -> 8278 bytes ...age_actions_modal_with_reactions_light.png | Bin 9171 -> 8855 bytes .../stream_message_reactions_modal_dark.png | Bin 12157 -> 12105 bytes .../stream_message_reactions_modal_light.png | Bin 13384 -> 13013 bytes ..._message_reactions_modal_reversed_dark.png | Bin 12239 -> 12209 bytes ...message_reactions_modal_reversed_light.png | Bin 13372 -> 12980 bytes 9 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart index a13cc5f3fe..ff4259aa96 100644 --- a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_bubble_overlay.dart @@ -59,9 +59,9 @@ class ReactionPickerBubbleOverlay extends StatelessWidget { visible: visible, childSizeDelta: childSizeDelta, config: ReactionBubbleConfig( - maskWidth: 0, - borderWidth: 0, fillColor: colorTheme.barsBg, + maskColor: Colors.transparent, + borderColor: Colors.transparent, ), anchor: ReactionBubbleAnchor( offset: anchorOffset, diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_dark.png index faf887e30e69c07bf939ae044f4bad4d87f0f775..73e3760669109b21269ef67df07dabeceab64ba1 100644 GIT binary patch literal 8499 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 literal 8601 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 F{U4q8$8rDw diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_reversed_with_reactions_light.png index ef7b39da942aab5a6ca235ad1aa3fa60baf017fe..1a5047f04b13db4f4a56b8b48c8f613d43bd0808 100644 GIT binary patch literal 9053 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 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_with_reactions_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_actions_modal_with_reactions_dark.png index 355c43d2bf4a8e033234d578ccab0dbf023049a3..77030a12a0a006acc6ba42d68e4069d593c6af44 100644 GIT binary patch literal 8278 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 n?*>R8y$kSPtAfSg{f~fRzfJ1MF-a(~G z6X{(DJrn~Z5CX|v@i%kt%$JKVk2+_gZVe`z_D&ygNeg3H1C~p0hMG zH0K}O*VLz>p^c-Vp))zd0M6)aehLRav|jqqdo*POeCy!gl-IonhG)Q^{~0?lC`9u> z^R6L0ZEMyqF3mCEC(i0%hNp)oX5~ZaaAI_vtE;PRbbm~}tB@<-J(Ggc-1u)}!W~A; zg!`ra?lp3a)zzs*rQbOJxU61h>)vO7W`)75Q|_=WOx)~;dAxSKqxO$J?*sDX7k3&Q zGXfC}&^@Bz(>@$w8kK8=BsFKq*ZS?P=+m^_UM^Opp;@^>ODhx+L=&f}PILc?5Y06< zR+{)TXJ{UrIu&${j!yl;zlZ;AmjB}p@kh=qLA#^l<6Vm#QMN7QTkr zk_cN;N=nbSvY!4)C(Uw4R<>iR+9l+zUsip+;#j$rU>J*FtlM-=$Hat5b(m(z#KBVx zr-UURube9@%St-t@(T}-a)Mp~tC^5&NpZ2LQJJ~v)}QJX=Hgr~<7F`k2?-O`F2>bi z8lA4eBL&ZjjUpJiqBAlw>h^y;DpoxwEi5GK)DwSwXmXNzTi(>vR8yIRB%Qu(N=nM& zZm&c+LGte_My1a$a#?sktq!}Zed?c1bKgn(cfHF+s^)fHEz=h3&_)6kJX(uHzsdgy_$n79Gqj;rZSV_$>+Zi@;<@LucreycQA8lt9R-f_eq~h9dV(s z9Hw$`oW`(}4?#+{9FKZr!0Mq$JbcNs{xETeyrp<)yign3wU}k4#?#;b821BP7U8cZ z$o~F48=I7(slpD%fKSQ$Ci#dGr~qCO1hWIxhGKFADLTi~kmGR!q@ywn|M(Q2OJAD=XT6sc-lRh}n(HdNu^Bv3z?j zcC5XV%j%*;>-tgQyz1U&&CQPw(T;;Hg|<*OHqqCJ_)KMdwXPd$98a8*@plP9@~B_p zEzT$@HK|u*AJtv#KT>^~Xp`tn%3{|0K;NDYuUeAGm28gOOSgT#3<|<;g7ABa#-(j= zv8ZrhFql^z%ZZ)UZ3>7~ z;=iAxQ#I2iudE;TQpl|s-g)xe0|;_uGNMy%npS zJlb4s<-3}bBPI9RCUVaPt>B~g+K*J>%}+ct%Aeeh%|aJSEl$*S zA*aS6teK6gqWS4baUqNX{%{e2+ScWoy1jH*8V5?jw~bQg8H?mI9>D7wCQ>~{zVNX` z;8WrJ6ggSBPP{~O-X>n>U=-2Hj>r$tPmg$3EM7Q~`T&&6V=`%;S4>PyCQ#>k&9}%d za#_CMNM;}luBYdo&XZ}S7tSiU6^omk7|O|3*CO&Hvo(TI;Mm@EvO;wa=QbO--yU2x z5DOnIm4Iv=fI`j8r=WljfEg2!+8>X;t1mx5p1;W%_0-r{9@|C51IlxRmBTO;GOuJ6 ziE%5BxE{roSRHGy1>Yu`Lh^oa$@t#(Kpix%4jlf1s=d;$LLeG3x{zNUHsjkZ3jT-p zH8ne8d(zguH`Z-0@hWq$4-fcntT|;WF-U{tH|VbTdfE5Uqetdm_$V2{dE9XNxRu|^ zrL3+_=JYC3X>nyv$!hUP1aIGY@Pb0_UA`s6#wHOsbW}&o<6XP~K?tqmu;ooE?)60b z2PoCVckhP4rtF!8KR&K?HJ`-FcYNlu47Y+1mP!O_-M2R2JBaO)?qtajQ_Eu`V`DD)d2fvsjKcfz z=9Mw{;X5nc^yezl(mVkH^vRopnT6|Jimw}#uO{|t6&gk|%0u|BUWKA~`RC7?`1Ew3 z?Rpj`UXFf5gL#)K2@ctf#WI8~UN!8PH8xud?P_Xvj%5e6+}oQ8_dMEGUJ(Q~0w^k~ zre=Rup6IVOcaSk3foR#s9}*?x2G^ug$FY!*tTi0&%a}TNEwQ)5gEF=? zgl#YTIDTpFw``C08s84LZ7iJgS)I0>Jdw@cLPWwaG~lC zCIB^Nhy%)tq1bX&ET+kxAT5FHkvA@sS7in*~=||+`n428y|&9 z-+^P(9%lu9#gBI`T!k(cTTy&R#>X>phW(wLo$!uckMQwU!bdOZJcH(A5F~RRb6jj} zE=Ge}=gW>5pO}xpdpbmI@I_I!Cm$2j_oP0K4bRH@pip^vc_yzz{fflv>*Q;86kdl~ zcbPAZ5PZ9Ot$YJ!yfKel zY#yShkobi7Rtf}%vBwOns^gh`X=h*>NMZdsAWqZZKrbpvHfBp<76DO@iHQm_acq(5E3(I`)yerBX zh5PlDWzhP8b9$kUb6@448g|26+{vugJ^izOA0q(#z>LTAm^am4s{;xzf3}@Vuu}t| zq6$eNPc$Q7)nT;BQ?(ve=gyroL~z@6zi5&zDleB1zH!5Lw5VRSnL{M2ynHY$n<*}6 zZdj7TnUV*p{Llih-+FcyWKG11ZOIVd&f0il)jckkZ8H_=_~ z7&-?gI{}b`(e}LwPEJnYfLU}bM(@nhnks?0TxT0(nFk%@9KVOkd_=#p2#)8(|bwoZLbGNw|o($Z4L z<5_UE3Vy`EOHDWlU2CvSUWX*w`2qOag)iAgWvkLtlK*Cu=ImS5k_ddsE%qteOEzfxPS+>4}hz zH&Q1@$x#C@YgMg%!SuFAuUHs+v;4hkn2O8F#Gjj)<(EC{J{l|4yUl59V{--A#m3cj zvx@X-X99f{)HqfjAD_JOpmT;QLKYSlXxB;UVGqewZ79?h4p#^b4b9tbc6%b#{X~l{ zzIQnrtZh_c!WI(~^AUblp`5x?H@BGW?QN7Xx>pybQ0VD!I&Z7bs%vq&X!{;U@xUu8qTrAG|W@ct3R;_bJQg+vdgQ!pY z{Q2_=^Xqm+RGM36ff(rF2u|*~EhK7O=IyS!_XY6rSrKmOxCiP9w@ojAy_=StUD1R> zq2OIVLvTx$+XEC{TPsgQ!{!5EoEp}&q@RqCq$+Gxety@BX1&k~kDH_4zq6*wxjhsN z3K;tEVrQ;-Xl^cJf1*neIm5p%^mMZE(nS!Cl25QonVlV#U$+|Ufy1ZYkH?GTjR<$gPMMQVVaCS zRrK@c=eMH*bbV%EZ@xdA|DqcZe+ZKc;D0z-Z=y~9}U!j+eW9ovRhlN zRQ}dUc9TBG%siFZ*CZ(|eW4MyQ$~=qp6m6_90qagUzC#C#0OBBK=yg!ofNimO$bbl z_9yOAt$h1=m6LeJg(OFiAZN}dgxP$a5JzsT^dOYq|PHU{y$x%dPsbEs(Ccfaj zz14k_LPQ4T7Zegz?tfx7G&92oFj~QtK`C}>Fpp+5CJ?={Qqrmncs*0)J;bp;24Z;S z9R%Kif;xOS)jSV~J!}TILamMt4dls}-+m_7UrBNn;W&%yzKR0%iOF)(jQS2IqnDBd z$%l>xxV825$RRYkjuHlm$=EJ)awQl zt%xzLsKuJ`*4G;c0PF+J$i;tedOpgck+hg2Nb+u?;%zbc){-I&gNc*#u3T_!%VHjU z+H9Vijm=8cS7oUVC=_+hC(F2C$kEB~#lU-|3Ok)|Srq?fkW6%TXIiQ=^Qgb|+>9$7 zpO64xvL(3!YYVtM?zeb>dt`<3aWU%HU0&&-O=6O*KkYf=Gj7Q*Z;sqjOq@JiEM5#v zY`NBXLwGSmA|PO(li}0%QEzpJjo8{bPCOou+m|u3v9>Ol`bulUDjptGRaMnqEiuW# z#)g6r4XeZGKM9$$(nf^WE$;dN#lwvh>&$Z6`fi;yohL4GE|-K<+AS zQi!Ss{iwi~H;&Zv|M@<`Kbt)qmHXW}sE)RudZyU5_3g-FdADv?9jc!@VBeJZ1?WGP zy%;y>Pktn&sAxK-#KX%gbG|!FZ9l7T?6fI6Yf)hy-ENukyujPHh;PrK0AV^{Xn$@x ziwH^7zqYLoqiH**7|#5=ukqmV)|ZrZQxnt77pL1cM-9~-UUM3aIXH>UqhK*=|4Ka+V*R-SK$oDI1b0zIuh@>)H%aSLCbG2}T< z+&)Q$9L&Pz(}_x#MJ+Q84IZCfa_v%~lIlTXT{44k2lWj_mhyhPF7$iQAoJuNC{)9N zfh}TD4;fAc$pAa^p}JgS{b=;~f%!2-etq;o$*(S7{(ttO^xx;>2F8eGhKxc8E=~13 zE0*}d=>obWrr!tkbF;IiqiCAj9No2mEA*IE!REp?_QXTE{~d*3n7dHVJ&AY_95Z8S{Y*V-ic+-r4`C zFBV@>t~vkT5gYba5tgrj(QQbvG8Ff%l<@Hu&obz#wx%=PNOEtu&3a#}O92;akVs*3 zP+CLBs~WhbrjCxb{}Sd#ORW~2q@%Nh5CxCa=2Mj3TZZgLuv^tu*$Kw22fqo~KG`WI zoGG|m%@x;rSQ*Ygn5*hLJ5>Vp^8DL6i=8zO%-BR8g~Du?J!R%o6k3j5+)MY@XcY1Y zbQijq)5b^B&vX~wRm77F5*hzqbe0k7(ARvm+kTMGusE`#YatL6S==9#wlSi9hCzL_ z{=&ba=l|{}CJW}{#zy&@U;c8Prd9~$ob)3mfqIo zI4yNRFe+K@2L!Y)Ee%md#|6^`T^iQsb@>|q{*-l(*I)$}|i{H0*hD?+4$9TaE?xoUgOb0dQ9hXiW%@2k+zY z_Gq4@Ks7uQg7?empa0kJ^Ho%{GJ>KFafM;kSk;sJN zQ{iMXnOi^r;8g{!mG`%{r>aFW5Zj8W$?C$sJ9GSvzFS3L=xt;lg^C=Zv3wDLSZbv! z76+XIwHD~1+bJj>BlIMkML>lc1tG&hV-D)*=(x1!5X(4F4w!3(Dk2+j+Yi@e%d&^- zb#-*w2hx>ot*wO;B&-B_6U3slqBx)J-U{|}c6GfS8Wv_d-x46Dre?XdAW2`}pDI7N z{y7q$O;Bt;`sFTtf3e>xpLBJ?l6B3zXUGJpcdz literal 9171 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 literal 12157 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 X$^)CUG2@8=0Uzy01`li0pS=1nU(oDT diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png index 8a76e3d5febd468e5833d4e10a03c11a5219a606..738acac9a4ca5e9fa37244b7fb2fa26203981e2d 100644 GIT binary patch literal 13013 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 literal 13384 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 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png index 2439b81f0bb752f85d7c0f73a1a1a6cb06e01405..56eca318c218b81ea922b7603e27c38578f6c949 100644 GIT binary patch literal 12209 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 diff --git a/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png b/packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png index 382c565a0abae62534cd03f79e4f273757963f66..ff2a215e7594d8afdcb211b729da243de1f9ec05 100644 GIT binary patch literal 12980 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 Date: Wed, 23 Jul 2025 15:13:00 +0200 Subject: [PATCH 18/34] feat(llc): add support for sharing live and static locations (#2305) --- melos.yaml | 5 + packages/stream_chat/CHANGELOG.md | 11 + .../stream_chat/lib/src/client/channel.dart | 594 ++++++++++++---- .../stream_chat/lib/src/client/client.dart | 186 ++++- .../lib/src/client/event_resolvers.dart | 114 ++- .../lib/src/core/api/responses.dart | 12 + .../lib/src/core/api/responses.g.dart | 8 + .../lib/src/core/api/user_api.dart | 33 + .../lib/src/core/models/channel_config.dart | 4 + .../lib/src/core/models/channel_config.g.dart | 2 + .../lib/src/core/models/channel_model.dart | 3 + .../lib/src/core/models/channel_state.dart | 7 + .../lib/src/core/models/channel_state.g.dart | 5 + .../lib/src/core/models/location.dart | 157 ++++ .../lib/src/core/models/location.g.dart | 39 + .../src/core/models/location_coordinates.dart | 33 + .../lib/src/core/models/message.dart | 16 + .../lib/src/core/models/message.g.dart | 7 +- packages/stream_chat/lib/src/event_type.dart | 12 + packages/stream_chat/lib/stream_chat.dart | 2 + .../test/fixtures/channel_state_to_json.json | 101 +-- .../test/fixtures/message_to_json.json | 2 - .../test/src/client/channel_test.dart | 589 +++++++++++++++ .../test/src/client/client_test.dart | 355 ++++++++++ .../test/src/client/event_resolvers_test.dart | 669 ++++++++++++++++++ .../test/src/core/api/user_api_test.dart | 76 ++ .../src/core/models/channel_state_test.dart | 1 + .../test/src/core/models/location_test.dart | 200 ++++++ .../src/core/util/event_controller_test.dart | 337 +++++++++ .../channel/stream_message_preview_text.dart | 4 + .../lib/src/localization/translations.dart | 11 + .../message_input/quoted_message_widget.dart | 14 +- .../stream_chat_localizations/CHANGELOG.md | 4 + .../example/lib/add_new_lang.dart | 6 + .../lib/src/stream_chat_localizations_ca.dart | 6 + .../lib/src/stream_chat_localizations_de.dart | 6 + .../lib/src/stream_chat_localizations_en.dart | 6 + .../lib/src/stream_chat_localizations_es.dart | 6 + .../lib/src/stream_chat_localizations_fr.dart | 6 + .../lib/src/stream_chat_localizations_hi.dart | 6 + .../lib/src/stream_chat_localizations_it.dart | 6 + .../lib/src/stream_chat_localizations_ja.dart | 6 + .../lib/src/stream_chat_localizations_ko.dart | 6 + .../lib/src/stream_chat_localizations_no.dart | 6 + .../lib/src/stream_chat_localizations_pt.dart | 6 + .../test/translations_test.dart | 2 + .../android/app/src/main/AndroidManifest.xml | 7 + .../ios/Runner.xcodeproj/project.pbxproj | 2 + sample_app/ios/Runner/Info.plist | 19 +- sample_app/lib/pages/channel_list_page.dart | 10 +- sample_app/lib/pages/channel_page.dart | 83 ++- sample_app/lib/pages/thread_page.dart | 18 + sample_app/lib/utils/location_provider.dart | 98 +++ .../lib/utils/shared_location_service.dart | 88 +++ sample_app/lib/widgets/channel_list.dart | 2 +- .../widgets/location/location_attachment.dart | 235 ++++++ .../location/location_detail_dialog.dart | 312 ++++++++ .../location/location_picker_dialog.dart | 362 ++++++++++ .../location/location_picker_option.dart | 74 ++ .../location/location_user_marker.dart | 56 ++ sample_app/lib/widgets/simple_map_view.dart | 153 ++++ .../macos/Flutter/Flutter-Debug.xcconfig | 2 - .../macos/Flutter/Flutter-Release.xcconfig | 2 - .../macos/Runner/DebugProfile.entitlements | 2 + sample_app/macos/Runner/Info.plist | 2 + sample_app/macos/Runner/Release.entitlements | 2 + sample_app/pubspec.yaml | 6 + 67 files changed, 4962 insertions(+), 260 deletions(-) create mode 100644 packages/stream_chat/lib/src/core/models/location.dart create mode 100644 packages/stream_chat/lib/src/core/models/location.g.dart create mode 100644 packages/stream_chat/lib/src/core/models/location_coordinates.dart create mode 100644 packages/stream_chat/test/src/client/event_resolvers_test.dart create mode 100644 packages/stream_chat/test/src/core/models/location_test.dart create mode 100644 packages/stream_chat/test/src/core/util/event_controller_test.dart create mode 100644 sample_app/lib/utils/location_provider.dart create mode 100644 sample_app/lib/utils/shared_location_service.dart create mode 100644 sample_app/lib/widgets/location/location_attachment.dart create mode 100644 sample_app/lib/widgets/location/location_detail_dialog.dart create mode 100644 sample_app/lib/widgets/location/location_picker_dialog.dart create mode 100644 sample_app/lib/widgets/location/location_picker_option.dart create mode 100644 sample_app/lib/widgets/location/location_user_marker.dart create mode 100644 sample_app/lib/widgets/simple_map_view.dart delete mode 100644 sample_app/macos/Flutter/Flutter-Debug.xcconfig delete mode 100644 sample_app/macos/Flutter/Flutter-Release.xcconfig diff --git a/melos.yaml b/melos.yaml index a081ebd3e3..22db60394e 100644 --- a/melos.yaml +++ b/melos.yaml @@ -25,6 +25,7 @@ command: # List of all the dependencies used in the project. dependencies: async: ^2.11.0 + avatar_glow: ^3.0.0 cached_network_image: ^3.3.1 chewie: ^1.8.1 collection: ^1.17.2 @@ -44,6 +45,8 @@ command: file_selector: ^1.0.3 flutter_app_badger: ^1.5.0 flutter_local_notifications: ^18.0.1 + flutter_map: ^8.1.1 + flutter_map_animations: ^0.9.0 flutter_markdown: ^0.7.2+1 flutter_portal: ^1.1.4 flutter_secure_storage: ^9.2.2 @@ -51,6 +54,7 @@ command: flutter_svg: ^2.0.10+1 freezed_annotation: ">=2.4.1 <4.0.0" gal: ^2.3.1 + geolocator: ^13.0.0 get_thumbnail_video: ^0.7.3 go_router: ^14.6.2 http_parser: ^4.0.2 @@ -60,6 +64,7 @@ command: jose: ^0.3.4 json_annotation: ^4.9.0 just_audio: ">=0.9.38 <0.11.0" + latlong2: ^0.9.1 logging: ^1.2.0 lottie: ^3.1.2 media_kit: ^1.1.10+1 diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index abb9ef2b1a..e5226701dc 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,14 @@ +## Upcoming Beta + +✅ Added + +- Added comprehensive location sharing support with static and live location features: + - `Channel.sendStaticLocation()` - Send a static location message to the channel + - `Channel.startLiveLocationSharing()` - Start sharing live location with automatic updates + - `Channel.activeLiveLocations` - Track members active live location shares in the channel + - `Client.activeLiveLocations` - Access current user active live location shares across channels + - Location event listeners for `locationShared`, `locationUpdated`, and `locationExpired` events + ## Upcoming 🐞 Fixed diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 6f42f2bbf8..bab7aa8f3b 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1079,6 +1079,72 @@ class Channel { return _client.deleteDraft(id!, type, parentId: parentId); } + /// Sends a static location to this channel. + /// + /// Optionally, provide a [messageText] and [extraData] to send along with + /// the location. + Future sendStaticLocation({ + String? id, + String? messageText, + String? createdByDeviceId, + required LocationCoordinates location, + Map extraData = const {}, + }) { + final message = Message( + id: id, + text: messageText, + extraData: extraData, + ); + + final currentUserId = _client.state.currentUser?.id; + final locationMessage = message.copyWith( + sharedLocation: Location( + channelCid: cid, + userId: currentUserId, + messageId: message.id, + latitude: location.latitude, + longitude: location.longitude, + createdByDeviceId: createdByDeviceId, + ), + ); + + return sendMessage(locationMessage); + } + + /// Sends a live location sharing message to this channel. + /// + /// Optionally, provide a [messageText] and [extraData] to send along with + /// the location. + Future startLiveLocationSharing({ + String? id, + String? messageText, + String? createdByDeviceId, + required DateTime endSharingAt, + required LocationCoordinates location, + Map extraData = const {}, + }) { + final message = Message( + id: id, + text: messageText, + extraData: extraData, + ); + + final currentUserId = _client.state.currentUser?.id; + final locationMessage = message.copyWith( + sharedLocation: Location( + channelCid: cid, + userId: currentUserId, + messageId: message.id, + endAt: endSharingAt, + latitude: location.latitude, + longitude: location.longitude, + createdByDeviceId: createdByDeviceId, + ), + ); + + return sendMessage(locationMessage); + } + /// Send a file to this channel. Future sendFile( AttachmentFile file, { @@ -1177,7 +1243,7 @@ class Channel { /// Optionally provide a [messageText] to send a message along with the poll. Future sendPoll( Poll poll, { - String messageText = '', + String? messageText, }) async { _checkInitialized(); final res = await _pollLock.synchronized(() => _client.createPoll(poll)); @@ -2090,78 +2156,78 @@ class ChannelClientState { _channelStateController = BehaviorSubject.seeded(channelState); + // region TYPING EVENTS _listenTypingEvents(); + // endregion + // region MESSAGE EVENTS _listenMessageNew(); - _listenMessageDeleted(); - _listenMessageUpdated(); + // endregion - /* Start of draft events */ - + // region DRAFT EVENTS _listenDraftUpdated(); - _listenDraftDeleted(); + // endregion - /* End of draft events */ - - _listenReactions(); - + // region REACTION EVENTS + _listenReactionNew(); + _listenReactionUpdated(); _listenReactionDeleted(); + // endregion - /* Start of poll events */ - + // region POLL EVENTS + _listenPollCreated(); _listenPollUpdated(); - _listenPollClosed(); - _listenPollAnswerCasted(); - _listenPollVoteCasted(); - _listenPollVoteChanged(); - _listenPollAnswerRemoved(); - _listenPollVoteRemoved(); + // endregion - /* End of poll events */ - + // region READ EVENTS _listenReadEvents(); + // endregion + // region CHANNEL EVENTS _listenChannelTruncated(); - _listenChannelUpdated(); + // endregion + // region MEMBER EVENTS _listenMemberAdded(); - _listenMemberRemoved(); - _listenMemberUpdated(); - _listenMemberBanned(); - _listenMemberUnbanned(); + // endregion + // region USER WATCHING EVENTS _listenUserStartWatching(); - _listenUserStopWatching(); + // endregion - /* Start of reminder events */ - + // region REMINDER EVENTS _listenReminderCreated(); - _listenReminderUpdated(); - _listenReminderDeleted(); + // endregion - /* End of reminder events */ + // region LOCATION EVENTS + _listenLocationShared(); + _listenLocationUpdated(); + _listenLocationExpired(); + // endregion _startCleaningStaleTypingEvents(); _startCleaningStalePinnedMessages(); + _startCleaningExpiredLocations(); + _channel._client.chatPersistenceClient ?.getChannelThreads(_channel.cid!) .then((threads) { @@ -2440,6 +2506,17 @@ class ChannelClientState { return threadMessage; } + void _listenPollCreated() { + _subscriptions.add( + _channel.on(EventType.pollCreated).listen((event) { + final message = event.message; + if (message == null || message.poll == null) return; + + return addNewMessage(message); + }), + ); + } + void _listenPollUpdated() { _subscriptions.add(_channel.on(EventType.pollUpdated).listen((event) { final eventPoll = event.poll; @@ -2702,58 +2779,144 @@ class ChannelClientState { } } + Message? _findLocationMessage(String id) { + final message = messages.firstWhereOrNull((it) { + return it.sharedLocation?.messageId == id; + }); + + if (message != null) return message; + + final threadMessage = threads.values.flattened.firstWhereOrNull((it) { + return it.sharedLocation?.messageId == id; + }); + + return threadMessage; + } + + void _listenLocationShared() { + _subscriptions.add( + _channel.on(EventType.locationShared).listen((event) { + final message = event.message; + if (message == null || message.sharedLocation == null) return; + + return addNewMessage(message); + }), + ); + } + + void _listenLocationUpdated() { + _subscriptions.add( + _channel.on(EventType.locationUpdated).listen((event) { + final location = event.message?.sharedLocation; + if (location == null) return; + + final messageId = location.messageId; + if (messageId == null) return; + + final oldMessage = _findLocationMessage(messageId); + if (oldMessage == null) return; + + final updatedMessage = oldMessage.copyWith(sharedLocation: location); + return updateMessage(updatedMessage); + }), + ); + } + + void _listenLocationExpired() { + _subscriptions.add( + _channel.on(EventType.locationExpired).listen((event) { + final location = event.message?.sharedLocation; + if (location == null) return; + + final messageId = location.messageId; + if (messageId == null) return; + + final oldMessage = _findLocationMessage(messageId); + if (oldMessage == null) return; + + final updatedMessage = oldMessage.copyWith(sharedLocation: location); + return updateMessage(updatedMessage); + }), + ); + } + void _listenReactionDeleted() { - _subscriptions.add(_channel.on(EventType.reactionDeleted).listen((event) { - final oldMessage = - messages.firstWhereOrNull((it) => it.id == event.message?.id) ?? - threads[event.message?.parentId] - ?.firstWhereOrNull((e) => e.id == event.message?.id); - final reaction = event.reaction; - final ownReactions = oldMessage?.ownReactions - ?.whereNot((it) => - it.type == reaction?.type && - it.score == reaction?.score && - it.messageId == reaction?.messageId && - it.userId == reaction?.userId && - it.extraData == reaction?.extraData) - .toList(growable: false); - final message = event.message!.copyWith( - ownReactions: ownReactions, - ); - updateMessage(message); - })); + _subscriptions.add( + _channel.on(EventType.reactionDeleted).listen((event) { + final eventMessage = event.message; + if (eventMessage == null) return; + + final reaction = event.reaction; + if (reaction == null) return; + + final messageId = eventMessage.id; + final parentId = eventMessage.parentId; + + for (final message in [...messages, ...?threads[parentId]]) { + if (message.id == messageId) { + final updatedOwnReactions = message.ownReactions?.where((it) { + return it.userId != reaction.userId || it.type != reaction.type; + }); + + return updateMessage( + eventMessage.copyWith( + ownReactions: updatedOwnReactions?.toList(), + ), + ); + } + } + }), + ); } - void _listenReactions() { + void _listenReactionNew() { _subscriptions.add(_channel.on(EventType.reactionNew).listen((event) { - final oldMessage = - messages.firstWhereOrNull((it) => it.id == event.message?.id) ?? - threads[event.message?.parentId] - ?.firstWhereOrNull((e) => e.id == event.message?.id); - final message = event.message!.copyWith( - ownReactions: oldMessage?.ownReactions, - ); - updateMessage(message); + final eventMessage = event.message; + if (eventMessage == null) return; + + final messageId = eventMessage.id; + final parentId = eventMessage.parentId; + + for (final message in [...messages, ...?threads[parentId]]) { + if (message.id == messageId) { + return updateMessage( + eventMessage.copyWith( + ownReactions: message.ownReactions, + ), + ); + } + } })); } + void _listenReactionUpdated() { + _subscriptions.add( + _channel.on(EventType.reactionUpdated).listen((event) { + final eventMessage = event.message; + if (eventMessage == null) return; + + final messageId = eventMessage.id; + final parentId = eventMessage.parentId; + + for (final message in [...messages, ...?threads[parentId]]) { + if (message.id == messageId) { + return updateMessage( + eventMessage.copyWith( + ownReactions: message.ownReactions, + ), + ); + } + } + }), + ); + } + void _listenMessageUpdated() { - _subscriptions.add(_channel - .on( - EventType.messageUpdated, - EventType.reactionUpdated, - ) - .listen((event) { - final oldMessage = - messages.firstWhereOrNull((it) => it.id == event.message?.id) ?? - threads[event.message?.parentId] - ?.firstWhereOrNull((e) => e.id == event.message?.id); - final message = event.message!.copyWith( - poll: oldMessage?.poll, - pollId: oldMessage?.pollId, - ownReactions: oldMessage?.ownReactions, - ); - updateMessage(message); + _subscriptions.add(_channel.on(EventType.messageUpdated).listen((event) { + final message = event.message; + if (message == null) return; + + return updateMessage(message); })); } @@ -2762,7 +2925,7 @@ class ChannelClientState { final message = event.message!; final hardDelete = event.hardDelete ?? false; - deleteMessage(message, hardDelete: hardDelete); + return deleteMessage(message, hardDelete: hardDelete); })); } @@ -2776,19 +2939,22 @@ class ChannelClientState { final message = event.message; if (message == null) return; - final isThreadMessage = message.parentId != null; - final isShownInChannel = message.showInChannel == true; - final isThreadOnlyMessage = isThreadMessage && !isShownInChannel; + return addNewMessage(message); + })); + } - // Only add the message if the channel is upToDate or if the message is - // a thread-only message. - if (isUpToDate || isThreadOnlyMessage) { - updateMessage(message); - } + /// Adds a new message to the channel state and updates the unread count. + void addNewMessage(Message message) { + final isThreadMessage = message.parentId != null; + final isShownInChannel = message.showInChannel == true; + final isThreadOnlyMessage = isThreadMessage && !isShownInChannel; - // Otherwise, check if we can count the message as unread. - if (_countMessageAsUnread(message)) unreadCount += 1; - })); + // Only add the message if the channel is upToDate or if the message is + // a thread-only message. + if (isUpToDate || isThreadOnlyMessage) updateMessage(message); + + // Otherwise, check if we can count the message as unread. + if (_countMessageAsUnread(message)) unreadCount += 1; } // Logic taken from the backend SDK @@ -2920,9 +3086,6 @@ class ChannelClientState { newMessages.add(message); } - // Handle updates to pinned messages. - final newPinnedMessages = _updatePinnedMessages(message); - // Calculate the new last message at time. var lastMessageAt = _channelState.channel?.lastMessageAt; lastMessageAt ??= message.createdAt; @@ -2933,17 +3096,45 @@ class ChannelClientState { // Apply the updated lists to the channel state. _channelState = _channelState.copyWith( messages: newMessages.sorted(_sortByCreatedAt), - pinnedMessages: newPinnedMessages, channel: _channelState.channel?.copyWith( lastMessageAt: lastMessageAt, ), ); } - // If the message is part of a thread, update thread information. + // If the message is part of a thread, update thread message. if (message.parentId case final parentId?) { - updateThreadInfo(parentId, [message]); + _updateThreadMessage(parentId, message); } + + // Handle updates to pinned messages. + final newPinnedMessages = _updatePinnedMessages(message); + + // Handle updates to the active live locations. + final newActiveLiveLocations = _updateActiveLiveLocations(message); + + // Update the channel state with the new pinned messages and + // active live locations. + _channelState = _channelState.copyWith( + pinnedMessages: newPinnedMessages, + activeLiveLocations: newActiveLiveLocations, + ); + } + + void _updateThreadMessage(String parentId, Message message) { + final existingThreadMessages = threads[parentId] ?? []; + final updatedThreadMessages = [ + ...existingThreadMessages.merge( + [message], + key: (it) => it.id, + update: (original, updated) => updated.syncWith(original), + ), + ]; + + _threads = { + ...threads, + parentId: updatedThreadMessages.sorted(_sortByCreatedAt) + }; } /// Cleans up all the stale error messages which requires no action. @@ -2959,70 +3150,122 @@ class ChannelClientState { /// Updates the list of pinned messages based on the current message's /// pinned status. List _updatePinnedMessages(Message message) { - final newPinnedMessages = [...pinnedMessages]; - final oldPinnedIndex = - newPinnedMessages.indexWhere((m) => m.id == message.id); - - if (message.pinned) { - // If the message is pinned, add or update it in the list of pinned - // messages. - if (oldPinnedIndex != -1) { - newPinnedMessages[oldPinnedIndex] = message; - } else { - newPinnedMessages.add(message); - } - } else { - // If the message is not pinned, remove it from the list of pinned - // messages. - newPinnedMessages.removeWhere((m) => m.id == message.id); + final existingPinnedMessages = [...pinnedMessages]; + + // If the message is pinned and not yet deleted, + // merge it into the existing pinned messages. + if (message.pinned && !message.isDeleted) { + final newPinnedMessages = [ + ...existingPinnedMessages.merge( + [message], + key: (it) => it.id, + update: (old, updated) => updated, + ), + ]; + + return newPinnedMessages; } + // Otherwise, remove the message from the pinned messages. + final newPinnedMessages = [ + ...existingPinnedMessages.where((m) => m.id != message.id), + ]; + return newPinnedMessages; } + List _updateActiveLiveLocations(Message message) { + final existingLocations = [...activeLiveLocations]; + + final location = message.sharedLocation; + if (location == null) return existingLocations; + + // If the location is live and active and not yet deleted, + // merge it into the existing active live locations. + if (location.isLive && location.isActive && !message.isDeleted) { + final newActiveLiveLocations = [ + ...existingLocations.merge( + [location], + key: (it) => (it.userId, it.channelCid, it.createdByDeviceId), + update: (old, updated) => updated, + ), + ]; + + return [...newActiveLiveLocations.where((it) => it.isActive)]; + } + + // Otherwise, remove the location from the active live locations. + final newActiveLiveLocations = [ + ...existingLocations.where((it) => it.messageId != location.messageId), + ]; + + return [...newActiveLiveLocations.where((it) => it.isActive)]; + } + /// Remove a [message] from this [channelState]. void removeMessage(Message message) async { await _channel._client.chatPersistenceClient?.deleteMessageById(message.id); - final parentId = message.parentId; - // i.e. it's a thread message, Remove it - if (parentId != null) { - final newThreads = {...threads}; - // Early return in case the thread is not available - if (!newThreads.containsKey(parentId)) return; - - // Remove thread message shown in thread page. - newThreads.update( - parentId, - (messages) => [...messages.where((e) => e.id != message.id)], - ); + if (message.parentId == null || message.showInChannel == true) { + // Remove regular message, thread message shown in channel + var updatedMessages = [...messages.where((e) => e.id != message.id)]; - _threads = newThreads; + // Remove quoted message reference from every message if available. + updatedMessages = [ + ...updatedMessages.map((it) { + // Early return if the message doesn't have a quoted message. + if (it.quotedMessageId != message.id) return it; - // Early return if the thread message is not shown in channel. - if (message.showInChannel == false) return; + // Setting it to null will remove the quoted message from the message. + return it.copyWith(quotedMessage: null, quotedMessageId: null); + }), + ]; + + _channelState = _channelState.copyWith( + messages: updatedMessages.sorted(_sortByCreatedAt), + ); } - // Remove regular message, thread message shown in channel - var updatedMessages = [...messages]..removeWhere((e) => e.id == message.id); + if (message.parentId case final parentId?) { + // If the message is a thread message, remove it from the threads. + _removeThreadMessage(message, parentId); + } - // Remove quoted message reference from every message if available. - updatedMessages = [...updatedMessages].map((it) { - // Early return if the message doesn't have a quoted message. - if (it.quotedMessageId != message.id) return it; + // If the message is pinned, remove it from the pinned messages. + final updatedPinnedMessages = [ + ...pinnedMessages.where((it) => it.id != message.id), + ]; - // Setting it to null will remove the quoted message from the message. - return it.copyWith( - quotedMessage: null, - quotedMessageId: null, - ); - }).toList(); + // If the message is a live location, update the active live locations. + final updatedActiveLiveLocations = [ + ...activeLiveLocations.where((it) => it.messageId != message.id), + ]; _channelState = _channelState.copyWith( - messages: updatedMessages, + pinnedMessages: updatedPinnedMessages, + activeLiveLocations: updatedActiveLiveLocations, ); } + void _removeThreadMessage(Message message, String parentId) { + final existingThreadMessages = threads[parentId] ?? []; + final updatedThreadMessages = [ + ...existingThreadMessages.where((it) => it.id != message.id), + ]; + + // If there are no more messages in the thread, remove the thread entry. + if (updatedThreadMessages.isEmpty) { + _threads = {...threads}..remove(parentId); + return; + } + + // Otherwise, update the thread messages. + _threads = { + ...threads, + parentId: updatedThreadMessages.sorted(_sortByCreatedAt), + }; + } + /// Removes/Updates the [message] based on the [hardDelete] value. void deleteMessage(Message message, {bool hardDelete = false}) { if (hardDelete) return removeMessage(message); @@ -3135,6 +3378,16 @@ class ChannelClientState { (watchers, users) => [...?watchers?.map((e) => users[e.id] ?? e)], ).distinct(const ListEquality().equals); + /// Channel active live locations. + List get activeLiveLocations { + return _channelState.activeLiveLocations ?? []; + } + + /// Channel active live locations as a stream. + Stream> get activeLiveLocationsStream => channelStateStream + .map((cs) => cs.activeLiveLocations ?? []) + .distinct(const ListEquality().equals); + /// Channel draft. Draft? get draft => _channelState.draft; @@ -3303,6 +3556,7 @@ class ChannelClientState { read: newReads, draft: updatedState.draft, pinnedMessages: updatedState.pinnedMessages, + activeLiveLocations: updatedState.activeLiveLocations, ); } @@ -3342,19 +3596,19 @@ class ChannelClientState { /// Update threads with updated information about messages. void updateThreadInfo(String parentId, List messages) { - final newThreads = {...threads}..update( - parentId, - (original) => [ - ...original.merge( - messages, - key: (message) => message.id, - update: (original, updated) => updated.syncWith(original), - ), - ].sorted(_sortByCreatedAt), - ifAbsent: () => messages.sorted(_sortByCreatedAt), - ); + final existingThreadMessages = threads[parentId] ?? []; + final updatedThreadMessages = [ + ...existingThreadMessages.merge( + messages, + key: (it) => it.id, + update: (original, updated) => updated.syncWith(original), + ), + ]; - _threads = newThreads; + _threads = { + ...threads, + parentId: updatedThreadMessages.sorted(_sortByCreatedAt) + }; } Draft? _getThreadDraft(String parentId, List? messages) { @@ -3469,6 +3723,42 @@ class ChannelClientState { ); } + Timer? _staleLiveLocationsCleanerTimer; + void _startCleaningExpiredLocations() { + _staleLiveLocationsCleanerTimer?.cancel(); + _staleLiveLocationsCleanerTimer = Timer.periodic( + const Duration(seconds: 1), + (_) { + final currentUserId = _channel._client.state.currentUser?.id; + if (currentUserId == null) return; + + final expired = activeLiveLocations.where((it) => it.isExpired); + if (expired.isEmpty) return; + + for (final sharedLocation in expired) { + // Skip if the location is shared by the current user, + // as we are already handling them in the client. + if (sharedLocation.userId == currentUserId) continue; + + final lastUpdatedAt = DateTime.timestamp(); + final locationExpiredEvent = Event( + type: EventType.locationExpired, + cid: sharedLocation.channelCid, + message: Message( + id: sharedLocation.messageId, + updatedAt: lastUpdatedAt, + sharedLocation: sharedLocation.copyWith( + updatedAt: lastUpdatedAt, + ), + ), + ); + + _channel._client.handleEvent(locationExpiredEvent); + } + }, + ); + } + /// Call this method to dispose this object. void dispose() { _debouncedUpdatePersistenceChannelState.cancel(); @@ -3479,6 +3769,7 @@ class ChannelClientState { _threadsController.close(); _staleTypingEventsCleanerTimer?.cancel(); _stalePinnedMessagesCleanerTimer?.cancel(); + _staleLiveLocationsCleanerTimer?.cancel(); _typingEventsController.close(); } } @@ -3670,4 +3961,9 @@ extension ChannelCapabilityCheck on Channel { bool get canQueryPollVotes { return ownCapabilities.contains(ChannelCapability.queryPollVotes); } + + /// True, if the current user can share location in the channel. + bool get canShareLocation { + return ownCapabilities.contains(ChannelCapability.shareLocation); + } } diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index e8697be6f6..e059436ff8 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -25,6 +25,8 @@ import 'package:stream_chat/src/core/models/draft.dart'; import 'package:stream_chat/src/core/models/draft_message.dart'; import 'package:stream_chat/src/core/models/event.dart'; import 'package:stream_chat/src/core/models/filter.dart'; +import 'package:stream_chat/src/core/models/location.dart'; +import 'package:stream_chat/src/core/models/location_coordinates.dart'; import 'package:stream_chat/src/core/models/member.dart'; import 'package:stream_chat/src/core/models/message.dart'; import 'package:stream_chat/src/core/models/message_reminder.dart'; @@ -35,6 +37,7 @@ import 'package:stream_chat/src/core/models/poll_vote.dart'; import 'package:stream_chat/src/core/models/thread.dart'; import 'package:stream_chat/src/core/models/user.dart'; import 'package:stream_chat/src/core/util/event_controller.dart'; +import 'package:stream_chat/src/core/util/extension.dart'; import 'package:stream_chat/src/core/util/utils.dart'; import 'package:stream_chat/src/db/chat_persistence_client.dart'; import 'package:stream_chat/src/event_type.dart'; @@ -229,8 +232,12 @@ class StreamChatClient { Stream get eventStream => _eventController.stream; late final _eventController = EventController( resolvers: [ + event_resolvers.pollCreatedResolver, event_resolvers.pollAnswerCastedResolver, event_resolvers.pollAnswerRemovedResolver, + event_resolvers.locationSharedResolver, + event_resolvers.locationUpdatedResolver, + event_resolvers.locationExpiredResolver, ], ); @@ -1765,6 +1772,51 @@ class StreamChatClient { pagination: pagination, ); + /// Retrieves all the active live locations of the current user. + Future getActiveLiveLocations() async { + try { + final response = await _chatApi.user.getActiveLiveLocations(); + + // Update the active live locations in the state. + final activeLiveLocations = response.activeLiveLocations; + state.activeLiveLocations = activeLiveLocations; + + return response; + } catch (e, stk) { + logger.severe('Error getting active live locations', e, stk); + rethrow; + } + } + + /// Updates an existing live location created by the current user. + Future updateLiveLocation({ + required String messageId, + String? createdByDeviceId, + LocationCoordinates? location, + DateTime? endAt, + }) { + return _chatApi.user.updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + location: location, + endAt: endAt, + ); + } + + /// Expire an existing live location created by the current user. + Future stopLiveLocation({ + required String messageId, + String? createdByDeviceId, + }) { + return updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + // Passing the current time as endAt will mark the location as expired + // and make it inactive. + endAt: DateTime.timestamp(), + ); + } + /// Enables slow mode Future enableSlowdown( String channelId, @@ -2072,15 +2124,27 @@ class ClientState { }), ); + // region CHANNEL EVENTS _listenChannelLeft(); - _listenChannelDeleted(); - _listenChannelHidden(); + // endregion + // region USER EVENTS _listenUserUpdated(); + // endregion + // region READ EVENTS _listenAllChannelsRead(); + // endregion + + // region LOCATION EVENTS + _listenLocationShared(); + _listenLocationUpdated(); + _listenLocationExpired(); + // endregion + + _startCleaningExpiredLocations(); } /// Stops listening to the client events. @@ -2168,6 +2232,103 @@ class ClientState { ); } + void _listenLocationShared() { + _eventsSubscription?.add( + _client.on(EventType.locationShared).listen((event) { + final location = event.message?.sharedLocation; + if (location == null || location.isStatic) return; + + final currentUserId = currentUser?.id; + if (currentUserId == null) return; + if (location.userId != currentUserId) return; + + final newActiveLiveLocations = [ + ...activeLiveLocations.merge( + [location], + key: (it) => (it.userId, it.channelCid, it.createdByDeviceId), + update: (original, updated) => updated, + ), + ]; + + activeLiveLocations = newActiveLiveLocations; + }), + ); + } + + void _listenLocationUpdated() { + _eventsSubscription?.add( + _client.on(EventType.locationUpdated).listen((event) { + final location = event.message?.sharedLocation; + if (location == null || location.isStatic) return; + + final currentUserId = currentUser?.id; + if (currentUserId == null) return; + if (location.userId != currentUserId) return; + + final newActiveLiveLocations = [ + ...activeLiveLocations.merge( + [location], + key: (it) => (it.userId, it.channelCid, it.createdByDeviceId), + update: (original, updated) => updated, + ), + ]; + + activeLiveLocations = newActiveLiveLocations; + }), + ); + } + + void _listenLocationExpired() { + _eventsSubscription?.add( + _client.on(EventType.locationExpired).listen((event) { + final location = event.message?.sharedLocation; + if (location == null || location.isStatic) return; + + final currentUserId = currentUser?.id; + if (currentUserId == null) return; + if (location.userId != currentUserId) return; + + final newActiveLiveLocations = [ + ...activeLiveLocations.where( + (it) => it.messageId != location.messageId, + ) + ]; + + activeLiveLocations = newActiveLiveLocations; + }), + ); + } + + Timer? _staleLiveLocationsCleanerTimer; + void _startCleaningExpiredLocations() { + _staleLiveLocationsCleanerTimer?.cancel(); + _staleLiveLocationsCleanerTimer = Timer.periodic( + const Duration(seconds: 1), + (_) { + final expired = activeLiveLocations.where((it) => it.isExpired); + if (expired.isEmpty) return; + + for (final sharedLocation in expired) { + final lastUpdatedAt = DateTime.timestamp(); + + final locationExpiredEvent = Event( + type: EventType.locationExpired, + cid: sharedLocation.channelCid, + message: Message( + id: sharedLocation.messageId, + updatedAt: lastUpdatedAt, + sharedLocation: sharedLocation.copyWith( + updatedAt: lastUpdatedAt, + ), + ), + ); + + _client.handleEvent(locationExpiredEvent); + } + }, + ); + } + final StreamChatClient _client; /// Sets the user currently interacting with the client @@ -2202,6 +2363,23 @@ class ClientState { /// The current user as a stream Stream> get usersStream => _usersController.stream; + /// The current active live locations shared by the user. + List get activeLiveLocations { + return _activeLiveLocationsController.value; + } + + /// The current active live locations shared by the user as a stream. + Stream> get activeLiveLocationsStream { + return _activeLiveLocationsController.stream; + } + + /// Sets the active live locations. + set activeLiveLocations(List locations) { + // For safe-keeping, we filter out any inactive locations before update. + final activeLocations = [...locations.where((it) => it.isActive)]; + _activeLiveLocationsController.add(activeLocations); + } + /// The current unread channels count int get unreadChannels => _unreadChannelsController.value; @@ -2274,14 +2452,18 @@ class ClientState { final _unreadChannelsController = BehaviorSubject.seeded(0); final _unreadThreadsController = BehaviorSubject.seeded(0); final _totalUnreadCountController = BehaviorSubject.seeded(0); + final _activeLiveLocationsController = BehaviorSubject.seeded([]); /// Call this method to dispose this object void dispose() { cancelEventSubscription(); _currentUserController.close(); + _usersController.close(); _unreadChannelsController.close(); _unreadThreadsController.close(); _totalUnreadCountController.close(); + _activeLiveLocationsController.close(); + _staleLiveLocationsCleanerTimer?.cancel(); final channels = [...this.channels.keys]; for (final channel in channels) { diff --git a/packages/stream_chat/lib/src/client/event_resolvers.dart b/packages/stream_chat/lib/src/client/event_resolvers.dart index fc2117fb58..6f462f6260 100644 --- a/packages/stream_chat/lib/src/client/event_resolvers.dart +++ b/packages/stream_chat/lib/src/client/event_resolvers.dart @@ -1,6 +1,27 @@ import 'package:stream_chat/src/core/models/event.dart'; import 'package:stream_chat/src/event_type.dart'; +/// Resolves message new events into more specific `pollCreated` events +/// for easier downstream state handling. +/// +/// Applies when: +/// - `event.type` is `messageNew` or `notification.message_new, and +/// - `event.poll` is not null +/// +/// Returns a modified event with type `pollCreated`, +/// or `null` if not applicable. +Event? pollCreatedResolver(Event event) { + final validTypes = {EventType.messageNew, EventType.notificationMessageNew}; + if (!validTypes.contains(event.type)) return null; + + final poll = event.poll; + if (poll == null) return null; + + // If the event is a message new or notification message new and + // it contains a poll, we can resolve it to a poll created event. + return event.copyWith(type: EventType.pollCreated); +} + /// Resolves casted or changed poll vote events into more specific /// `pollAnswerCasted` events for easier downstream state handling. /// @@ -11,12 +32,15 @@ import 'package:stream_chat/src/event_type.dart'; /// Returns a modified event with type `pollAnswerCasted`, /// or `null` if not applicable. Event? pollAnswerCastedResolver(Event event) { - return switch (event.type) { - EventType.pollVoteCasted || - EventType.pollVoteChanged when event.pollVote?.isAnswer == true => - event.copyWith(type: EventType.pollAnswerCasted), - _ => null, - }; + final validTypes = {EventType.pollVoteCasted, EventType.pollVoteChanged}; + if (!validTypes.contains(event.type)) return null; + + final pollVote = event.pollVote; + if (pollVote?.isAnswer == false) return null; + + // If the event is a poll vote casted or changed and it's an answer + // we can resolve it to a poll answer casted event. + return event.copyWith(type: EventType.pollAnswerCasted); } /// Resolves removed poll vote events into more specific @@ -29,9 +53,77 @@ Event? pollAnswerCastedResolver(Event event) { /// Returns a modified event with type `pollAnswerRemoved`, /// or `null` if not applicable. Event? pollAnswerRemovedResolver(Event event) { - return switch (event.type) { - EventType.pollVoteRemoved when event.pollVote?.isAnswer == true => - event.copyWith(type: EventType.pollAnswerRemoved), - _ => null, - }; + if (event.type != EventType.pollVoteRemoved) return null; + + final pollVote = event.pollVote; + if (pollVote?.isAnswer == false) return null; + + // If the event is a poll vote removed and it's an answer + // we can resolve it to a poll answer removed event. + return event.copyWith(type: EventType.pollAnswerRemoved); +} + +/// Resolves message new events into more specific `locationShared` events +/// for easier downstream state handling. +/// +/// Applies when: +/// - `event.type` is `messageNew` or `notification.message_new, and +/// - `event.message.sharedLocation` is not null +/// +/// Returns a modified event with type `locationShared`, +/// or `null` if not applicable. +Event? locationSharedResolver(Event event) { + final validTypes = {EventType.messageNew, EventType.notificationMessageNew}; + if (!validTypes.contains(event.type)) return null; + + final sharedLocation = event.message?.sharedLocation; + if (sharedLocation == null) return null; + + // If the event is a message new or notification message new and it + // contains a shared location, we can resolve it to a location shared event. + return event.copyWith(type: EventType.locationShared); +} + +/// Resolves message updated events into more specific `locationUpdated` +/// events for easier downstream state handling. +/// +/// Applies when: +/// - `event.type` is `messageUpdated`, and +/// - `event.message.sharedLocation` is not null and not expired +/// +/// Returns a modified event with type `locationUpdated`, +/// or `null` if not applicable. +Event? locationUpdatedResolver(Event event) { + if (event.type != EventType.messageUpdated) return null; + + final sharedLocation = event.message?.sharedLocation; + if (sharedLocation == null) return null; + + if (sharedLocation.isLive && sharedLocation.isExpired) return null; + + // If the location is static or still active, we can resolve it + // to a location updated event. + return event.copyWith(type: EventType.locationUpdated); +} + +/// Resolves message updated events into more specific `locationExpired` +/// events for easier downstream state handling. +/// +/// Applies when: +/// - `event.type` is `messageUpdated`, and +/// - `event.message.sharedLocation` is not null and expired +/// +/// Returns a modified event with type `locationExpired`, +/// or `null` if not applicable. +Event? locationExpiredResolver(Event event) { + if (event.type != EventType.messageUpdated) return null; + + final sharedLocation = event.message?.sharedLocation; + if (sharedLocation == null) return null; + + if (sharedLocation.isStatic || sharedLocation.isActive) return null; + + // If the location is live and expired, we can resolve it to a + // location expired event. + return event.copyWith(type: EventType.locationExpired); } diff --git a/packages/stream_chat/lib/src/core/api/responses.dart b/packages/stream_chat/lib/src/core/api/responses.dart index 80ea1a653f..7bc2cfc616 100644 --- a/packages/stream_chat/lib/src/core/api/responses.dart +++ b/packages/stream_chat/lib/src/core/api/responses.dart @@ -7,6 +7,7 @@ import 'package:stream_chat/src/core/models/channel_state.dart'; import 'package:stream_chat/src/core/models/device.dart'; import 'package:stream_chat/src/core/models/draft.dart'; import 'package:stream_chat/src/core/models/event.dart'; +import 'package:stream_chat/src/core/models/location.dart'; import 'package:stream_chat/src/core/models/member.dart'; import 'package:stream_chat/src/core/models/message.dart'; import 'package:stream_chat/src/core/models/message_reminder.dart'; @@ -797,3 +798,14 @@ class GetUnreadCountResponse extends _BaseResponse { static GetUnreadCountResponse fromJson(Map json) => _$GetUnreadCountResponseFromJson(json); } + +/// Model response for [StreamChatClient.updateDraft] api call +@JsonSerializable(createToJson: false) +class GetActiveLiveLocationsResponse extends _BaseResponse { + /// List of active live locations returned by the api call + late List activeLiveLocations; + + /// Create a new instance from a json + static GetActiveLiveLocationsResponse fromJson(Map json) => + _$GetActiveLiveLocationsResponseFromJson(json); +} diff --git a/packages/stream_chat/lib/src/core/api/responses.g.dart b/packages/stream_chat/lib/src/core/api/responses.g.dart index 29f91d56b1..a8cc26f578 100644 --- a/packages/stream_chat/lib/src/core/api/responses.g.dart +++ b/packages/stream_chat/lib/src/core/api/responses.g.dart @@ -475,3 +475,11 @@ GetUnreadCountResponse _$GetUnreadCountResponseFromJson( ..threads = (json['threads'] as List) .map((e) => UnreadCountsThread.fromJson(e as Map)) .toList(); + +GetActiveLiveLocationsResponse _$GetActiveLiveLocationsResponseFromJson( + Map json) => + GetActiveLiveLocationsResponse() + ..duration = json['duration'] as String? + ..activeLiveLocations = (json['active_live_locations'] as List) + .map((e) => Location.fromJson(e as Map)) + .toList(); diff --git a/packages/stream_chat/lib/src/core/api/user_api.dart b/packages/stream_chat/lib/src/core/api/user_api.dart index 064792bfe4..668e7ac70a 100644 --- a/packages/stream_chat/lib/src/core/api/user_api.dart +++ b/packages/stream_chat/lib/src/core/api/user_api.dart @@ -5,6 +5,8 @@ import 'package:stream_chat/src/core/api/responses.dart'; import 'package:stream_chat/src/core/api/sort_order.dart'; import 'package:stream_chat/src/core/http/stream_http_client.dart'; import 'package:stream_chat/src/core/models/filter.dart'; +import 'package:stream_chat/src/core/models/location.dart'; +import 'package:stream_chat/src/core/models/location_coordinates.dart'; import 'package:stream_chat/src/core/models/user.dart'; /// Defines the api dedicated to users operations @@ -95,4 +97,35 @@ class UserApi { return GetUnreadCountResponse.fromJson(response.data); } + + /// Retrieves all the active live locations of the current user. + Future getActiveLiveLocations() async { + final response = await _client.get( + '/users/live_locations', + ); + + return GetActiveLiveLocationsResponse.fromJson(response.data); + } + + /// Updates an existing live location created by the current user. + Future updateLiveLocation({ + required String messageId, + String? createdByDeviceId, + LocationCoordinates? location, + DateTime? endAt, + }) async { + final response = await _client.put( + '/users/live_locations', + data: json.encode({ + 'message_id': messageId, + if (createdByDeviceId != null) + 'created_by_device_id': createdByDeviceId, + if (location?.latitude case final latitude) 'latitude': latitude, + if (location?.longitude case final longitude) 'longitude': longitude, + if (endAt != null) 'end_at': endAt.toIso8601String(), + }), + ); + + return Location.fromJson(response.data); + } } diff --git a/packages/stream_chat/lib/src/core/models/channel_config.dart b/packages/stream_chat/lib/src/core/models/channel_config.dart index 2bcf0a1ed5..489b71e334 100644 --- a/packages/stream_chat/lib/src/core/models/channel_config.dart +++ b/packages/stream_chat/lib/src/core/models/channel_config.dart @@ -26,6 +26,7 @@ class ChannelConfig { this.urlEnrichment = false, this.skipLastMsgUpdateForSystemMsgs = false, this.userMessageReminders = false, + this.sharedLocations = false, }) : createdAt = createdAt ?? DateTime.now(), updatedAt = updatedAt ?? DateTime.now(); @@ -91,6 +92,9 @@ class ChannelConfig { /// True if the user can set reminders for messages in this channel. final bool userMessageReminders; + /// True if shared locations are enabled for this channel. + final bool sharedLocations; + /// Serialize to json Map toJson() => _$ChannelConfigToJson(this); } diff --git a/packages/stream_chat/lib/src/core/models/channel_config.g.dart b/packages/stream_chat/lib/src/core/models/channel_config.g.dart index 8cb758b875..1a57d3e743 100644 --- a/packages/stream_chat/lib/src/core/models/channel_config.g.dart +++ b/packages/stream_chat/lib/src/core/models/channel_config.g.dart @@ -34,6 +34,7 @@ ChannelConfig _$ChannelConfigFromJson(Map json) => skipLastMsgUpdateForSystemMsgs: json['skip_last_msg_update_for_system_msgs'] as bool? ?? false, userMessageReminders: json['user_message_reminders'] as bool? ?? false, + sharedLocations: json['shared_locations'] as bool? ?? false, ); Map _$ChannelConfigToJson(ChannelConfig instance) => @@ -57,4 +58,5 @@ Map _$ChannelConfigToJson(ChannelConfig instance) => 'skip_last_msg_update_for_system_msgs': instance.skipLastMsgUpdateForSystemMsgs, 'user_message_reminders': instance.userMessageReminders, + 'shared_locations': instance.sharedLocations, }; diff --git a/packages/stream_chat/lib/src/core/models/channel_model.dart b/packages/stream_chat/lib/src/core/models/channel_model.dart index d55f0e42b5..49a3c99bf2 100644 --- a/packages/stream_chat/lib/src/core/models/channel_model.dart +++ b/packages/stream_chat/lib/src/core/models/channel_model.dart @@ -366,4 +366,7 @@ extension type const ChannelCapability(String capability) implements String { /// Ability to query poll votes. static const queryPollVotes = ChannelCapability('query-poll-votes'); + + /// Ability to share location. + static const shareLocation = ChannelCapability('share-location'); } diff --git a/packages/stream_chat/lib/src/core/models/channel_state.dart b/packages/stream_chat/lib/src/core/models/channel_state.dart index ae7b9062b6..3e06a86d79 100644 --- a/packages/stream_chat/lib/src/core/models/channel_state.dart +++ b/packages/stream_chat/lib/src/core/models/channel_state.dart @@ -2,6 +2,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:stream_chat/src/core/models/channel_model.dart'; import 'package:stream_chat/src/core/models/comparable_field.dart'; import 'package:stream_chat/src/core/models/draft.dart'; +import 'package:stream_chat/src/core/models/location.dart'; import 'package:stream_chat/src/core/models/member.dart'; import 'package:stream_chat/src/core/models/message.dart'; import 'package:stream_chat/src/core/models/read.dart'; @@ -29,6 +30,7 @@ class ChannelState implements ComparableFieldProvider { this.read, this.membership, this.draft, + this.activeLiveLocations, }); /// The channel to which this state belongs @@ -58,6 +60,9 @@ class ChannelState implements ComparableFieldProvider { /// The draft message for this channel if it exists. final Draft? draft; + /// The list of active live locations in the channel. + final List? activeLiveLocations; + /// Create a new instance from a json static ChannelState fromJson(Map json) => _$ChannelStateFromJson(json); @@ -76,6 +81,7 @@ class ChannelState implements ComparableFieldProvider { List? read, Member? membership, Object? draft = _nullConst, + List? activeLiveLocations, }) => ChannelState( channel: channel ?? this.channel, @@ -87,6 +93,7 @@ class ChannelState implements ComparableFieldProvider { read: read ?? this.read, membership: membership ?? this.membership, draft: draft == _nullConst ? this.draft : draft as Draft?, + activeLiveLocations: activeLiveLocations ?? this.activeLiveLocations, ); @override diff --git a/packages/stream_chat/lib/src/core/models/channel_state.g.dart b/packages/stream_chat/lib/src/core/models/channel_state.g.dart index 88bd81e77e..99d5098b2e 100644 --- a/packages/stream_chat/lib/src/core/models/channel_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/channel_state.g.dart @@ -32,6 +32,9 @@ ChannelState _$ChannelStateFromJson(Map json) => ChannelState( draft: json['draft'] == null ? null : Draft.fromJson(json['draft'] as Map), + activeLiveLocations: (json['active_live_locations'] as List?) + ?.map((e) => Location.fromJson(e as Map)) + .toList(), ); Map _$ChannelStateToJson(ChannelState instance) => @@ -46,4 +49,6 @@ Map _$ChannelStateToJson(ChannelState instance) => 'read': instance.read?.map((e) => e.toJson()).toList(), 'membership': instance.membership?.toJson(), 'draft': instance.draft?.toJson(), + 'active_live_locations': + instance.activeLiveLocations?.map((e) => e.toJson()).toList(), }; diff --git a/packages/stream_chat/lib/src/core/models/location.dart b/packages/stream_chat/lib/src/core/models/location.dart new file mode 100644 index 0000000000..008ab6390d --- /dev/null +++ b/packages/stream_chat/lib/src/core/models/location.dart @@ -0,0 +1,157 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:stream_chat/src/core/models/channel_model.dart'; +import 'package:stream_chat/src/core/models/location_coordinates.dart'; +import 'package:stream_chat/src/core/models/message.dart'; + +part 'location.g.dart'; + +/// {@template location} +/// A model class representing a shared location. +/// +/// The [Location] represents a location shared in a channel message. +/// +/// It can be of two types: +/// 1. **Static Location**: A location that does not change over time and has +/// no end time. +/// 2. **Live Location**: A location that updates in real-time and has an +/// end time. +/// {@endtemplate} +@JsonSerializable() +class Location extends Equatable { + /// {@macro location} + Location({ + this.channelCid, + this.channel, + this.messageId, + this.message, + this.userId, + required this.latitude, + required this.longitude, + this.createdByDeviceId, + this.endAt, + DateTime? createdAt, + DateTime? updatedAt, + }) : createdAt = createdAt ?? DateTime.timestamp(), + updatedAt = updatedAt ?? DateTime.timestamp(); + + /// Create a new instance from a json + factory Location.fromJson(Map json) => + _$LocationFromJson(json); + + /// The channel CID where the message exists. + /// + /// This is only available if the location is coming from server response. + @JsonKey(includeToJson: false) + final String? channelCid; + + /// The channel where the message exists. + @JsonKey(includeToJson: false) + final ChannelModel? channel; + + /// The ID of the message that contains the shared location. + @JsonKey(includeToJson: false) + final String? messageId; + + /// The message that contains the shared location. + @JsonKey(includeToJson: false) + final Message? message; + + /// The ID of the user who shared the location. + @JsonKey(includeToJson: false) + final String? userId; + + /// The latitude of the shared location. + final double latitude; + + /// The longitude of the shared location. + final double longitude; + + /// The ID of the device that created the reminder. + @JsonKey(includeIfNull: false) + final String? createdByDeviceId; + + /// The date at which the shared location will end. + @JsonKey(includeIfNull: false) + final DateTime? endAt; + + /// The date at which the reminder was created. + @JsonKey(includeToJson: false) + final DateTime createdAt; + + /// The date at which the reminder was last updated. + @JsonKey(includeToJson: false) + final DateTime updatedAt; + + /// Returns true if the live location is still active (end_at > now) + bool get isActive { + final endAt = this.endAt; + if (endAt == null) return false; + + return endAt.isAfter(DateTime.now()); + } + + /// Returns true if the live location is expired (end_at <= now) + bool get isExpired => !isActive; + + /// Returns true if this is a live location (has end_at) + bool get isLive => endAt != null; + + /// Returns true if this is a static location (no end_at) + bool get isStatic => endAt == null; + + /// Returns the coordinates of the shared location. + LocationCoordinates get coordinates { + return LocationCoordinates( + latitude: latitude, + longitude: longitude, + ); + } + + /// Serialize to json + Map toJson() => _$LocationToJson(this); + + /// Creates a copy of [Location] with specified attributes overridden. + Location copyWith({ + String? channelCid, + ChannelModel? channel, + String? messageId, + Message? message, + String? userId, + double? latitude, + double? longitude, + String? createdByDeviceId, + DateTime? endAt, + DateTime? createdAt, + DateTime? updatedAt, + }) { + return Location( + channelCid: channelCid ?? this.channelCid, + channel: channel ?? this.channel, + messageId: messageId ?? this.messageId, + message: message ?? this.message, + userId: userId ?? this.userId, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + createdByDeviceId: createdByDeviceId ?? this.createdByDeviceId, + endAt: endAt ?? this.endAt, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ); + } + + @override + List get props => [ + channelCid, + channel, + messageId, + message, + userId, + latitude, + longitude, + createdByDeviceId, + endAt, + createdAt, + updatedAt, + ]; +} diff --git a/packages/stream_chat/lib/src/core/models/location.g.dart b/packages/stream_chat/lib/src/core/models/location.g.dart new file mode 100644 index 0000000000..e1fac9ac92 --- /dev/null +++ b/packages/stream_chat/lib/src/core/models/location.g.dart @@ -0,0 +1,39 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'location.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Location _$LocationFromJson(Map json) => Location( + channelCid: json['channel_cid'] as String?, + channel: json['channel'] == null + ? null + : ChannelModel.fromJson(json['channel'] as Map), + messageId: json['message_id'] as String?, + message: json['message'] == null + ? null + : Message.fromJson(json['message'] as Map), + userId: json['user_id'] as String?, + latitude: (json['latitude'] as num).toDouble(), + longitude: (json['longitude'] as num).toDouble(), + createdByDeviceId: json['created_by_device_id'] as String?, + endAt: json['end_at'] == null + ? null + : DateTime.parse(json['end_at'] as String), + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), + ); + +Map _$LocationToJson(Location instance) => { + 'latitude': instance.latitude, + 'longitude': instance.longitude, + if (instance.createdByDeviceId case final value?) + 'created_by_device_id': value, + if (instance.endAt?.toIso8601String() case final value?) 'end_at': value, + }; diff --git a/packages/stream_chat/lib/src/core/models/location_coordinates.dart b/packages/stream_chat/lib/src/core/models/location_coordinates.dart new file mode 100644 index 0000000000..f23389d7e6 --- /dev/null +++ b/packages/stream_chat/lib/src/core/models/location_coordinates.dart @@ -0,0 +1,33 @@ +import 'package:equatable/equatable.dart'; + +/// {@template locationInfo} +/// A model class representing a location with latitude and longitude. +/// {@endtemplate} +class LocationCoordinates extends Equatable { + /// {@macro locationInfo} + const LocationCoordinates({ + required this.latitude, + required this.longitude, + }); + + /// The latitude of the location. + final double latitude; + + /// The longitude of the location. + final double longitude; + + /// Creates a copy of [LocationCoordinates] with specified attributes + /// overridden. + LocationCoordinates copyWith({ + double? latitude, + double? longitude, + }) { + return LocationCoordinates( + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + ); + } + + @override + List get props => [latitude, longitude]; +} diff --git a/packages/stream_chat/lib/src/core/models/message.dart b/packages/stream_chat/lib/src/core/models/message.dart index de5143b242..150224031c 100644 --- a/packages/stream_chat/lib/src/core/models/message.dart +++ b/packages/stream_chat/lib/src/core/models/message.dart @@ -4,6 +4,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:stream_chat/src/core/models/attachment.dart'; import 'package:stream_chat/src/core/models/comparable_field.dart'; import 'package:stream_chat/src/core/models/draft.dart'; +import 'package:stream_chat/src/core/models/location.dart'; import 'package:stream_chat/src/core/models/message_reminder.dart'; import 'package:stream_chat/src/core/models/message_state.dart'; import 'package:stream_chat/src/core/models/moderation.dart'; @@ -65,6 +66,7 @@ class Message extends Equatable implements ComparableFieldProvider { this.moderation, this.draft, this.reminder, + this.sharedLocation, }) : id = id ?? const Uuid().v4(), type = MessageType(type), pinExpires = pinExpires?.toUtc(), @@ -293,13 +295,22 @@ class Message extends Equatable implements ComparableFieldProvider { /// Optional draft message linked to this message. /// /// This is present when the message is a thread i.e. contains replies. + @JsonKey(includeToJson: false) final Draft? draft; /// Optional reminder for this message. /// /// This is present when a user has set a reminder for this message. + @JsonKey(includeToJson: false) final MessageReminder? reminder; + /// Optional shared location associated with this message. + /// + /// This is used to share a location in a message, allowing users to view the + /// location on a map. + @JsonKey(includeIfNull: false) + final Location? sharedLocation; + /// Message custom extraData. final Map extraData; @@ -348,6 +359,7 @@ class Message extends Equatable implements ComparableFieldProvider { 'moderation_details', 'draft', 'reminder', + 'shared_location', ]; /// Serialize to json. @@ -406,6 +418,7 @@ class Message extends Equatable implements ComparableFieldProvider { Moderation? moderation, Object? draft = _nullConst, Object? reminder = _nullConst, + Location? sharedLocation, }) { assert(() { if (pinExpires is! DateTime && @@ -483,6 +496,7 @@ class Message extends Equatable implements ComparableFieldProvider { draft: draft == _nullConst ? this.draft : draft as Draft?, reminder: reminder == _nullConst ? this.reminder : reminder as MessageReminder?, + sharedLocation: sharedLocation ?? this.sharedLocation, ); } @@ -528,6 +542,7 @@ class Message extends Equatable implements ComparableFieldProvider { moderation: other.moderation, draft: other.draft, reminder: other.reminder, + sharedLocation: other.sharedLocation, ); } @@ -593,6 +608,7 @@ class Message extends Equatable implements ComparableFieldProvider { moderation, draft, reminder, + sharedLocation, ]; @override diff --git a/packages/stream_chat/lib/src/core/models/message.g.dart b/packages/stream_chat/lib/src/core/models/message.g.dart index 2d2165b60a..3add1df41b 100644 --- a/packages/stream_chat/lib/src/core/models/message.g.dart +++ b/packages/stream_chat/lib/src/core/models/message.g.dart @@ -91,6 +91,9 @@ Message _$MessageFromJson(Map json) => Message( reminder: json['reminder'] == null ? null : MessageReminder.fromJson(json['reminder'] as Map), + sharedLocation: json['shared_location'] == null + ? null + : Location.fromJson(json['shared_location'] as Map), ); Map _$MessageToJson(Message instance) => { @@ -108,7 +111,7 @@ Map _$MessageToJson(Message instance) => { 'poll_id': instance.pollId, if (instance.restrictedVisibility case final value?) 'restricted_visibility': value, - 'draft': instance.draft?.toJson(), - 'reminder': instance.reminder?.toJson(), + if (instance.sharedLocation?.toJson() case final value?) + 'shared_location': value, 'extra_data': instance.extraData, }; diff --git a/packages/stream_chat/lib/src/event_type.dart b/packages/stream_chat/lib/src/event_type.dart index 29ab5b1de8..189350d959 100644 --- a/packages/stream_chat/lib/src/event_type.dart +++ b/packages/stream_chat/lib/src/event_type.dart @@ -122,6 +122,9 @@ class EventType { /// Event sent when the AI indicator is cleared static const String aiIndicatorClear = 'ai_indicator.clear'; + /// Event sent when a new poll is created. + static const String pollCreated = 'poll.created'; + /// Event sent when a poll is updated. static const String pollUpdated = 'poll.updated'; @@ -170,4 +173,13 @@ class EventType { /// Event sent when a message reminder is due. static const String notificationReminderDue = 'notification.reminder_due'; + + /// Event sent when a new shared location is created. + static const String locationShared = 'location.shared'; + + /// Event sent when a live shared location is updated. + static const String locationUpdated = 'location.updated'; + + /// Event sent when a live shared location is expired. + static const String locationExpired = 'location.expired'; } diff --git a/packages/stream_chat/lib/stream_chat.dart b/packages/stream_chat/lib/stream_chat.dart index 452056f2de..131c41743e 100644 --- a/packages/stream_chat/lib/stream_chat.dart +++ b/packages/stream_chat/lib/stream_chat.dart @@ -43,6 +43,8 @@ export 'src/core/models/draft.dart'; export 'src/core/models/draft_message.dart'; export 'src/core/models/event.dart'; export 'src/core/models/filter.dart' show Filter; +export 'src/core/models/location.dart'; +export 'src/core/models/location_coordinates.dart'; export 'src/core/models/member.dart'; export 'src/core/models/message.dart'; export 'src/core/models/message_reminder.dart'; diff --git a/packages/stream_chat/test/fixtures/channel_state_to_json.json b/packages/stream_chat/test/fixtures/channel_state_to_json.json index 9eec788ae6..662cf61908 100644 --- a/packages/stream_chat/test/fixtures/channel_state_to_json.json +++ b/packages/stream_chat/test/fixtures/channel_state_to_json.json @@ -29,9 +29,7 @@ "poll_id": null, "restricted_visibility": [ "user-id-3" - ], - "draft": null, - "reminder": null + ] }, { "id": "dry-meadow-0-e8e74482-b4cd-48db-9d1e-30e6c191786f", @@ -46,9 +44,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "dry-meadow-0-53e6299f-9b97-4a9c-a27e-7e2dde49b7e0", @@ -63,9 +59,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "dry-meadow-0-80925be0-786e-40a5-b225-486518dafd35", @@ -80,9 +74,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "dry-meadow-0-64d7970f-ede8-4b31-9738-1bc1756d2bfe", @@ -97,9 +89,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "withered-cell-0-84cbd760-cf55-4f7e-9207-c5f66cccc6dc", @@ -114,9 +104,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "dry-meadow-0-e9203588-43c3-40b1-91f7-f217fc42aa53", @@ -131,9 +119,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "withered-cell-0-7e3552d7-7a0d-45f2-a856-e91b23a7e240", @@ -148,9 +134,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "dry-meadow-0-1ffeafd4-e4fc-4c84-9394-9d7cb10fff42", @@ -165,9 +149,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "dry-meadow-0-3f147324-12c8-4b41-9fb5-2db88d065efa", @@ -182,9 +164,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "dry-meadow-0-51a348ae-0c0a-44de-a556-eac7891c0cf0", @@ -199,9 +179,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "icy-recipe-7-a29e237b-8d81-4a97-9bc8-d42bca3f1356", @@ -216,9 +194,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "icy-recipe-7-935c396e-ddf8-4a9a-951c-0a12fa5bf055", @@ -233,9 +209,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "throbbing-boat-5-1e4d5730-5ff0-4d25-9948-9f34ffda43e4", @@ -250,9 +224,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "snowy-credit-3-3e0c1a0d-d22f-42ee-b2a1-f9f49477bf21", @@ -267,9 +239,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "snowy-credit-3-3319537e-2d0e-4876-8170-a54f046e4b7d", @@ -284,9 +254,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "snowy-credit-3-cfaf0b46-1daa-49c5-947c-b16d6697487d", @@ -301,9 +269,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "snowy-credit-3-cebe25a7-a3a3-49fc-9919-91c6725e81f3", @@ -318,9 +284,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "divine-glade-9-0cea9262-5766-48e9-8b22-311870aed3bf", @@ -335,9 +299,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "red-firefly-9-c4e9007b-bb7d-4238-ae08-5f8e3cd03d73", @@ -352,9 +314,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "bitter-glade-2-02aee4eb-4093-4736-808b-2de75820e854", @@ -369,9 +329,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "morning-sea-1-0c700bcb-46dd-4224-b590-e77bdbccc480", @@ -386,9 +344,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "ancient-salad-0-53e8b4e6-5b7b-43ad-aeee-8bfb6a9ed0be", @@ -403,9 +359,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "ancient-salad-0-8c225075-bd4c-42e2-8024-530aae13cd40", @@ -420,9 +374,7 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null }, { "id": "proud-sea-7-17802096-cbf8-4e3c-addd-4ee31f4c8b5c", @@ -437,12 +389,11 @@ "silent": false, "pinned": false, "pin_expires": null, - "poll_id": null, - "draft": null, - "reminder": null + "poll_id": null } ], "pinned_messages": [], "members": [], + "active_live_locations": [], "watcher_count": 5 } diff --git a/packages/stream_chat/test/fixtures/message_to_json.json b/packages/stream_chat/test/fixtures/message_to_json.json index 8803f1ed1d..c4568628d3 100644 --- a/packages/stream_chat/test/fixtures/message_to_json.json +++ b/packages/stream_chat/test/fixtures/message_to_json.json @@ -26,7 +26,5 @@ "restricted_visibility": [ "user-id-3" ], - "draft": null, - "reminder": null, "hey": "test" } \ No newline at end of file diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index eabb98f7c2..a07f7fbbae 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -461,6 +461,109 @@ void main() { }); }); + group('`.sendStaticLocation`', () { + const deviceId = 'test-device-id'; + const locationId = 'test-location-id'; + const coordinates = LocationCoordinates( + latitude: 40.7128, + longitude: -74.0060, + ); + + test('should create a static location and call sendMessage', () async { + when( + () => client.sendMessage(any(), channelId, channelType), + ).thenAnswer( + (_) async => SendMessageResponse() + ..message = Message( + id: locationId, + text: 'Location shared', + extraData: const {'custom': 'data'}, + sharedLocation: Location( + channelCid: channel.cid, + messageId: locationId, + userId: client.state.currentUser?.id, + latitude: coordinates.latitude, + longitude: coordinates.longitude, + createdByDeviceId: deviceId, + ), + ), + ); + + final response = await channel.sendStaticLocation( + id: locationId, + messageText: 'Location shared', + createdByDeviceId: deviceId, + location: coordinates, + extraData: {'custom': 'data'}, + ); + + expect(response, isNotNull); + expect(response.message.id, locationId); + expect(response.message.text, 'Location shared'); + expect(response.message.extraData['custom'], 'data'); + expect(response.message.sharedLocation, isNotNull); + + verify( + () => client.sendMessage(any(), channelId, channelType), + ).called(1); + }); + }); + + group('`.startLiveLocationSharing`', () { + const deviceId = 'test-device-id'; + const locationId = 'test-location-id'; + final endSharingAt = DateTime.now().add(const Duration(hours: 1)); + const coordinates = LocationCoordinates( + latitude: 40.7128, + longitude: -74.0060, + ); + + test( + 'should create message with live location and call sendMessage', + () async { + when( + () => client.sendMessage(any(), channelId, channelType), + ).thenAnswer( + (_) async => SendMessageResponse() + ..message = Message( + id: locationId, + text: 'Location shared', + extraData: const {'custom': 'data'}, + sharedLocation: Location( + channelCid: channel.cid, + messageId: locationId, + userId: client.state.currentUser?.id, + latitude: coordinates.latitude, + longitude: coordinates.longitude, + createdByDeviceId: deviceId, + endAt: endSharingAt, + ), + ), + ); + + final response = await channel.startLiveLocationSharing( + id: locationId, + messageText: 'Location shared', + createdByDeviceId: deviceId, + location: coordinates, + endSharingAt: endSharingAt, + extraData: {'custom': 'data'}, + ); + + expect(response, isNotNull); + expect(response.message.id, locationId); + expect(response.message.text, 'Location shared'); + expect(response.message.extraData['custom'], 'data'); + expect(response.message.sharedLocation, isNotNull); + expect(response.message.sharedLocation?.endAt, endSharingAt); + + verify( + () => client.sendMessage(any(), channelId, channelType), + ).called(1); + }, + ); + }); + group('`.createDraft`', () { final draftMessage = DraftMessage(text: 'Draft message text'); @@ -4814,6 +4917,486 @@ void main() { expect(updatedMessage?.reminder, isNull); }); }); + + group('Location events', () { + const channelId = 'test-channel-id'; + const channelType = 'test-channel-type'; + late Channel channel; + + setUp(() { + final channelState = _generateChannelState(channelId, channelType); + channel = Channel.fromState(client, channelState); + }); + + tearDown(() { + channel.dispose(); + }); + + test('should handle location.shared event', () async { + // Verify initial state + expect(channel.state?.activeLiveLocations, isEmpty); + + // Create live location + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final locationMessage = Message( + id: 'msg1', + text: 'Live location shared', + sharedLocation: liveLocation, + ); + + // Create location.shared event + final locationSharedEvent = Event( + cid: channel.cid, + type: EventType.locationShared, + message: locationMessage, + ); + + // Dispatch event + client.addEvent(locationSharedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Check if message was added + final messages = channel.state?.messages; + final message = messages?.firstWhere((m) => m.id == 'msg1'); + expect(message, isNotNull); + + // Check if active live location was updated + final activeLiveLocations = channel.state?.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations?.first.messageId, equals('msg1')); + }); + + test('should handle location.updated event', () async { + // Setup initial state with location message + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final locationMessage = Message( + id: 'msg1', + text: 'Live location shared', + sharedLocation: liveLocation, + ); + + // Add initial message + channel.state?.addNewMessage(locationMessage); + + // Create updated location + final updatedLocation = liveLocation.copyWith( + latitude: 40.7500, // Updated latitude + longitude: -74.1000, // Updated longitude + ); + + final updatedMessage = locationMessage.copyWith( + sharedLocation: updatedLocation, + ); + + // Create location.updated event + final locationUpdatedEvent = Event( + cid: channel.cid, + type: EventType.locationUpdated, + message: updatedMessage, + ); + + // Dispatch event + client.addEvent(locationUpdatedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Check if message was updated + final messages = channel.state?.messages; + final message = messages?.firstWhere((m) => m.id == 'msg1'); + expect(message?.sharedLocation?.latitude, equals(40.7500)); + expect(message?.sharedLocation?.longitude, equals(-74.1000)); + + // Check if active live location was updated + final activeLiveLocations = channel.state?.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations?.first.latitude, equals(40.7500)); + expect(activeLiveLocations?.first.longitude, equals(-74.1000)); + }); + + test('should handle location.expired event', () async { + // Setup initial state with location message + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final locationMessage = Message( + id: 'msg1', + text: 'Live location shared', + sharedLocation: liveLocation, + ); + + // Add initial message + channel.state?.addNewMessage(locationMessage); + expect(channel.state?.activeLiveLocations, hasLength(1)); + + // Create expired location + final expiredLocation = liveLocation.copyWith( + endAt: DateTime.now().subtract(const Duration(hours: 1)), + ); + + final expiredMessage = locationMessage.copyWith( + sharedLocation: expiredLocation, + ); + + // Create location.expired event + final locationExpiredEvent = Event( + cid: channel.cid, + type: EventType.locationExpired, + message: expiredMessage, + ); + + // Dispatch event + client.addEvent(locationExpiredEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Check if message was updated + final messages = channel.state?.messages; + final message = messages?.firstWhere((m) => m.id == 'msg1'); + expect(message?.sharedLocation?.isExpired, isTrue); + + // Check if active live location was removed + expect(channel.state?.activeLiveLocations, isEmpty); + }); + + test('should not add static location to active locations', () async { + final staticLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + // No endAt - static location + ); + + final staticMessage = Message( + id: 'msg1', + text: 'Static location shared', + sharedLocation: staticLocation, + ); + + // Create location.shared event + final locationSharedEvent = Event( + cid: channel.cid, + type: EventType.locationShared, + message: staticMessage, + ); + + // Dispatch event + client.addEvent(locationSharedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Check if message was added + final messages = channel.state?.messages; + final message = messages?.firstWhere((m) => m.id == 'msg1'); + expect(message?.sharedLocation, isNotNull); + + // Check if active live location was NOT updated (should remain empty) + expect(channel.state?.activeLiveLocations, isEmpty); + }); + + test( + 'should update active locations when location message is deleted', + () async { + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final locationMessage = Message( + id: 'msg1', + text: 'Live location shared', + sharedLocation: liveLocation, + ); + + // Verify initial state + channel.state?.addNewMessage(locationMessage); + expect(channel.state?.activeLiveLocations, hasLength(1)); + + final messageDeletedEvent = Event( + type: EventType.messageDeleted, + cid: channel.cid, + message: locationMessage.copyWith( + type: MessageType.deleted, + deletedAt: DateTime.timestamp(), + ), + ); + + // Dispatch event + client.addEvent(messageDeletedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Verify active locations are updated + expect(channel.state?.activeLiveLocations, isEmpty); + }, + ); + + test('should merge locations with same key', () async { + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final locationMessage = Message( + id: 'msg1', + text: 'Live location shared', + sharedLocation: liveLocation, + ); + + // Add initial location for setup + channel.state?.addNewMessage(locationMessage); + expect(channel.state?.activeLiveLocations, hasLength(1)); + + // Create new location with same user, channel, and device + final newLocation = Location( + channelCid: channel.cid, + userId: 'user1', // Same user + messageId: 'msg2', // Different message + latitude: 40.7500, + longitude: -74.1000, + createdByDeviceId: 'device1', // Same device + endAt: DateTime.now().add(const Duration(hours: 2)), + ); + + final newMessage = Message( + id: 'msg2', + text: 'Updated location', + sharedLocation: newLocation, + ); + + // Create location.shared event for the new message + final locationSharedEvent = Event( + cid: channel.cid, + type: EventType.locationShared, + message: newMessage, + ); + + // Dispatch event + client.addEvent(locationSharedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Should still have only one active location (merged) + final activeLiveLocations = channel.state?.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations?.first.messageId, equals('msg2')); + expect(activeLiveLocations?.first.latitude, equals(40.7500)); + }); + + test( + 'should handle multiple active locations from different devices', + () async { + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final locationMessage = Message( + id: 'msg1', + text: 'Live location shared', + sharedLocation: liveLocation, + ); + + // Add first location for setup + channel.state?.addNewMessage(locationMessage); + expect(channel.state?.activeLiveLocations, hasLength(1)); + + // Create location from different device + final location2 = Location( + channelCid: channel.cid, + userId: 'user1', // Same user + messageId: 'msg2', + latitude: 34.0522, + longitude: -118.2437, + createdByDeviceId: 'device2', // Different device + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final message2 = Message( + id: 'msg2', + text: 'Location from device 2', + sharedLocation: location2, + ); + + // Create location.shared event for the second message + final locationSharedEvent = Event( + cid: channel.cid, + type: EventType.locationShared, + message: message2, + ); + + // Dispatch event + client.addEvent(locationSharedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Should have two active locations + expect(channel.state?.activeLiveLocations, hasLength(2)); + }, + ); + + test('should handle location messages in threads', () async { + final parentMessage = Message( + id: 'parent1', + text: 'Thread parent', + ); + + // Add parent message first for setup + channel.state?.addNewMessage(parentMessage); + + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'thread-msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final threadLocationMessage = Message( + id: 'thread-msg1', + text: 'Live location in thread', + parentId: 'parent1', + sharedLocation: liveLocation, + ); + + // Create location.shared event for the thread message + final locationSharedEvent = Event( + cid: channel.cid, + type: EventType.locationShared, + message: threadLocationMessage, + ); + + // Dispatch event + client.addEvent(locationSharedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Check if thread message was added + final thread = channel.state?.threads['parent1']; + expect(thread, contains(threadLocationMessage)); + + // Check if location was added to active locations + final activeLiveLocations = channel.state?.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations?.first.messageId, equals('thread-msg1')); + }); + + test('should update thread location messages', () async { + final parentMessage = Message( + id: 'parent1', + text: 'Thread parent', + ); + + final liveLocation = Location( + channelCid: channel.cid, + userId: 'user1', + messageId: 'thread-msg1', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final threadLocationMessage = Message( + id: 'thread-msg1', + text: 'Live location in thread', + parentId: 'parent1', + sharedLocation: liveLocation, + ); + + // Add messages + channel.state?.addNewMessage(parentMessage); + channel.state?.addNewMessage(threadLocationMessage); + + // Update the location + final updatedLocation = liveLocation.copyWith( + latitude: 40.7500, + longitude: -74.1000, + ); + + final updatedThreadMessage = threadLocationMessage.copyWith( + sharedLocation: updatedLocation, + ); + + // Create location.updated event for the thread message + final locationUpdatedEvent = Event( + cid: channel.cid, + type: EventType.locationUpdated, + message: updatedThreadMessage, + ); + + // Dispatch event + client.addEvent(locationUpdatedEvent); + + // Wait for the event to be processed + await Future.delayed(Duration.zero); + + // Check if thread message was updated + final thread = channel.state?.threads['parent1']; + final threadMessage = thread?.firstWhere((m) => m.id == 'thread-msg1'); + expect(threadMessage?.sharedLocation?.latitude, equals(40.7500)); + expect(threadMessage?.sharedLocation?.longitude, equals(-74.1000)); + + // Check if active location was updated + final activeLiveLocations = channel.state?.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations?.first.latitude, equals(40.7500)); + expect(activeLiveLocations?.first.longitude, equals(-74.1000)); + }); + }); }); group('ChannelCapabilityCheck', () { @@ -5076,6 +5659,12 @@ void main() { (channel) => channel.canQueryPollVotes, ); + testCapability( + 'ShareLocation', + ChannelCapability.shareLocation, + (channel) => channel.canShareLocation, + ); + test('returns correct values with multiple capabilities', () { final channelState = _generateChannelState( channelId, diff --git a/packages/stream_chat/test/src/client/client_test.dart b/packages/stream_chat/test/src/client/client_test.dart index 9ea62a75c4..95f48ab2c5 100644 --- a/packages/stream_chat/test/src/client/client_test.dart +++ b/packages/stream_chat/test/src/client/client_test.dart @@ -2841,6 +2841,361 @@ void main() { verifyNoMoreInteractions(api.moderation); }); + test('`.getActiveLiveLocations`', () async { + final locations = [ + Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ), + Location( + latitude: 34.0522, + longitude: -118.2437, + createdByDeviceId: 'device-2', + endAt: DateTime.now().add(const Duration(hours: 2)), + ), + ]; + + when(() => api.user.getActiveLiveLocations()).thenAnswer( + (_) async => GetActiveLiveLocationsResponse() // + ..activeLiveLocations = locations, + ); + + // Initial state should be empty + expect(client.state.activeLiveLocations, isEmpty); + + final res = await client.getActiveLiveLocations(); + + expect(res, isNotNull); + expect(res.activeLiveLocations, hasLength(2)); + expect(res.activeLiveLocations, equals(locations)); + expect(client.state.activeLiveLocations, equals(locations)); + + verify(() => api.user.getActiveLiveLocations()).called(1); + verifyNoMoreInteractions(api.user); + }); + + test('`.updateLiveLocation`', () async { + const messageId = 'test-message-id'; + const createdByDeviceId = 'test-device-id'; + final endAt = DateTime.timestamp().add(const Duration(hours: 1)); + const location = LocationCoordinates( + latitude: 40.7128, + longitude: -74.0060, + ); + + final expectedLocation = Location( + latitude: location.latitude, + longitude: location.longitude, + createdByDeviceId: createdByDeviceId, + endAt: endAt, + ); + + when( + () => api.user.updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + location: location, + endAt: endAt, + ), + ).thenAnswer((_) async => expectedLocation); + + final res = await client.updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + location: location, + endAt: endAt, + ); + + expect(res, isNotNull); + expect(res, equals(expectedLocation)); + + verify( + () => api.user.updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + location: location, + endAt: endAt, + ), + ).called(1); + verifyNoMoreInteractions(api.user); + }); + + test('`.stopLiveLocation`', () async { + const messageId = 'test-message-id'; + const createdByDeviceId = 'test-device-id'; + + final expectedLocation = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: createdByDeviceId, + endAt: DateTime.now(), // Should be expired + ); + + when( + () => api.user.updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + endAt: any(named: 'endAt'), + ), + ).thenAnswer((_) async => expectedLocation); + + final res = await client.stopLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + ); + + expect(res, isNotNull); + expect(res, equals(expectedLocation)); + + verify( + () => api.user.updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + endAt: any(named: 'endAt'), + ), + ).called(1); + verifyNoMoreInteractions(api.user); + }); + + group('Live Location Event Handling', () { + test('should handle location.shared event', () async { + final location = Location( + channelCid: 'test-channel:123', + messageId: 'message-123', + userId: userId, + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final event = Event( + type: EventType.locationShared, + cid: 'test-channel:123', + message: Message( + id: 'message-123', + sharedLocation: location, + ), + ); + + // Initially empty + expect(client.state.activeLiveLocations, isEmpty); + + // Trigger the event + client.handleEvent(event); + + // Wait for the event to get processed + await Future.delayed(Duration.zero); + + // Should add location to active live locations + final activeLiveLocations = client.state.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations.first.messageId, equals('message-123')); + }); + + test('should handle location.updated event', () async { + final initialLocation = Location( + channelCid: 'test-channel:123', + messageId: 'message-123', + userId: userId, + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + // Set initial location + client.state.activeLiveLocations = [initialLocation]; + + final updatedLocation = Location( + channelCid: 'test-channel:123', + messageId: 'message-123', + userId: userId, + latitude: 40.7500, // Updated latitude + longitude: -74.1000, // Updated longitude + createdByDeviceId: 'device-1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final event = Event( + type: EventType.locationUpdated, + cid: 'test-channel:123', + message: Message( + id: 'message-123', + sharedLocation: updatedLocation, + ), + ); + + // Trigger the event + client.handleEvent(event); + + // Wait for the event to get processed + await Future.delayed(Duration.zero); + + // Should update the location + final activeLiveLocations = client.state.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations.first.latitude, equals(40.7500)); + expect(activeLiveLocations.first.longitude, equals(-74.1000)); + }); + + test('should handle location.expired event', () async { + final location = Location( + channelCid: 'test-channel:123', + messageId: 'message-123', + userId: userId, + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + // Set initial location + client.state.activeLiveLocations = [location]; + expect(client.state.activeLiveLocations, hasLength(1)); + + final expiredLocation = location.copyWith( + endAt: DateTime.now().subtract(const Duration(hours: 1)), + ); + + final event = Event( + type: EventType.locationExpired, + cid: 'test-channel:123', + message: Message( + id: 'message-123', + sharedLocation: expiredLocation, + ), + ); + + // Trigger the event + client.handleEvent(event); + + // Wait for the event to get processed + await Future.delayed(Duration.zero); + + // Should remove the location + expect(client.state.activeLiveLocations, isEmpty); + }); + + test('should ignore location events for other users', () async { + final location = Location( + channelCid: 'test-channel:123', + messageId: 'message-123', + userId: 'other-user', // Different user + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final event = Event( + type: EventType.locationShared, + cid: 'test-channel:123', + message: Message( + id: 'message-123', + sharedLocation: location, + ), + ); + + // Trigger the event + client.handleEvent(event); + + // Wait for the event to get processed + await Future.delayed(Duration.zero); + + // Should not add location from other user + expect(client.state.activeLiveLocations, isEmpty); + }); + + test('should ignore static location events', () async { + final staticLocation = Location( + channelCid: 'test-channel:123', + messageId: 'message-123', + userId: userId, + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-1', + // No endAt means it's static + ); + + final event = Event( + type: EventType.locationShared, + cid: 'test-channel:123', + message: Message( + id: 'message-123', + sharedLocation: staticLocation, + ), + ); + + // Trigger the event + client.handleEvent(event); + + // Wait for the event to get processed + await Future.delayed(Duration.zero); + + // Should not add static location + expect(client.state.activeLiveLocations, isEmpty); + }); + + test('should merge locations with same key', () async { + final location1 = Location( + channelCid: 'test-channel:123', + messageId: 'message-123', + userId: userId, + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-1', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final location2 = Location( + channelCid: 'test-channel:123', + messageId: 'message-456', + userId: userId, + latitude: 40.7500, + longitude: -74.1000, + createdByDeviceId: 'device-1', // Same device, should merge + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final event1 = Event( + type: EventType.locationShared, + cid: 'test-channel:123', + message: Message( + id: 'message-123', + sharedLocation: location1, + ), + ); + + final event2 = Event( + type: EventType.locationShared, + cid: 'test-channel:123', + message: Message( + id: 'message-456', + sharedLocation: location2, + ), + ); + + // Trigger first event + client.handleEvent(event1); + await Future.delayed(Duration.zero); + + final activeLiveLocations = client.state.activeLiveLocations; + expect(activeLiveLocations, hasLength(1)); + expect(activeLiveLocations.first.messageId, equals('message-123')); + + // Trigger second event - should merge/update + client.handleEvent(event2); + await Future.delayed(Duration.zero); + + final activeLiveLocations2 = client.state.activeLiveLocations; + expect(activeLiveLocations2, hasLength(1)); + expect(activeLiveLocations2.first.messageId, equals('message-456')); + }); + }); + test('`.markAllRead`', () async { when(() => api.channel.markAllRead()) .thenAnswer((_) async => EmptyResponse()); diff --git a/packages/stream_chat/test/src/client/event_resolvers_test.dart b/packages/stream_chat/test/src/client/event_resolvers_test.dart new file mode 100644 index 0000000000..0d8155ccf4 --- /dev/null +++ b/packages/stream_chat/test/src/client/event_resolvers_test.dart @@ -0,0 +1,669 @@ +// ignore_for_file: avoid_redundant_argument_values, lines_longer_than_80_chars + +import 'package:stream_chat/src/client/event_resolvers.dart'; +import 'package:stream_chat/src/core/models/event.dart'; +import 'package:stream_chat/src/core/models/location.dart'; +import 'package:stream_chat/src/core/models/message.dart'; +import 'package:stream_chat/src/core/models/poll.dart'; +import 'package:stream_chat/src/core/models/poll_option.dart'; +import 'package:stream_chat/src/core/models/poll_vote.dart'; +import 'package:stream_chat/src/core/models/user.dart'; +import 'package:stream_chat/src/event_type.dart'; +import 'package:test/test.dart'; + +void main() { + group('Poll resolver events', () { + group('pollCreatedResolver', () { + test('should resolve messageNew event with poll to pollCreated', () { + final poll = Poll( + id: 'poll-123', + name: 'Test Poll', + options: const [ + PollOption(id: 'option-1', text: 'Option 1'), + PollOption(id: 'option-2', text: 'Option 2'), + ], + ); + + final event = Event( + type: EventType.messageNew, + poll: poll, + cid: 'channel-123', + ); + + final resolved = pollCreatedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.pollCreated); + expect(resolved.poll, equals(poll)); + expect(resolved.cid, equals('channel-123')); + }); + + test( + 'should resolve notificationMessageNew event with poll to pollCreated', + () { + final poll = Poll( + id: 'poll-123', + name: 'Test Poll', + options: const [ + PollOption(id: 'option-1', text: 'Option 1'), + ], + ); + + final event = Event( + type: EventType.notificationMessageNew, + poll: poll, + cid: 'channel-123', + ); + + final resolved = pollCreatedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.pollCreated); + expect(resolved.poll, equals(poll)); + }, + ); + + test('should return null for messageNew event without poll', () { + final event = Event( + type: EventType.messageNew, + cid: 'channel-123', + ); + + final resolved = pollCreatedResolver(event); + + expect(resolved, isNull); + }); + + test('should return null for invalid event types', () { + final poll = Poll( + id: 'poll-123', + name: 'Test Poll', + options: const [ + PollOption(id: 'option-1', text: 'Option 1'), + ], + ); + + final event = Event( + type: EventType.messageUpdated, + poll: poll, + cid: 'channel-123', + ); + + final resolved = pollCreatedResolver(event); + + expect(resolved, isNull); + }); + + test('should return null for event with null poll', () { + final event = Event( + type: EventType.messageNew, + poll: null, + cid: 'channel-123', + ); + + final resolved = pollCreatedResolver(event); + + expect(resolved, isNull); + }); + }); + + group('pollAnswerCastedResolver', () { + test( + 'should resolve pollVoteCasted event with answer to pollAnswerCasted', + () { + final pollVote = PollVote( + id: 'vote-123', + answerText: 'My answer', + pollId: 'poll-123', + ); + + final event = Event( + type: EventType.pollVoteCasted, + pollVote: pollVote, + cid: 'channel-123', + ); + + final resolved = pollAnswerCastedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.pollAnswerCasted); + expect(resolved.pollVote, equals(pollVote)); + expect(resolved.cid, equals('channel-123')); + }, + ); + + test( + 'should resolve pollVoteChanged event with answer to pollAnswerCasted', + () { + final pollVote = PollVote( + id: 'vote-123', + answerText: 'My updated answer', + pollId: 'poll-123', + ); + + final event = Event( + type: EventType.pollVoteChanged, + pollVote: pollVote, + cid: 'channel-123', + ); + + final resolved = pollAnswerCastedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.pollAnswerCasted); + expect(resolved.pollVote, equals(pollVote)); + }, + ); + + test('should return null for pollVoteCasted event with option vote', () { + final pollVote = PollVote( + id: 'vote-123', + optionId: 'option-1', + pollId: 'poll-123', + ); + + final event = Event( + type: EventType.pollVoteCasted, + pollVote: pollVote, + cid: 'channel-123', + ); + + final resolved = pollAnswerCastedResolver(event); + + expect(resolved, isNull); + }); + + test('should return null for invalid event types', () { + final pollVote = PollVote( + id: 'vote-123', + answerText: 'My answer', + pollId: 'poll-123', + ); + + final event = Event( + type: EventType.pollVoteRemoved, + pollVote: pollVote, + cid: 'channel-123', + ); + + final resolved = pollAnswerCastedResolver(event); + + expect(resolved, isNull); + }); + + test('should return resolved event for event with null pollVote', () { + final event = Event( + type: EventType.pollVoteCasted, + pollVote: null, + cid: 'channel-123', + ); + + final resolved = pollAnswerCastedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.pollAnswerCasted); + expect(resolved.pollVote, isNull); + }); + }); + + group('pollAnswerRemovedResolver', () { + test( + 'should resolve pollVoteRemoved event with answer to pollAnswerRemoved', + () { + final pollVote = PollVote( + id: 'vote-123', + answerText: 'My answer', + pollId: 'poll-123', + ); + + final event = Event( + type: EventType.pollVoteRemoved, + pollVote: pollVote, + cid: 'channel-123', + ); + + final resolved = pollAnswerRemovedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.pollAnswerRemoved); + expect(resolved.pollVote, equals(pollVote)); + expect(resolved.cid, equals('channel-123')); + }, + ); + + test('should return null for pollVoteRemoved event with option vote', () { + final pollVote = PollVote( + id: 'vote-123', + optionId: 'option-1', + pollId: 'poll-123', + ); + + final event = Event( + type: EventType.pollVoteRemoved, + pollVote: pollVote, + cid: 'channel-123', + ); + + final resolved = pollAnswerRemovedResolver(event); + + expect(resolved, isNull); + }); + + test('should return null for invalid event types', () { + final pollVote = PollVote( + id: 'vote-123', + answerText: 'My answer', + pollId: 'poll-123', + ); + + final event = Event( + type: EventType.pollVoteCasted, + pollVote: pollVote, + cid: 'channel-123', + ); + + final resolved = pollAnswerRemovedResolver(event); + + expect(resolved, isNull); + }); + + test('should return resolved event for event with null pollVote', () { + final event = Event( + type: EventType.pollVoteRemoved, + pollVote: null, + cid: 'channel-123', + ); + + final resolved = pollAnswerRemovedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.pollAnswerRemoved); + expect(resolved.pollVote, isNull); + }); + }); + }); + + group('Location resolver events', () { + group('locationSharedResolver', () { + test( + 'should resolve messageNew event with sharedLocation to locationShared', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + ); + + final message = Message( + id: 'message-123', + text: 'Check out this location', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageNew, + message: message, + cid: 'channel-123', + ); + + final resolved = locationSharedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.locationShared); + expect(resolved.message, equals(message)); + expect(resolved.cid, equals('channel-123')); + }, + ); + + test( + 'should resolve notificationMessageNew event with sharedLocation to locationShared', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + ); + + final message = Message( + id: 'message-123', + text: 'Check out this location', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.notificationMessageNew, + message: message, + cid: 'channel-123', + ); + + final resolved = locationSharedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.locationShared); + expect(resolved.message, equals(message)); + }, + ); + + test( + 'should return null for messageNew event without sharedLocation', + () { + final message = Message( + id: 'message-123', + text: 'Just a regular message', + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageNew, + message: message, + cid: 'channel-123', + ); + + final resolved = locationSharedResolver(event); + + expect(resolved, isNull); + }, + ); + + test('should return null for invalid event types', () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + ); + + final message = Message( + id: 'message-123', + text: 'Check out this location', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageUpdated, + message: message, + cid: 'channel-123', + ); + + final resolved = locationSharedResolver(event); + + expect(resolved, isNull); + }); + + test('should return null for event with null message', () { + final event = Event( + type: EventType.messageNew, + message: null, + cid: 'channel-123', + ); + + final resolved = locationSharedResolver(event); + + expect(resolved, isNull); + }); + }); + + group('locationUpdatedResolver', () { + test( + 'should resolve messageUpdated event with active live location to locationUpdated', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final message = Message( + id: 'message-123', + text: 'Live location sharing', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageUpdated, + message: message, + cid: 'channel-123', + ); + + final resolved = locationUpdatedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.locationUpdated); + expect(resolved.message, equals(message)); + expect(resolved.cid, equals('channel-123')); + }, + ); + + test( + 'should resolve messageUpdated event with static location to locationUpdated', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + // No endAt means static location + ); + + final message = Message( + id: 'message-123', + text: 'Static location sharing', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageUpdated, + message: message, + cid: 'channel-123', + ); + + final resolved = locationUpdatedResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.locationUpdated); + expect(resolved.message, equals(message)); + }, + ); + + test( + 'should return null for messageUpdated event with expired live location', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + endAt: DateTime.now().subtract(const Duration(hours: 1)), + ); + + final message = Message( + id: 'message-123', + text: 'Expired location sharing', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageUpdated, + message: message, + cid: 'channel-123', + ); + + final resolved = locationUpdatedResolver(event); + + expect(resolved, isNull); + }, + ); + + test('should return null for invalid event types', () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + ); + + final message = Message( + id: 'message-123', + text: 'Check out this location', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageNew, + message: message, + cid: 'channel-123', + ); + + final resolved = locationUpdatedResolver(event); + + expect(resolved, isNull); + }); + + test('should return null for event with null message', () { + final event = Event( + type: EventType.messageUpdated, + message: null, + cid: 'channel-123', + ); + + final resolved = locationUpdatedResolver(event); + + expect(resolved, isNull); + }); + }); + + group('locationExpiredResolver', () { + test( + 'should resolve messageUpdated event with expired live location to locationExpired', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + endAt: DateTime.now().subtract(const Duration(hours: 1)), + ); + + final message = Message( + id: 'message-123', + text: 'Expired location sharing', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageUpdated, + message: message, + cid: 'channel-123', + ); + + final resolved = locationExpiredResolver(event); + + expect(resolved, isNotNull); + expect(resolved!.type, EventType.locationExpired); + expect(resolved.message, equals(message)); + expect(resolved.cid, equals('channel-123')); + }, + ); + + test( + 'should return null for messageUpdated event with active live location', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + endAt: DateTime.now().add(const Duration(hours: 1)), + ); + + final message = Message( + id: 'message-123', + text: 'Active location sharing', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageUpdated, + message: message, + cid: 'channel-123', + ); + + final resolved = locationExpiredResolver(event); + + expect(resolved, isNull); + }, + ); + + test( + 'should return null for messageUpdated event with static location', + () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + // No endAt means static location + ); + + final message = Message( + id: 'message-123', + text: 'Static location sharing', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageUpdated, + message: message, + cid: 'channel-123', + ); + + final resolved = locationExpiredResolver(event); + + expect(resolved, isNull); + }, + ); + + test('should return null for invalid event types', () { + final location = Location( + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'device-123', + endAt: DateTime.now().subtract(const Duration(hours: 1)), + ); + + final message = Message( + id: 'message-123', + text: 'Expired location sharing', + sharedLocation: location, + user: User(id: 'user-123'), + ); + + final event = Event( + type: EventType.messageNew, + message: message, + cid: 'channel-123', + ); + + final resolved = locationExpiredResolver(event); + + expect(resolved, isNull); + }); + + test('should return null for event with null message', () { + final event = Event( + type: EventType.messageUpdated, + message: null, + cid: 'channel-123', + ); + + final resolved = locationExpiredResolver(event); + + expect(resolved, isNull); + }); + }); + }); +} diff --git a/packages/stream_chat/test/src/core/api/user_api_test.dart b/packages/stream_chat/test/src/core/api/user_api_test.dart index 97eda70148..9a77907e64 100644 --- a/packages/stream_chat/test/src/core/api/user_api_test.dart +++ b/packages/stream_chat/test/src/core/api/user_api_test.dart @@ -246,4 +246,80 @@ void main() { verify(() => client.get(path)).called(1); verifyNoMoreInteractions(client); }); + + test('getActiveLiveLocations', () async { + const path = '/users/live_locations'; + + when(() => client.get(path)).thenAnswer( + (_) async => successResponse( + path, + data: {'active_live_locations': []}, + ), + ); + + final res = await userApi.getActiveLiveLocations(); + + expect(res, isNotNull); + + verify(() => client.get(path)).called(1); + verifyNoMoreInteractions(client); + }); + + test('updateLiveLocation', () async { + const path = '/users/live_locations'; + const messageId = 'test-message-id'; + const createdByDeviceId = 'test-device-id'; + final endAt = DateTime.timestamp().add(const Duration(hours: 1)); + const coordinates = LocationCoordinates( + latitude: 40.7128, + longitude: -74.0060, + ); + + when( + () => client.put( + path, + data: json.encode({ + 'message_id': messageId, + 'created_by_device_id': createdByDeviceId, + 'latitude': coordinates.latitude, + 'longitude': coordinates.longitude, + 'end_at': endAt.toIso8601String(), + }), + ), + ).thenAnswer( + (_) async => successResponse( + path, + data: { + 'message_id': messageId, + 'created_by_device_id': createdByDeviceId, + 'latitude': coordinates.latitude, + 'longitude': coordinates.longitude, + 'end_at': endAt.toIso8601String(), + }, + ), + ); + + final res = await userApi.updateLiveLocation( + messageId: messageId, + createdByDeviceId: createdByDeviceId, + location: coordinates, + endAt: endAt, + ); + + expect(res, isNotNull); + + verify( + () => client.put( + path, + data: json.encode({ + 'message_id': messageId, + 'created_by_device_id': createdByDeviceId, + 'latitude': coordinates.latitude, + 'longitude': coordinates.longitude, + 'end_at': endAt.toIso8601String(), + }), + ), + ).called(1); + verifyNoMoreInteractions(client); + }); } diff --git a/packages/stream_chat/test/src/core/models/channel_state_test.dart b/packages/stream_chat/test/src/core/models/channel_state_test.dart index 6a436f1dcf..2d20cc8760 100644 --- a/packages/stream_chat/test/src/core/models/channel_state_test.dart +++ b/packages/stream_chat/test/src/core/models/channel_state_test.dart @@ -59,6 +59,7 @@ void main() { watcherCount: 5, pinnedMessages: [], watchers: [], + activeLiveLocations: [], ); expect( diff --git a/packages/stream_chat/test/src/core/models/location_test.dart b/packages/stream_chat/test/src/core/models/location_test.dart new file mode 100644 index 0000000000..2ddcfbaf5d --- /dev/null +++ b/packages/stream_chat/test/src/core/models/location_test.dart @@ -0,0 +1,200 @@ +import 'package:stream_chat/src/core/models/channel_model.dart'; +import 'package:stream_chat/src/core/models/location.dart'; +import 'package:stream_chat/src/core/models/location_coordinates.dart'; +import 'package:stream_chat/src/core/models/message.dart'; +import 'package:test/test.dart'; + +void main() { + group('Location', () { + const latitude = 37.7749; + const longitude = -122.4194; + const createdByDeviceId = 'device_123'; + + final location = Location( + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + ); + + test('should create a valid instance with minimal parameters', () { + expect(location.latitude, equals(latitude)); + expect(location.longitude, equals(longitude)); + expect(location.createdByDeviceId, equals(createdByDeviceId)); + expect(location.endAt, isNull); + expect(location.channelCid, isNull); + expect(location.channel, isNull); + expect(location.messageId, isNull); + expect(location.message, isNull); + expect(location.userId, isNull); + expect(location.createdAt, isA()); + expect(location.updatedAt, isA()); + }); + + test('should create a valid instance with all parameters', () { + final createdAt = DateTime.parse('2023-01-01T00:00:00.000Z'); + final updatedAt = DateTime.parse('2023-01-01T01:00:00.000Z'); + final endAt = DateTime.parse('2024-12-31T23:59:59.999Z'); + final channel = ChannelModel( + cid: 'test:channel', + id: 'channel', + type: 'test', + createdAt: createdAt, + updatedAt: updatedAt, + ); + final message = Message( + id: 'message_123', + text: 'Test message', + createdAt: createdAt, + updatedAt: updatedAt, + ); + + final fullLocation = Location( + channelCid: 'test:channel', + channel: channel, + messageId: 'message_123', + message: message, + userId: 'user_123', + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, + ); + + expect(fullLocation.channelCid, equals('test:channel')); + expect(fullLocation.channel, equals(channel)); + expect(fullLocation.messageId, equals('message_123')); + expect(fullLocation.message, equals(message)); + expect(fullLocation.userId, equals('user_123')); + expect(fullLocation.latitude, equals(latitude)); + expect(fullLocation.longitude, equals(longitude)); + expect(fullLocation.createdByDeviceId, equals(createdByDeviceId)); + expect(fullLocation.endAt, equals(endAt)); + expect(fullLocation.createdAt, equals(createdAt)); + expect(fullLocation.updatedAt, equals(updatedAt)); + }); + + test('should correctly serialize to JSON', () { + final json = location.toJson(); + + expect(json['latitude'], equals(latitude)); + expect(json['longitude'], equals(longitude)); + expect(json['created_by_device_id'], equals(createdByDeviceId)); + expect(json['end_at'], isNull); + expect(json.containsKey('channel_cid'), isFalse); + expect(json.containsKey('channel'), isFalse); + expect(json.containsKey('message_id'), isFalse); + expect(json.containsKey('message'), isFalse); + expect(json.containsKey('user_id'), isFalse); + expect(json.containsKey('created_at'), isFalse); + expect(json.containsKey('updated_at'), isFalse); + }); + + test('should serialize live location with endAt correctly', () { + final endAt = DateTime.parse('2024-12-31T23:59:59.999Z'); + final liveLocation = Location( + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: endAt, + ); + + final json = liveLocation.toJson(); + + expect(json['latitude'], equals(latitude)); + expect(json['longitude'], equals(longitude)); + expect(json['created_by_device_id'], equals(createdByDeviceId)); + expect(json['end_at'], equals('2024-12-31T23:59:59.999Z')); + }); + + test('should return correct coordinates', () { + final coordinates = location.coordinates; + + expect(coordinates, isA()); + expect(coordinates.latitude, equals(latitude)); + expect(coordinates.longitude, equals(longitude)); + }); + + test('isActive should return true for active live location', () { + final futureDate = DateTime.now().add(const Duration(hours: 1)); + final activeLocation = Location( + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: futureDate, + ); + + expect(activeLocation.isActive, isTrue); + expect(activeLocation.isExpired, isFalse); + }); + + test('isActive should return false for expired live location', () { + final pastDate = DateTime.now().subtract(const Duration(hours: 1)); + final expiredLocation = Location( + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: pastDate, + ); + + expect(expiredLocation.isActive, isFalse); + expect(expiredLocation.isExpired, isTrue); + }); + + test('isLive should return true for live location', () { + final futureDate = DateTime.now().add(const Duration(hours: 1)); + final liveLocation = Location( + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: futureDate, + ); + + expect(liveLocation.isLive, isTrue); + expect(liveLocation.isStatic, isFalse); + }); + + test('equality should work correctly', () { + final location1 = Location( + channelCid: 'test:channel', + messageId: 'message_123', + userId: 'user_123', + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: DateTime.parse('2024-12-31T23:59:59.999Z'), + createdAt: DateTime.parse('2023-01-01T00:00:00.000Z'), + updatedAt: DateTime.parse('2023-01-01T00:00:00.000Z'), + ); + + final location2 = Location( + channelCid: 'test:channel', + messageId: 'message_123', + userId: 'user_123', + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: DateTime.parse('2024-12-31T23:59:59.999Z'), + createdAt: DateTime.parse('2023-01-01T00:00:00.000Z'), + updatedAt: DateTime.parse('2023-01-01T00:00:00.000Z'), + ); + + final location3 = Location( + channelCid: 'test:channel', + messageId: 'message_123', + userId: 'user_123', + latitude: 40.7128, // Different latitude + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: DateTime.parse('2024-12-31T23:59:59.999Z'), + createdAt: DateTime.parse('2023-01-01T00:00:00.000Z'), + updatedAt: DateTime.parse('2023-01-01T00:00:00.000Z'), + ); + + expect(location1, equals(location2)); + expect(location1.hashCode, equals(location2.hashCode)); + expect(location1, isNot(equals(location3))); + }); + }); +} diff --git a/packages/stream_chat/test/src/core/util/event_controller_test.dart b/packages/stream_chat/test/src/core/util/event_controller_test.dart new file mode 100644 index 0000000000..a789d2826b --- /dev/null +++ b/packages/stream_chat/test/src/core/util/event_controller_test.dart @@ -0,0 +1,337 @@ +// ignore_for_file: cascade_invocations, avoid_redundant_argument_values + +import 'dart:async'; +import 'package:stream_chat/src/core/models/event.dart'; +import 'package:stream_chat/src/core/util/event_controller.dart'; +import 'package:stream_chat/src/event_type.dart'; +import 'package:test/test.dart'; + +void main() { + group('EventController events', () { + late EventController controller; + + setUp(() { + controller = EventController(); + }); + + tearDown(() { + controller.close(); + }); + + test('should emit events without resolvers', () async { + final event = Event(type: EventType.messageNew); + + final streamEvents = []; + controller.listen(streamEvents.add); + + controller.add(event); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.messageNew); + }); + + test('should apply resolvers in order', () async { + Event? firstResolver(Event event) { + if (event.type == EventType.messageNew) { + return event.copyWith(type: EventType.pollCreated); + } + return null; + } + + Event? secondResolver(Event event) { + if (event.type == EventType.pollCreated) { + return event.copyWith(type: EventType.locationShared); + } + return null; + } + + controller = EventController( + resolvers: [firstResolver, secondResolver], + ); + + final streamEvents = []; + controller.listen(streamEvents.add); + + final originalEvent = Event(type: EventType.messageNew); + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.pollCreated); + }); + + test('should stop at first matching resolver', () async { + var firstResolverCalled = false; + var secondResolverCalled = false; + + Event? firstResolver(Event event) { + firstResolverCalled = true; + if (event.type == EventType.messageNew) { + return event.copyWith(type: EventType.pollCreated); + } + return null; + } + + Event? secondResolver(Event event) { + secondResolverCalled = true; + return event.copyWith(type: EventType.locationShared); + } + + controller = EventController( + resolvers: [firstResolver, secondResolver], + ); + + final streamEvents = []; + controller.listen(streamEvents.add); + + final originalEvent = Event(type: EventType.messageNew); + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(firstResolverCalled, isTrue); + expect(secondResolverCalled, isFalse); + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.pollCreated); + }); + + test('should emit original event when no resolver matches', () async { + Event? resolver(Event event) { + if (event.type == EventType.pollCreated) { + return event.copyWith(type: EventType.locationShared); + } + return null; + } + + controller = EventController( + resolvers: [resolver], + ); + + final streamEvents = []; + controller.listen(streamEvents.add); + + final originalEvent = Event(type: EventType.messageNew); + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.messageNew); + }); + + test('should work with multiple resolvers that return null', () async { + Event? firstResolver(Event event) => null; + Event? secondResolver(Event event) => null; + Event? thirdResolver(Event event) => null; + + controller = EventController( + resolvers: [firstResolver, secondResolver, thirdResolver], + ); + + final streamEvents = []; + controller.listen(streamEvents.add); + + final originalEvent = Event(type: EventType.messageNew); + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.messageNew); + }); + + test('should handle empty resolvers list', () async { + controller = EventController(resolvers: []); + + final streamEvents = []; + controller.listen(streamEvents.add); + + final originalEvent = Event(type: EventType.messageNew); + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.messageNew); + }); + + test('should support custom onListen callback', () async { + var onListenCalled = false; + + controller = EventController( + onListen: () => onListenCalled = true, + ); + + expect(onListenCalled, isFalse); + + controller.listen((_) {}); + + expect(onListenCalled, isTrue); + }); + + test('should support custom onCancel callback', () async { + var onCancelCalled = false; + + controller = EventController( + onCancel: () => onCancelCalled = true, + ); + + final subscription = controller.listen((_) {}); + + expect(onCancelCalled, isFalse); + + await subscription.cancel(); + + expect(onCancelCalled, isTrue); + }); + + test('should support sync mode', () async { + controller = EventController(sync: true); + + final streamEvents = []; + controller.listen(streamEvents.add); + + final originalEvent = Event(type: EventType.messageNew); + controller.add(originalEvent); + + // In sync mode, events should be available immediately + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.messageNew); + }); + + test('should handle resolver exceptions gracefully', () async { + Event? failingResolver(Event event) { + throw Exception('Resolver failed'); + } + + Event? workingResolver(Event event) { + return event.copyWith(type: EventType.pollCreated); + } + + controller = EventController( + resolvers: [failingResolver, workingResolver], + ); + + final streamEvents = []; + controller.listen(streamEvents.add); + + final originalEvent = Event(type: EventType.messageNew); + + // This should throw an exception because the resolver throws + expect(() => controller.add(originalEvent), throwsException); + }); + + test('should be compatible with stream operations', () async { + final event1 = Event(type: EventType.messageNew); + final event2 = Event(type: EventType.messageUpdated); + + final streamEvents = []; + controller + .where((event) => event.type == EventType.messageNew) + .listen(streamEvents.add); + + controller.add(event1); + controller.add(event2); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + expect(streamEvents.first.type, EventType.messageNew); + }); + + test('should work with multiple listeners', () async { + final streamEvents1 = []; + final streamEvents2 = []; + + controller.listen(streamEvents1.add); + controller.listen(streamEvents2.add); + + final originalEvent = Event(type: EventType.messageNew); + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(streamEvents1, hasLength(1)); + expect(streamEvents2, hasLength(1)); + expect(streamEvents1.first.type, EventType.messageNew); + expect(streamEvents2.first.type, EventType.messageNew); + }); + + test('should preserve event properties through resolvers', () async { + final originalEvent = Event( + type: EventType.messageNew, + userId: 'user123', + cid: 'channel123', + connectionId: 'conn123', + me: null, + user: null, + extraData: {'custom': 'data'}, + ); + + Event? resolver(Event event) { + if (event.type == EventType.messageNew) { + return event.copyWith(type: EventType.pollCreated); + } + return null; + } + + controller = EventController( + resolvers: [resolver], + ); + + final streamEvents = []; + controller.listen(streamEvents.add); + + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + final resolvedEvent = streamEvents.first; + expect(resolvedEvent.type, EventType.pollCreated); + expect(resolvedEvent.userId, 'user123'); + expect(resolvedEvent.cid, 'channel123'); + expect(resolvedEvent.connectionId, 'conn123'); + expect(resolvedEvent.extraData, {'custom': 'data'}); + }); + + test('should handle resolver modifying event data', () async { + final originalEvent = Event( + type: EventType.messageNew, + userId: 'user123', + extraData: {'original': 'data'}, + ); + + Event? resolver(Event event) { + if (event.type == EventType.messageNew) { + return event.copyWith( + type: EventType.pollCreated, + userId: 'modified_user', + extraData: {'modified': 'data'}, + ); + } + return null; + } + + controller = EventController( + resolvers: [resolver], + ); + + final streamEvents = []; + controller.listen(streamEvents.add); + + controller.add(originalEvent); + + await Future.delayed(Duration.zero); + + expect(streamEvents, hasLength(1)); + final resolvedEvent = streamEvents.first; + expect(resolvedEvent.type, EventType.pollCreated); + expect(resolvedEvent.userId, 'modified_user'); + expect(resolvedEvent.extraData, {'modified': 'data'}); + }); + }); +} diff --git a/packages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dart b/packages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dart index fdd0ce95d2..09cda58d55 100644 --- a/packages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dart +++ b/packages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dart @@ -86,6 +86,10 @@ class StreamMessagePreviewText extends StatelessWidget { return _pollPreviewText(context, poll, currentUser); } + if (message.sharedLocation case final location?) { + return translations.locationLabel(isLive: location.isLive); + } + final previewText = _previewMessageContextText(context, message); if (previewText == null) return translations.emptyMessagePreviewText; diff --git a/packages/stream_chat_flutter/lib/src/localization/translations.dart b/packages/stream_chat_flutter/lib/src/localization/translations.dart index e08562e7a7..957ff7683e 100644 --- a/packages/stream_chat_flutter/lib/src/localization/translations.dart +++ b/packages/stream_chat_flutter/lib/src/localization/translations.dart @@ -545,6 +545,11 @@ abstract class Translations { /// The label for draft message String get draftLabel; + + /// The label for location attachment. + /// + /// [isLive] indicates if the location is live or not. + String locationLabel({bool isLive = false}); } /// Default implementation of Translation strings for the stream chat widgets @@ -1217,4 +1222,10 @@ Attachment limit exceeded: it's not possible to add more than $limit attachments @override String get draftLabel => 'Draft'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Live Location'; + return '📍 Location'; + } } diff --git a/packages/stream_chat_flutter/lib/src/message_input/quoted_message_widget.dart b/packages/stream_chat_flutter/lib/src/message_input/quoted_message_widget.dart index 24611a0a13..931ea553bc 100644 --- a/packages/stream_chat_flutter/lib/src/message_input/quoted_message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_input/quoted_message_widget.dart @@ -151,9 +151,17 @@ class _QuotedMessage extends StatelessWidget { Flexible( child: Text( '📊 ${message.poll?.name}', - style: messageTheme.messageTextStyle?.copyWith( - fontSize: 12, - ), + style: messageTheme.messageTextStyle?.copyWith(fontSize: 12), + ), + ), + ]; + } else if (message.sharedLocation case final location?) { + // Show shared location message + children = [ + Flexible( + child: Text( + context.translations.locationLabel(isLive: location.isLive), + style: messageTheme.messageTextStyle?.copyWith(fontSize: 12), ), ), ]; diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 0e85fffd66..6a824da2b5 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,3 +1,7 @@ +## Upcoming Beta + +- Added translations for new `locationLabel` label. + ## 10.0.0-beta.3 - Included the changes from version [`9.14.0`](https://pub.dev/packages/stream_chat_localizations/changelog). diff --git a/packages/stream_chat_localizations/example/lib/add_new_lang.dart b/packages/stream_chat_localizations/example/lib/add_new_lang.dart index aa65d95ce9..0921a52519 100644 --- a/packages/stream_chat_localizations/example/lib/add_new_lang.dart +++ b/packages/stream_chat_localizations/example/lib/add_new_lang.dart @@ -692,6 +692,12 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations { @override String get draftLabel => 'Draft'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Live Location'; + return '📍 Location'; + } } void main() async { diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart index 1986b0f0fc..eb5894392c 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ca.dart @@ -674,4 +674,10 @@ class StreamChatLocalizationsCa extends GlobalStreamChatLocalizations { @override String get draftLabel => 'Esborrany'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Ubicació en directe'; + return '📍 Ubicació'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart index 93b1e2c28b..910eb7270b 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart @@ -666,4 +666,10 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations { @override String get draftLabel => 'Entwurf'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Live-Standort'; + return '📍 Standort'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart index fdc85f41cc..9b2a00263a 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart @@ -669,4 +669,10 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { @override String get draftLabel => 'Draft'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Live Location'; + return '📍 Location'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart index 887854d929..4362dfc712 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart @@ -676,4 +676,10 @@ No es posible añadir más de $limit archivos adjuntos @override String get draftLabel => 'Borrador'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Ubicación en vivo'; + return '📍 Ubicación'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart index 7c1fcbc994..7af6c9d6bf 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart @@ -678,4 +678,10 @@ Limite de pièces jointes dépassée : il n'est pas possible d'ajouter plus de $ @override String get draftLabel => 'Brouillon'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Position en direct'; + return '📍 Position'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart index 34694c6466..3302b54f7e 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart @@ -671,4 +671,10 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { @override String get draftLabel => 'ड्राफ्ट'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 लाइव लोकेशन'; + return '📍 लोकेशन'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart index 0f4ab0b2a4..a32a46ff04 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart @@ -680,4 +680,10 @@ Attenzione: il limite massimo di $limit file è stato superato. @override String get draftLabel => 'Bozza'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Posizione dal vivo'; + return '📍 Posizione'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart index c5a714075e..34fef9844b 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart @@ -645,4 +645,10 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { @override String get draftLabel => '下書き'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 ライブ位置情報'; + return '📍 位置情報'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart index 62b14d818b..3fec27ffa4 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart @@ -649,4 +649,10 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations { @override String get draftLabel => '임시글'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 실시간 위치'; + return '📍 위치'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart index d1a841e01e..a02387c433 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_no.dart @@ -659,4 +659,10 @@ class StreamChatLocalizationsNo extends GlobalStreamChatLocalizations { @override String get draftLabel => 'Utkast'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Direkte posisjon'; + return '📍 Posisjon'; + } } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart index 415ddd0ecd..24508b70e1 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart @@ -674,4 +674,10 @@ Não é possível adicionar mais de $limit arquivos de uma vez @override String get draftLabel => 'Rascunho'; + + @override + String locationLabel({bool isLive = false}) { + if (isLive) return '📍 Localização ao Vivo'; + return '📍 Localização'; + } } diff --git a/packages/stream_chat_localizations/test/translations_test.dart b/packages/stream_chat_localizations/test/translations_test.dart index 4f11894f86..18757b4371 100644 --- a/packages/stream_chat_localizations/test/translations_test.dart +++ b/packages/stream_chat_localizations/test/translations_test.dart @@ -309,6 +309,8 @@ void main() { expect(localizations.pollYouCreatedText, isNotNull); expect(localizations.pollSomeoneCreatedText('TestUser'), isNotNull); expect(localizations.systemMessageLabel, isNotNull); + expect(localizations.draftLabel, isNotNull); + expect(localizations.locationLabel(), isNotNull); }); } diff --git a/sample_app/android/app/src/main/AndroidManifest.xml b/sample_app/android/app/src/main/AndroidManifest.xml index 8ff8f0abb5..6fb866b633 100644 --- a/sample_app/android/app/src/main/AndroidManifest.xml +++ b/sample_app/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,13 @@ + + + + + + + ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) + ITSAppUsesNonExemptEncryption + LSRequiresIPhoneOS + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSAppleMusicUsageDescription Used to send message attachments NSCameraUsageDescription Used to send message attachments + NSLocationWhenInUseUsageDescription + We need access to your location to share it in the chat. + NSLocationAlwaysUsageDescription + We need access to your location to share it in the chat. NSMicrophoneUsageDescription Used to send message attachments NSPhotoLibraryUsageDescription @@ -43,6 +54,7 @@ fetch remote-notification + location UILaunchStoryboardName LaunchScreen @@ -65,12 +77,5 @@ UIViewControllerBasedStatusBarAppearance - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - ITSAppUsesNonExemptEncryption - diff --git a/sample_app/lib/pages/channel_list_page.dart b/sample_app/lib/pages/channel_list_page.dart index 63613c0c8b..6d8f6ae545 100644 --- a/sample_app/lib/pages/channel_list_page.dart +++ b/sample_app/lib/pages/channel_list_page.dart @@ -17,6 +17,7 @@ import 'package:sample_app/routes/routes.dart'; import 'package:sample_app/state/init_data.dart'; import 'package:sample_app/utils/app_config.dart'; import 'package:sample_app/utils/localizations.dart'; +import 'package:sample_app/utils/shared_location_service.dart'; import 'package:sample_app/widgets/channel_list.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:streaming_shared_preferences/streaming_shared_preferences.dart'; @@ -105,6 +106,10 @@ class _ChannelListPageState extends State { ]; } + late final _locationService = SharedLocationService( + client: StreamChat.of(context).client, + ); + @override Widget build(BuildContext context) { final user = StreamChat.of(context).currentUser; @@ -156,6 +161,7 @@ class _ChannelListPageState extends State { @override void initState() { + super.initState(); if (!kIsWeb) { badgeListener = StreamChat.of(context) .client @@ -169,12 +175,14 @@ class _ChannelListPageState extends State { } }); } - super.initState(); + + _locationService.initialize(); } @override void dispose() { badgeListener?.cancel(); + _locationService.dispose(); super.dispose(); } } diff --git a/sample_app/lib/pages/channel_page.dart b/sample_app/lib/pages/channel_page.dart index ba7603935f..988ac96959 100644 --- a/sample_app/lib/pages/channel_page.dart +++ b/sample_app/lib/pages/channel_page.dart @@ -5,6 +5,10 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:sample_app/pages/thread_page.dart'; import 'package:sample_app/routes/routes.dart'; +import 'package:sample_app/widgets/location/location_attachment.dart'; +import 'package:sample_app/widgets/location/location_detail_dialog.dart'; +import 'package:sample_app/widgets/location/location_picker_dialog.dart'; +import 'package:sample_app/widgets/location/location_picker_option.dart'; import 'package:sample_app/widgets/reminder_dialog.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -25,8 +29,7 @@ class ChannelPage extends StatefulWidget { class _ChannelPageState extends State { FocusNode? _focusNode; - final StreamMessageInputController _messageInputController = - StreamMessageInputController(); + final _messageInputController = StreamMessageInputController(); @override void initState() { @@ -53,6 +56,9 @@ class _ChannelPageState extends State { final textTheme = theme.textTheme; final colorTheme = theme.colorTheme; + final channel = StreamChannel.of(context).channel; + final config = channel.config; + return Scaffold( backgroundColor: colorTheme.appBg, appBar: StreamChannelHeader( @@ -124,12 +130,73 @@ class _ChannelPageState extends State { messageInputController: _messageInputController, onQuotedMessageCleared: _messageInputController.clearQuotedMessage, enableVoiceRecording: true, + allowedAttachmentPickerTypes: [ + ...AttachmentPickerType.values, + if (config?.sharedLocations == true && channel.canShareLocation) + const LocationPickerType(), + ], + onCustomAttachmentPickerResult: (result) { + return _onCustomAttachmentPickerResult(channel, result).ignore(); + }, + customAttachmentPickerOptions: [ + TabbedAttachmentPickerOption( + key: 'location-picker', + icon: const Icon(Icons.near_me_rounded), + supportedTypes: [const LocationPickerType()], + isEnabled: (value) { + // Enable if nothing has been selected yet. + if (value.isEmpty) return true; + + // Otherwise, enable only if there is a location. + return value.extraData['location'] != null; + }, + optionViewBuilder: (context, controller) => LocationPicker( + onLocationPicked: (locationResult) { + if (locationResult == null) return Navigator.pop(context); + + controller.extraData = { + ...controller.value.extraData, + 'location': locationResult, + }; + + final result = LocationPicked(location: locationResult); + return Navigator.pop(context, result); + }, + ), + ), + ], ), ], ), ); } + Future _onCustomAttachmentPickerResult( + Channel channel, + CustomAttachmentPickerResult result, + ) async { + final response = switch (result) { + LocationPicked() => _onShareLocationPicked(channel, result.location), + _ => null, + }; + + return response?.ignore(); + } + + Future _onShareLocationPicked( + Channel channel, + LocationPickerResult result, + ) async { + if (result.endSharingAt case final endSharingAt?) { + return channel.startLiveLocationSharing( + endSharingAt: endSharingAt, + location: result.coordinates, + ); + } + + return channel.sendStaticLocation(location: result.coordinates); + } + Widget customMessageBuilder( BuildContext context, MessageDetails details, @@ -142,7 +209,8 @@ class _ChannelPageState extends State { final message = details.message; final reminder = message.reminder; - final channelConfig = StreamChannel.of(context).channel.config; + final channel = StreamChannel.of(context).channel; + final channelConfig = channel.config; final customOptions = [ if (channelConfig?.userMessageReminders == true) ...[ @@ -184,6 +252,13 @@ class _ChannelPageState extends State { ] ]; + final locationAttachmentBuilder = LocationAttachmentBuilder( + onAttachmentTap: (location) => showLocationDetailDialog( + context: context, + location: location, + ), + ); + return Container( color: reminder != null ? colorTheme.accentPrimary.withOpacity(.1) : null, child: Column( @@ -220,6 +295,7 @@ class _ChannelPageState extends State { defaultMessageWidget.copyWith( onReplyTap: _reply, customActions: customOptions, + showEditMessage: message.sharedLocation == null, onCustomActionTap: (it) async => await switch (it) { CreateReminder() => _createReminder(it.message), CreateBookmark() => _createBookmark(it.message), @@ -227,6 +303,7 @@ class _ChannelPageState extends State { RemoveReminder() => _removeReminder(it.message, it.reminder), _ => null, }, + attachmentBuilders: [locationAttachmentBuilder], onShowMessage: (message, channel) => GoRouter.of(context).goNamed( Routes.CHANNEL_PAGE.name, pathParameters: Routes.CHANNEL_PAGE.params(channel), diff --git a/sample_app/lib/pages/thread_page.dart b/sample_app/lib/pages/thread_page.dart index 622b5772ca..3e8376eb44 100644 --- a/sample_app/lib/pages/thread_page.dart +++ b/sample_app/lib/pages/thread_page.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:sample_app/widgets/location/location_attachment.dart'; +import 'package:sample_app/widgets/location/location_detail_dialog.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class ThreadPage extends StatefulWidget { @@ -43,6 +45,13 @@ class _ThreadPageState extends State { @override Widget build(BuildContext context) { + final locationAttachmentBuilder = LocationAttachmentBuilder( + onAttachmentTap: (location) => showLocationDetailDialog( + context: context, + location: location, + ), + ); + return Scaffold( backgroundColor: StreamChatTheme.of(context).colorTheme.appBg, appBar: StreamThreadHeader( @@ -59,9 +68,18 @@ class _ThreadPageState extends State { messageFilter: defaultFilter, showScrollToBottom: false, highlightInitialMessage: true, + parentMessageBuilder: (context, message, defaultMessage) { + return defaultMessage.copyWith( + attachmentBuilders: [locationAttachmentBuilder], + ); + }, messageBuilder: (context, details, messages, defaultMessage) { + final message = details.message; + return defaultMessage.copyWith( onReplyTap: _reply, + showEditMessage: message.sharedLocation == null, + attachmentBuilders: [locationAttachmentBuilder], bottomRowBuilderWithDefaultWidget: ( context, message, diff --git a/sample_app/lib/utils/location_provider.dart b/sample_app/lib/utils/location_provider.dart new file mode 100644 index 0000000000..fbf7168028 --- /dev/null +++ b/sample_app/lib/utils/location_provider.dart @@ -0,0 +1,98 @@ +// ignore_for_file: close_sinks + +import 'dart:async'; + +import 'package:geolocator/geolocator.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +const notificationTitle = 'Live Location Tracking'; +const notificationText = 'Your location is being tracked live.'; + +class LocationProvider { + factory LocationProvider() => _instance; + LocationProvider._(); + + static final LocationProvider _instance = LocationProvider._(); + + Stream get positionStream => _positionStreamController.stream; + final _positionStreamController = StreamController.broadcast(); + + StreamSubscription? _positionSubscription; + + /// Opens the device's location settings page. + /// + /// Returns [true] if the location settings page could be opened, otherwise + /// [false] is returned. + Future openLocationSettings() => Geolocator.openLocationSettings(); + + /// Get current static location + Future getCurrentLocation() async { + final hasPermission = await _handlePermission(); + if (!hasPermission) return null; + + return Geolocator.getCurrentPosition(); + } + + /// Start live tracking + Future startTracking({ + int distanceFilter = 10, + LocationAccuracy accuracy = LocationAccuracy.high, + ActivityType activityType = ActivityType.automotiveNavigation, + }) async { + final hasPermission = await _handlePermission(); + if (!hasPermission) return; + + final settings = switch (CurrentPlatform.type) { + PlatformType.android => AndroidSettings( + accuracy: accuracy, + distanceFilter: distanceFilter, + foregroundNotificationConfig: const ForegroundNotificationConfig( + setOngoing: true, + notificationText: notificationText, + notificationTitle: notificationTitle, + notificationIcon: AndroidResource(name: 'ic_notification'), + ), + ), + PlatformType.ios || PlatformType.macOS => AppleSettings( + accuracy: accuracy, + activityType: activityType, + distanceFilter: distanceFilter, + showBackgroundLocationIndicator: true, + pauseLocationUpdatesAutomatically: true, + ), + _ => LocationSettings( + accuracy: accuracy, + distanceFilter: distanceFilter, + ) + }; + + _positionSubscription?.cancel(); // avoid duplicate subscriptions + _positionSubscription = Geolocator.getPositionStream( + locationSettings: settings, + ).listen( + _positionStreamController.safeAdd, + onError: _positionStreamController.safeAddError, + ); + } + + /// Stop live tracking + void stopTracking() { + _positionSubscription?.cancel(); + _positionSubscription = null; + } + + Future _handlePermission() async { + final serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) return false; + + var permission = await Geolocator.checkPermission(); + if (permission == LocationPermission.denied) { + permission = await Geolocator.requestPermission(); + } + + return switch (permission) { + LocationPermission.denied || LocationPermission.deniedForever => false, + _ => true, + }; + } +} diff --git a/sample_app/lib/utils/shared_location_service.dart b/sample_app/lib/utils/shared_location_service.dart new file mode 100644 index 0000000000..1d7a7128c6 --- /dev/null +++ b/sample_app/lib/utils/shared_location_service.dart @@ -0,0 +1,88 @@ +import 'dart:async'; + +import 'package:geolocator/geolocator.dart'; +import 'package:rxdart/rxdart.dart'; +import 'package:sample_app/utils/location_provider.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +class SharedLocationService { + SharedLocationService({ + required StreamChatClient client, + LocationProvider? locationProvider, + }) : _client = client, + _locationProvider = locationProvider ?? LocationProvider(); + + final StreamChatClient _client; + final LocationProvider _locationProvider; + + StreamSubscription? _positionSubscription; + StreamSubscription>? _activeLiveLocationsSubscription; + + Future initialize() async { + _activeLiveLocationsSubscription?.cancel(); + _activeLiveLocationsSubscription = _client.state.activeLiveLocationsStream + .distinct((prev, curr) => prev.length == curr.length) + .listen((locations) async { + // If there are no more active locations to update, stop tracking. + if (locations.isEmpty) return _stopTrackingLocation(); + + // Otherwise, start tracking the user's location. + return _startTrackingLocation(); + }); + + return _client.getActiveLiveLocations().ignore(); + } + + Future _startTrackingLocation() async { + if (_positionSubscription != null) return; + + // Start listening to the position stream. + _positionSubscription = _locationProvider.positionStream + .throttleTime(const Duration(seconds: 3)) + .listen(_onPositionUpdate); + + return _locationProvider.startTracking(); + } + + void _stopTrackingLocation() { + _locationProvider.stopTracking(); + + // Stop tracking the user's location + _positionSubscription?.cancel(); + _positionSubscription = null; + } + + void _onPositionUpdate(Position position) { + // Handle location updates, e.g., update the UI or send to server + final activeLiveLocations = _client.state.activeLiveLocations; + if (activeLiveLocations.isEmpty) return _stopTrackingLocation(); + + // Update all active live locations + for (final location in activeLiveLocations) { + // Skip if the location is not live or has expired + if (location.isLive && location.isExpired) continue; + + // Skip if the location does not have a messageId + final messageId = location.messageId; + if (messageId == null) continue; + + // Update the live location with the new position + _client.updateLiveLocation( + messageId: messageId, + createdByDeviceId: location.createdByDeviceId, + location: LocationCoordinates( + latitude: position.latitude, + longitude: position.longitude, + ), + ); + } + } + + /// Clean up resources + Future dispose() async { + _stopTrackingLocation(); + + _activeLiveLocationsSubscription?.cancel(); + _activeLiveLocationsSubscription = null; + } +} diff --git a/sample_app/lib/widgets/channel_list.dart b/sample_app/lib/widgets/channel_list.dart index c2dab2bb85..a87e51b012 100644 --- a/sample_app/lib/widgets/channel_list.dart +++ b/sample_app/lib/widgets/channel_list.dart @@ -61,7 +61,7 @@ class _ChannelList extends State { ChannelSortKey.pinnedAt, nullOrdering: NullOrdering.nullsLast, ), - const SortOption.desc(ChannelSortKey.lastMessageAt), + const SortOption.desc(ChannelSortKey.lastUpdated), ], limit: 30, ); diff --git a/sample_app/lib/widgets/location/location_attachment.dart b/sample_app/lib/widgets/location/location_attachment.dart new file mode 100644 index 0000000000..405f97b7df --- /dev/null +++ b/sample_app/lib/widgets/location/location_attachment.dart @@ -0,0 +1,235 @@ +import 'package:flutter/material.dart'; +import 'package:sample_app/widgets/location/location_user_marker.dart'; +import 'package:sample_app/widgets/simple_map_view.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +const _defaultLocationConstraints = BoxConstraints( + maxWidth: 270, + maxHeight: 180, +); + +/// {@template locationAttachmentBuilder} +/// A builder for creating a location attachment widget. +/// {@endtemplate} +class LocationAttachmentBuilder extends StreamAttachmentWidgetBuilder { + /// {@macro locationAttachmentBuilder} + const LocationAttachmentBuilder({ + this.constraints = _defaultLocationConstraints, + this.padding = const EdgeInsets.all(4), + this.onAttachmentTap, + }); + + /// The constraints to apply to the file attachment widget. + final BoxConstraints constraints; + + /// The padding to apply to the file attachment widget. + final EdgeInsetsGeometry padding; + + /// Optional callback to handle tap events on the attachment. + final ValueSetter? onAttachmentTap; + + @override + bool canHandle(Message message, _) => message.sharedLocation != null; + + @override + Widget build(BuildContext context, Message message, _) { + assert(debugAssertCanHandle(message, _), ''); + + final user = message.user; + final location = message.sharedLocation!; + return LocationAttachment( + user: user, + sharedLocation: location, + constraints: constraints, + padding: padding, + onLocationTap: switch (onAttachmentTap) { + final onTap? => () => onTap(location), + _ => null, + }, + ); + } +} + +/// Displays a location attachment with a map view and optional footer. +class LocationAttachment extends StatelessWidget { + /// Creates a new [LocationAttachment]. + const LocationAttachment({ + super.key, + required this.user, + required this.sharedLocation, + this.constraints = _defaultLocationConstraints, + this.padding = const EdgeInsets.all(2), + this.onLocationTap, + }); + + /// The user who shared the location. + final User? user; + + /// The shared location data. + final Location sharedLocation; + + /// The constraints to apply to the file attachment widget. + final BoxConstraints constraints; + + /// The padding to apply to the file attachment widget. + final EdgeInsetsGeometry padding; + + /// Optional callback to handle tap events on the location attachment. + final VoidCallback? onLocationTap; + + @override + Widget build(BuildContext context) { + final currentUser = StreamChat.of(context).currentUser; + final sharedLocationEndAt = sharedLocation.endAt; + + return Padding( + padding: padding, + child: ConstrainedBox( + constraints: constraints, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Material( + clipBehavior: Clip.antiAlias, + type: MaterialType.transparency, + borderRadius: BorderRadius.circular(14), + child: InkWell( + onTap: onLocationTap, + child: IgnorePointer( + child: SimpleMapView( + markerSize: 40, + showLocateMeButton: false, + coordinates: sharedLocation.coordinates, + markerBuilder: (_, __, size) => LocationUserMarker( + user: user, + markerSize: size, + sharedLocation: sharedLocation, + ), + ), + ), + ), + ), + ), + if (sharedLocationEndAt != null && currentUser != null) + LocationAttachmentFooter( + currentUser: currentUser, + sharingEndAt: sharedLocationEndAt, + sharedLocation: sharedLocation, + onStopSharingPressed: () { + final client = StreamChat.of(context).client; + + final location = sharedLocation; + final messageId = location.messageId; + if (messageId == null) return; + + client.stopLiveLocation( + messageId: messageId, + createdByDeviceId: location.createdByDeviceId, + ); + }, + ), + ], + ), + ), + ); + } +} + +class LocationAttachmentFooter extends StatelessWidget { + const LocationAttachmentFooter({ + super.key, + required this.currentUser, + required this.sharingEndAt, + required this.sharedLocation, + this.onStopSharingPressed, + }); + + final User currentUser; + final DateTime sharingEndAt; + final Location sharedLocation; + final VoidCallback? onStopSharingPressed; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final textTheme = theme.textTheme; + final colorTheme = theme.colorTheme; + + const maximumSize = Size(double.infinity, 40); + + // If the location sharing has ended, show a message indicating that. + if (sharingEndAt.isBefore(DateTime.now())) { + return SizedBox.fromSize( + size: maximumSize, + child: Row( + spacing: 8, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.near_me_disabled_rounded, + color: colorTheme.textLowEmphasis, + ), + Text( + 'Live location ended', + style: textTheme.bodyBold.copyWith( + color: colorTheme.textLowEmphasis, + ), + ), + ], + ), + ); + } + + final currentUserId = currentUser.id; + final sharedLocationUserId = sharedLocation.userId; + + // If the shared location is not shared by the current user, show the + // "Live until" duration text. + if (sharedLocationUserId != currentUserId) { + final liveUntil = Jiffy.parseFromDateTime(sharingEndAt.toLocal()); + + return SizedBox.fromSize( + size: maximumSize, + child: Row( + spacing: 8, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.near_me_rounded, + color: colorTheme.accentPrimary, + ), + Text( + 'Live until ${liveUntil.jm}', + style: textTheme.bodyBold.copyWith( + color: colorTheme.accentPrimary, + ), + ), + ], + ), + ); + } + + // Otherwise, show the "Stop Sharing" button. + final buttonStyle = TextButton.styleFrom( + maximumSize: maximumSize, + textStyle: textTheme.bodyBold, + visualDensity: VisualDensity.compact, + foregroundColor: colorTheme.accentError, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + ); + + return TextButton.icon( + style: buttonStyle, + onPressed: onStopSharingPressed, + icon: Icon( + Icons.near_me_disabled_rounded, + color: colorTheme.accentError, + ), + label: const Text('Stop Sharing'), + ); + } +} diff --git a/sample_app/lib/widgets/location/location_detail_dialog.dart b/sample_app/lib/widgets/location/location_detail_dialog.dart new file mode 100644 index 0000000000..c5082bf365 --- /dev/null +++ b/sample_app/lib/widgets/location/location_detail_dialog.dart @@ -0,0 +1,312 @@ +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:sample_app/widgets/location/location_user_marker.dart'; +import 'package:sample_app/widgets/simple_map_view.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +Future showLocationDetailDialog({ + required BuildContext context, + required Location location, +}) async { + final navigator = Navigator.of(context); + return navigator.push( + MaterialPageRoute( + fullscreenDialog: true, + builder: (_) => StreamChannel( + channel: StreamChannel.of(context).channel, + child: LocationDetailDialog(sharedLocation: location), + ), + ), + ); +} + +Stream _findLocationMessageStream( + Channel channel, + Location location, +) { + final messageId = location.messageId; + if (messageId == null) return Stream.value(null); + + final channelState = channel.state; + if (channelState == null) return Stream.value(null); + + return channelState.messagesStream.map((messages) { + return messages.firstWhereOrNull((message) => message.id == messageId); + }); +} + +class LocationDetailDialog extends StatelessWidget { + const LocationDetailDialog({ + super.key, + required this.sharedLocation, + }); + + final Location sharedLocation; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + final channel = StreamChannel.of(context).channel; + final locationStream = _findLocationMessageStream(channel, sharedLocation); + + return Scaffold( + backgroundColor: colorTheme.appBg, + appBar: AppBar( + backgroundColor: colorTheme.barsBg, + title: const Text('Shared Location'), + ), + body: BetterStreamBuilder( + stream: locationStream, + errorBuilder: (_, __) => const Center(child: LocationNotFound()), + noDataBuilder: (_) => const Center(child: CircularProgressIndicator()), + builder: (context, message) { + final sharedLocation = message.sharedLocation; + if (sharedLocation == null) { + return const Center(child: LocationNotFound()); + } + + return Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + SimpleMapView( + cameraZoom: 16, + markerSize: 48, + coordinates: sharedLocation.coordinates, + markerBuilder: (_, __, size) => LocationUserMarker( + user: message.user, + markerSize: size, + sharedLocation: sharedLocation, + ), + ), + if (sharedLocation.isLive) + LocationDetailBottomSheet( + sharedLocation: sharedLocation, + onStopSharingPressed: () { + final client = StreamChat.of(context).client; + + final messageId = sharedLocation.messageId; + if (messageId == null) return; + + client.stopLiveLocation( + messageId: messageId, + createdByDeviceId: sharedLocation.createdByDeviceId, + ); + }, + ), + ], + ); + }, + ), + ); + } +} + +class LocationNotFound extends StatelessWidget { + const LocationNotFound({super.key}); + + @override + Widget build(BuildContext context) { + final chatThemeData = StreamChatTheme.of(context); + final colorTheme = chatThemeData.colorTheme; + final textTheme = chatThemeData.textTheme; + + return Column( + spacing: 8, + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + size: 48, + Icons.near_me_disabled_rounded, + color: colorTheme.accentError, + ), + Text( + 'Location not found', + style: textTheme.headline.copyWith( + color: colorTheme.textHighEmphasis, + ), + ), + Text( + 'The location you are looking for is not available.', + style: textTheme.body.copyWith( + color: colorTheme.textLowEmphasis, + ), + ), + ], + ); + } +} + +class LocationDetailBottomSheet extends StatelessWidget { + const LocationDetailBottomSheet({ + super.key, + required this.sharedLocation, + this.onStopSharingPressed, + }); + + final Location sharedLocation; + final VoidCallback? onStopSharingPressed; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + return Material( + color: colorTheme.barsBg, + borderRadius: const BorderRadiusDirectional.only( + topEnd: Radius.circular(14), + topStart: Radius.circular(14), + ), + child: SafeArea( + minimum: const EdgeInsets.all(8), + child: LocationDetail( + sharedLocation: sharedLocation, + onStopSharingPressed: onStopSharingPressed, + ), + ), + ); + } +} + +class LocationDetail extends StatelessWidget { + const LocationDetail({ + super.key, + required this.sharedLocation, + this.onStopSharingPressed, + }); + + final Location sharedLocation; + final VoidCallback? onStopSharingPressed; + + @override + Widget build(BuildContext context) { + assert( + sharedLocation.isLive, + 'Footer should only be shown for live locations', + ); + + final theme = StreamChatTheme.of(context); + final textTheme = theme.textTheme; + final colorTheme = theme.colorTheme; + + final updatedAt = sharedLocation.updatedAt; + final sharingEndAt = sharedLocation.endAt!; + const maximumButtonSize = Size(double.infinity, 40); + + if (sharingEndAt.isBefore(DateTime.now())) { + final jiffyUpdatedAt = Jiffy.parseFromDateTime(updatedAt.toLocal()); + + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox.fromSize( + size: maximumButtonSize, + child: Row( + spacing: 8, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.near_me_disabled_rounded, + color: colorTheme.accentError, + ), + Text( + 'Live location ended', + style: textTheme.headlineBold.copyWith( + color: colorTheme.accentError, + ), + ), + ], + ), + ), + Text( + 'Location last updated at ${jiffyUpdatedAt.jm}', + style: textTheme.body.copyWith( + color: colorTheme.textLowEmphasis, + ), + ), + ], + ); + } + + final sharedLocationUserId = sharedLocation.userId; + final currentUserId = StreamChat.of(context).currentUser?.id; + + // If the shared location is not shared by the current user, show the + // "Live until" duration text. + if (sharedLocationUserId != currentUserId) { + final jiffySharingEndAt = Jiffy.parseFromDateTime(sharingEndAt.toLocal()); + + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox.fromSize( + size: maximumButtonSize, + child: Row( + spacing: 8, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.near_me_rounded, + color: colorTheme.accentPrimary, + ), + Text( + 'Live Location', + style: textTheme.headlineBold.copyWith( + color: colorTheme.accentPrimary, + ), + ), + ], + ), + ), + Text( + 'Live until ${jiffySharingEndAt.jm}', + style: textTheme.body.copyWith( + color: colorTheme.textLowEmphasis, + ), + ), + ], + ); + } + + // Otherwise, show the "Stop Sharing" button. + final buttonStyle = TextButton.styleFrom( + maximumSize: maximumButtonSize, + textStyle: textTheme.headlineBold, + visualDensity: VisualDensity.compact, + foregroundColor: colorTheme.accentError, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + ); + + final jiffySharingEndAt = Jiffy.parseFromDateTime(sharingEndAt.toLocal()); + + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: TextButton.icon( + style: buttonStyle, + onPressed: onStopSharingPressed, + icon: Icon( + Icons.near_me_disabled_rounded, + color: colorTheme.accentError, + ), + label: const Text('Stop Sharing'), + ), + ), + Center( + child: Text( + 'Live until ${jiffySharingEndAt.jm}', + style: textTheme.body.copyWith( + color: colorTheme.textLowEmphasis, + ), + ), + ), + ], + ); + } +} diff --git a/sample_app/lib/widgets/location/location_picker_dialog.dart b/sample_app/lib/widgets/location/location_picker_dialog.dart new file mode 100644 index 0000000000..1abaaf9e1c --- /dev/null +++ b/sample_app/lib/widgets/location/location_picker_dialog.dart @@ -0,0 +1,362 @@ +import 'package:avatar_glow/avatar_glow.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:sample_app/utils/location_provider.dart'; +import 'package:sample_app/widgets/simple_map_view.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +class LocationPickerResult { + const LocationPickerResult({ + this.endSharingAt, + required this.coordinates, + }); + + final DateTime? endSharingAt; + final LocationCoordinates coordinates; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + return other is LocationPickerResult && + runtimeType == other.runtimeType && + endSharingAt == other.endSharingAt && + coordinates == other.coordinates; + } + + @override + int get hashCode => endSharingAt.hashCode ^ coordinates.hashCode; +} + +Future showLocationPickerDialog({ + required BuildContext context, + bool barrierDismissible = true, + Color? barrierColor, + String? barrierLabel, + bool useSafeArea = true, + bool useRootNavigator = false, + RouteSettings? routeSettings, + Offset? anchorPoint, + EdgeInsets padding = const EdgeInsets.all(16), + TraversalEdgeBehavior? traversalEdgeBehavior, +}) { + final navigator = Navigator.of(context, rootNavigator: useRootNavigator); + return navigator.push( + MaterialPageRoute( + fullscreenDialog: true, + barrierDismissible: barrierDismissible, + builder: (context) => const LocationPickerDialog(), + ), + ); +} + +class LocationPickerDialog extends StatefulWidget { + const LocationPickerDialog({super.key}); + + @override + State createState() => _LocationPickerDialogState(); +} + +class _LocationPickerDialogState extends State { + LocationCoordinates? _currentLocation; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + return Scaffold( + backgroundColor: colorTheme.appBg, + appBar: AppBar( + backgroundColor: colorTheme.barsBg, + title: const Text('Share Location'), + ), + body: Stack( + alignment: AlignmentDirectional.bottomCenter, + children: [ + FutureBuilder( + future: LocationProvider().getCurrentLocation(), + builder: (context, snapshot) { + if (snapshot.connectionState != ConnectionState.done) { + return const Center( + child: CircularProgressIndicator.adaptive(), + ); + } + + final position = snapshot.data; + if (snapshot.hasError || position == null) { + return const Center(child: LocationNotFound()); + } + + final coordinates = _currentLocation = LocationCoordinates( + latitude: position.latitude, + longitude: position.longitude, + ); + + return SimpleMapView( + cameraZoom: 18, + markerSize: 24, + coordinates: coordinates, + markerBuilder: (context, _, size) => AvatarGlow( + glowColor: colorTheme.accentPrimary, + child: Material( + elevation: 2, + shape: CircleBorder( + side: BorderSide( + width: 4, + color: colorTheme.barsBg, + ), + ), + child: CircleAvatar( + radius: size / 2, + backgroundColor: colorTheme.accentPrimary, + ), + ), + ), + ); + }, + ), + // Location picker options + LocationPickerOptionList( + onOptionSelected: (option) { + final currentLocation = _currentLocation; + if (currentLocation == null) return Navigator.pop(context); + + final result = LocationPickerResult( + endSharingAt: switch (option) { + ShareStaticLocation() => null, + ShareLiveLocation() => option.endSharingAt, + }, + coordinates: currentLocation, + ); + + return Navigator.pop(context, result); + }, + ), + ], + ), + ); + } +} + +class LocationNotFound extends StatelessWidget { + const LocationNotFound({super.key}); + + @override + Widget build(BuildContext context) { + final chatThemeData = StreamChatTheme.of(context); + final colorTheme = chatThemeData.colorTheme; + final textTheme = chatThemeData.textTheme; + + return Column( + spacing: 8, + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + size: 48, + Icons.near_me_disabled_rounded, + color: colorTheme.accentError, + ), + Text( + 'Something went wrong', + style: textTheme.headline.copyWith( + color: colorTheme.textHighEmphasis, + ), + ), + Text( + 'Please check your location settings and try again.', + style: textTheme.body.copyWith( + color: colorTheme.textLowEmphasis, + ), + ), + ], + ); + } +} + +class LocationPickerOptionList extends StatelessWidget { + const LocationPickerOptionList({ + super.key, + required this.onOptionSelected, + }); + + final ValueSetter onOptionSelected; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + return Material( + color: colorTheme.barsBg, + borderRadius: const BorderRadiusDirectional.only( + topEnd: Radius.circular(14), + topStart: Radius.circular(14), + ), + child: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 14, + horizontal: 14, + ), + child: Column( + spacing: 8, + mainAxisSize: MainAxisSize.min, + children: [ + LocationPickerOptionItem( + icon: const Icon(Icons.share_location_rounded), + title: 'Share Live Location', + subtitle: 'Your location will update in real-time', + onTap: () async { + final duration = await showCupertinoModalPopup( + context: context, + builder: (_) => const LiveLocationDurationDialog(), + ); + + if (duration == null) return; + final endSharingAt = DateTime.timestamp().add(duration); + + return onOptionSelected( + ShareLiveLocation(endSharingAt: endSharingAt), + ); + }, + ), + LocationPickerOptionItem( + icon: const Icon(Icons.my_location), + title: 'Share Static Location', + subtitle: 'Send your current location only', + onTap: () => onOptionSelected(const ShareStaticLocation()), + ), + ], + ), + ), + ), + ); + } +} + +sealed class LocationPickerOption { + const LocationPickerOption(); +} + +final class ShareLiveLocation extends LocationPickerOption { + const ShareLiveLocation({required this.endSharingAt}); + final DateTime endSharingAt; +} + +final class ShareStaticLocation extends LocationPickerOption { + const ShareStaticLocation(); +} + +class LocationPickerOptionItem extends StatelessWidget { + const LocationPickerOptionItem({ + super.key, + required this.icon, + required this.title, + required this.subtitle, + required this.onTap, + }); + + final Widget icon; + final String title; + final String subtitle; + final VoidCallback onTap; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final textTheme = theme.textTheme; + final colorTheme = theme.colorTheme; + + return OutlinedButton( + onPressed: onTap, + style: OutlinedButton.styleFrom( + backgroundColor: colorTheme.barsBg, + foregroundColor: colorTheme.accentPrimary, + side: BorderSide(color: colorTheme.borders, width: 1.2), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8), + ), + child: IconTheme( + data: IconTheme.of(context).copyWith( + size: 24, + color: colorTheme.accentPrimary, + ), + child: Row( + spacing: 16, + children: [ + icon, + Expanded( + child: Column( + spacing: 2, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: textTheme.bodyBold.copyWith( + color: colorTheme.textHighEmphasis, + ), + ), + Text( + subtitle, + style: textTheme.footnote.copyWith( + color: colorTheme.textLowEmphasis, + ), + ), + ], + ), + ), + StreamSvgIcon( + size: 24, + icon: StreamSvgIcons.right, + color: colorTheme.textLowEmphasis, + ), + ], + ), + ), + ); + } +} + +class LiveLocationDurationDialog extends StatelessWidget { + const LiveLocationDurationDialog({super.key}); + + static const _endAtDurations = [ + Duration(minutes: 15), + Duration(hours: 1), + Duration(hours: 8), + ]; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + + return CupertinoTheme( + data: CupertinoTheme.of(context).copyWith( + primaryColor: theme.colorTheme.accentPrimary, + ), + child: CupertinoActionSheet( + title: const Text('Share Live Location'), + message: Text( + 'Select the duration for sharing your live location.', + style: theme.textTheme.footnote.copyWith( + color: theme.colorTheme.textLowEmphasis, + ), + ), + actions: [ + ..._endAtDurations.map((duration) { + final endAt = Jiffy.now().addDuration(duration); + return CupertinoActionSheetAction( + onPressed: () => Navigator.of(context).pop(duration), + child: Text(endAt.fromNow(withPrefixAndSuffix: false)), + ); + }), + ], + cancelButton: CupertinoActionSheetAction( + isDestructiveAction: true, + onPressed: Navigator.of(context).pop, + child: const Text('Cancel'), + ), + ), + ); + } +} diff --git a/sample_app/lib/widgets/location/location_picker_option.dart b/sample_app/lib/widgets/location/location_picker_option.dart new file mode 100644 index 0000000000..e32ba43ee7 --- /dev/null +++ b/sample_app/lib/widgets/location/location_picker_option.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:sample_app/utils/location_provider.dart'; +import 'package:sample_app/widgets/location/location_picker_dialog.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +final class LocationPickerType extends CustomAttachmentPickerType { + const LocationPickerType(); +} + +final class LocationPicked extends CustomAttachmentPickerResult { + const LocationPicked({required this.location}); + final LocationPickerResult location; +} + +class LocationPicker extends StatelessWidget { + const LocationPicker({ + super.key, + this.onLocationPicked, + }); + + final ValueSetter? onLocationPicked; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + return OptionDrawer( + child: EndOfFrameCallbackWidget( + child: Icon( + size: 148, + Icons.near_me_rounded, + color: colorTheme.disabled, + ), + onEndOfFrame: (context) async { + final result = await runInPermissionRequestLock(() { + return showLocationPickerDialog(context: context); + }); + + onLocationPicked?.call(result); + }, + errorBuilder: (context, error, stacktrace) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + size: 148, + Icons.near_me_rounded, + color: theme.colorTheme.disabled, + ), + Text( + 'Please enable access to your location', + style: theme.textTheme.body.copyWith( + color: theme.colorTheme.textLowEmphasis, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + TextButton( + onPressed: LocationProvider().openLocationSettings, + child: Text( + 'Allow Location Access', + style: theme.textTheme.bodyBold.copyWith( + color: theme.colorTheme.accentPrimary, + ), + ), + ), + ], + ); + }, + ), + ); + } +} diff --git a/sample_app/lib/widgets/location/location_user_marker.dart b/sample_app/lib/widgets/location/location_user_marker.dart new file mode 100644 index 0000000000..102e16876c --- /dev/null +++ b/sample_app/lib/widgets/location/location_user_marker.dart @@ -0,0 +1,56 @@ +import 'package:avatar_glow/avatar_glow.dart'; +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +class LocationUserMarker extends StatelessWidget { + const LocationUserMarker({ + super.key, + this.user, + this.markerSize = 40, + required this.sharedLocation, + }); + + final User? user; + final double markerSize; + final Location sharedLocation; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + if (user case final user? when sharedLocation.isLive) { + const borderWidth = 4.0; + + final avatar = Material( + shape: const CircleBorder(), + clipBehavior: Clip.antiAlias, + color: colorTheme.overlayDark, + child: Padding( + padding: const EdgeInsets.all(borderWidth), + child: StreamUserAvatar( + user: user, + constraints: BoxConstraints.tightFor( + width: markerSize, + height: markerSize, + ), + showOnlineStatus: false, + ), + ), + ); + + if (sharedLocation.isExpired) return avatar; + + return AvatarGlow( + glowColor: colorTheme.accentPrimary, + child: avatar, + ); + } + + return Icon( + size: markerSize, + Icons.person_pin, + color: colorTheme.accentPrimary, + ); + } +} diff --git a/sample_app/lib/widgets/simple_map_view.dart b/sample_app/lib/widgets/simple_map_view.dart new file mode 100644 index 0000000000..0faadc11f7 --- /dev/null +++ b/sample_app/lib/widgets/simple_map_view.dart @@ -0,0 +1,153 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:flutter_map_animations/flutter_map_animations.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +typedef MarkerBuilder = Widget Function( + BuildContext context, + Animation animation, + double markerSize, +); + +class SimpleMapView extends StatefulWidget { + const SimpleMapView({ + super.key, + this.cameraZoom = 15, + this.markerSize = 30, + required this.coordinates, + this.showLocateMeButton = true, + this.markerBuilder = _defaultMarkerBuilder, + }); + + final double cameraZoom; + + final double markerSize; + + final LocationCoordinates coordinates; + + final bool showLocateMeButton; + + final MarkerBuilder markerBuilder; + static Widget _defaultMarkerBuilder(BuildContext context, _, double size) { + final theme = StreamChatTheme.of(context); + final iconColor = theme.colorTheme.accentPrimary; + return Icon(size: size, Icons.person_pin, color: iconColor); + } + + @override + State createState() => _SimpleMapViewState(); +} + +class _SimpleMapViewState extends State + with TickerProviderStateMixin { + late final _mapController = AnimatedMapController(vsync: this); + late final _initialCenter = widget.coordinates.toLatLng(); + + @override + void didUpdateWidget(covariant SimpleMapView oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.coordinates != widget.coordinates) { + _mapController.animateTo( + dest: widget.coordinates.toLatLng(), + zoom: widget.cameraZoom, + curve: Curves.easeInOut, + ); + } + } + + @override + Widget build(BuildContext context) { + final brightness = Theme.of(context).brightness; + const baseMapTemplate = 'https://{s}.basemaps.cartocdn.com'; + const mapTemplate = '$baseMapTemplate/rastertiles/voyager/{z}/{x}/{y}.png'; + const fallbackTemplate = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + return FlutterMap( + mapController: _mapController.mapController, + options: MapOptions( + keepAlive: true, + initialCenter: _initialCenter, + initialZoom: widget.cameraZoom, + ), + children: [ + TileLayer( + urlTemplate: mapTemplate, + fallbackUrl: fallbackTemplate, + tileBuilder: (context, tile, __) => switch (brightness) { + Brightness.light => tile, + Brightness.dark => darkModeTilesContainerBuilder(context, tile), + }, + userAgentPackageName: switch (CurrentPlatform.type) { + PlatformType.ios => 'io.getstream.flutter', + PlatformType.android => 'io.getstream.chat.android.flutter.sample', + _ => 'unknown', + }, + ), + AnimatedMarkerLayer( + markers: [ + AnimatedMarker( + height: widget.markerSize, + width: widget.markerSize, + point: widget.coordinates.toLatLng(), + builder: (context, animation) => widget.markerBuilder( + context, + animation, + widget.markerSize, + ), + ), + ], + ), + if (widget.showLocateMeButton) + SimpleMapLocateMeButton( + onPressed: () => _mapController.animateTo( + zoom: widget.cameraZoom, + curve: Curves.easeInOut, + dest: widget.coordinates.toLatLng(), + ), + ), + ], + ); + } + + @override + void dispose() { + _mapController.dispose(); + super.dispose(); + } +} + +class SimpleMapLocateMeButton extends StatelessWidget { + const SimpleMapLocateMeButton({ + super.key, + this.onPressed, + this.alignment = AlignmentDirectional.topEnd, + }); + + final AlignmentGeometry alignment; + final VoidCallback? onPressed; + + @override + Widget build(BuildContext context) { + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + return Align( + alignment: alignment, + child: Padding( + padding: const EdgeInsets.all(8), + child: FloatingActionButton.small( + onPressed: onPressed, + shape: const CircleBorder(), + foregroundColor: colorTheme.accentPrimary, + backgroundColor: colorTheme.barsBg, + child: const Icon(Icons.near_me_rounded), + ), + ), + ); + } +} + +extension on LocationCoordinates { + LatLng toLatLng() => LatLng(latitude, longitude); +} diff --git a/sample_app/macos/Flutter/Flutter-Debug.xcconfig b/sample_app/macos/Flutter/Flutter-Debug.xcconfig deleted file mode 100644 index 4b81f9b2d2..0000000000 --- a/sample_app/macos/Flutter/Flutter-Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/sample_app/macos/Flutter/Flutter-Release.xcconfig b/sample_app/macos/Flutter/Flutter-Release.xcconfig deleted file mode 100644 index 5caa9d1579..0000000000 --- a/sample_app/macos/Flutter/Flutter-Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/sample_app/macos/Runner/DebugProfile.entitlements b/sample_app/macos/Runner/DebugProfile.entitlements index 0eaccf1418..6bc96b3bc4 100644 --- a/sample_app/macos/Runner/DebugProfile.entitlements +++ b/sample_app/macos/Runner/DebugProfile.entitlements @@ -12,5 +12,7 @@ com.apple.security.network.server + com.apple.security.personal-information.location + diff --git a/sample_app/macos/Runner/Info.plist b/sample_app/macos/Runner/Info.plist index 4789daa6a4..49bb9bb13c 100644 --- a/sample_app/macos/Runner/Info.plist +++ b/sample_app/macos/Runner/Info.plist @@ -28,5 +28,7 @@ MainMenu NSPrincipalClass NSApplication + NSLocationUsageDescription + We need access to your location to share it in the chat. diff --git a/sample_app/macos/Runner/Release.entitlements b/sample_app/macos/Runner/Release.entitlements index a0463869a9..731447a00b 100644 --- a/sample_app/macos/Runner/Release.entitlements +++ b/sample_app/macos/Runner/Release.entitlements @@ -8,5 +8,7 @@ com.apple.security.network.client + com.apple.security.personal-information.location + diff --git a/sample_app/pubspec.yaml b/sample_app/pubspec.yaml index 3cbf74a632..5ba315520a 100644 --- a/sample_app/pubspec.yaml +++ b/sample_app/pubspec.yaml @@ -20,6 +20,7 @@ environment: flutter: ">=3.27.4" dependencies: + avatar_glow: ^3.0.0 collection: ^1.17.2 firebase_core: ^3.0.0 firebase_messaging: ^15.0.0 @@ -27,12 +28,17 @@ dependencies: sdk: flutter flutter_app_badger: ^1.5.0 flutter_local_notifications: ^18.0.1 + flutter_map: ^8.1.1 + flutter_map_animations: ^0.9.0 flutter_secure_storage: ^9.2.2 flutter_slidable: ^3.1.1 flutter_svg: ^2.0.10+1 + geolocator: ^13.0.0 go_router: ^14.6.2 + latlong2: ^0.9.1 lottie: ^3.1.2 provider: ^6.0.5 + rxdart: ^0.28.0 sentry_flutter: ^8.3.0 stream_chat_flutter: ^10.0.0-beta.3 stream_chat_localizations: ^10.0.0-beta.3 From a32d298285ea996ef161308b49a11f1d35011dbd Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 24 Jul 2025 02:02:37 +0200 Subject: [PATCH 19/34] fix(ui): adjust reaction picker and message modal animations The animation curves and durations for the reaction picker and message modal have been updated for a smoother user experience. - The `reaction_picker_icon_list.dart` animation curve is now `Curves.easeOutBack` and the duration is 335 milliseconds. - The `message_modal.dart` transition duration is now 335 milliseconds, and the scale animation curve is `Curves.easeOutBack`. --- .../lib/src/message_modal/message_modal.dart | 4 ++-- .../lib/src/reactions/picker/reaction_picker_icon_list.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart index 86bc303f77..57035fee32 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart @@ -18,7 +18,7 @@ Future showStreamMessageModal({ bool barrierDismissible = true, String? barrierLabel, Color? barrierColor, - Duration transitionDuration = const Duration(milliseconds: 300), + Duration transitionDuration = const Duration(milliseconds: 335), RouteTransitionsBuilder? transitionBuilder, bool useRootNavigator = true, RouteSettings? routeSettings, @@ -47,7 +47,7 @@ Future showStreamMessageModal({ transitionBuilder: (context, animation, secondaryAnimation, child) { final sigma = 10 * animation.value; final scaleAnimation = Tween(begin: 0, end: 1).animate( - CurvedAnimation(parent: animation, curve: Curves.easeInOutBack), + CurvedAnimation(parent: animation, curve: Curves.easeOutBack), ); return BackdropFilter( diff --git a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart index 124757aeb4..5c2a4ad06a 100644 --- a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart @@ -200,8 +200,8 @@ class _ReactionPickerIconListState extends State { return TweenAnimationBuilder( tween: Tween(begin: 0, end: 1), - curve: Curves.easeInOutBack, - duration: const Duration(milliseconds: 500), + curve: Curves.easeOutBack, + duration: const Duration(milliseconds: 335), builder: (context, scale, child) { return Transform.scale(scale: scale, child: child); }, From 84b299471fba8e471e633ee3c8ba505d12704b8f Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 24 Jul 2025 16:13:12 +0200 Subject: [PATCH 20/34] feat(persistence): add support for location persistence (#2319) --- .../lib/src/db/chat_persistence_client.dart | 24 + .../src/db/chat_persistence_client_test.dart | 17 + packages/stream_chat_persistence/CHANGELOG.md | 4 + .../lib/src/dao/dao.dart | 1 + .../lib/src/dao/draft_message_dao.dart | 17 +- .../lib/src/dao/location_dao.dart | 83 + .../lib/src/dao/location_dao.g.dart | 10 + .../lib/src/dao/message_dao.dart | 11 + .../lib/src/dao/pinned_message_dao.dart | 11 + .../lib/src/db/drift_chat_database.dart | 4 +- .../lib/src/db/drift_chat_database.g.dart | 12100 +++++++++------- .../lib/src/entity/entity.dart | 1 + .../lib/src/entity/locations.dart | 43 + .../lib/src/mapper/location_mapper.dart | 40 + .../lib/src/mapper/mapper.dart | 1 + .../lib/src/mapper/message_mapper.dart | 2 + .../lib/src/mapper/pinned_message_mapper.dart | 2 + .../src/stream_chat_persistence_client.dart | 35 + .../test/mock_chat_database.dart | 6 + .../test/src/dao/location_dao_test.dart | 318 + .../test/src/mapper/location_mapper_test.dart | 141 + .../stream_chat_persistence_client_test.dart | 92 + 22 files changed, 7439 insertions(+), 5524 deletions(-) create mode 100644 packages/stream_chat_persistence/lib/src/dao/location_dao.dart create mode 100644 packages/stream_chat_persistence/lib/src/dao/location_dao.g.dart create mode 100644 packages/stream_chat_persistence/lib/src/entity/locations.dart create mode 100644 packages/stream_chat_persistence/lib/src/mapper/location_mapper.dart create mode 100644 packages/stream_chat_persistence/test/src/dao/location_dao_test.dart create mode 100644 packages/stream_chat_persistence/test/src/mapper/location_mapper_test.dart diff --git a/packages/stream_chat/lib/src/db/chat_persistence_client.dart b/packages/stream_chat/lib/src/db/chat_persistence_client.dart index 95439d5743..758e43f392 100644 --- a/packages/stream_chat/lib/src/db/chat_persistence_client.dart +++ b/packages/stream_chat/lib/src/db/chat_persistence_client.dart @@ -7,6 +7,7 @@ import 'package:stream_chat/src/core/models/channel_state.dart'; import 'package:stream_chat/src/core/models/draft.dart'; import 'package:stream_chat/src/core/models/event.dart'; import 'package:stream_chat/src/core/models/filter.dart'; +import 'package:stream_chat/src/core/models/location.dart'; import 'package:stream_chat/src/core/models/member.dart'; import 'package:stream_chat/src/core/models/message.dart'; import 'package:stream_chat/src/core/models/poll.dart'; @@ -83,6 +84,12 @@ abstract class ChatPersistenceClient { /// [parentId] for thread messages. Future getDraftMessageByCid(String cid, {String? parentId}); + /// Get stored [Location]s by providing channel [cid] + Future> getLocationsByCid(String cid); + + /// Get stored [Location] by providing [messageId] + Future getLocationByMessageId(String messageId); + /// Get [ChannelState] data by providing channel [cid] Future getChannelStateByCid( String cid, { @@ -168,6 +175,12 @@ abstract class ChatPersistenceClient { /// [DraftMessages.parentId]. Future deleteDraftMessageByCid(String cid, {String? parentId}); + /// Removes locations by channel [cid] + Future deleteLocationsByCid(String cid); + + /// Removes locations by message [messageIds] + Future deleteLocationsByMessageIds(List messageIds); + /// Updates the message data of a particular channel [cid] with /// the new [messages] data Future updateMessages(String cid, List messages) => @@ -228,6 +241,9 @@ abstract class ChatPersistenceClient { /// Updates the draft messages data with the new [draftMessages] data Future updateDraftMessages(List draftMessages); + /// Updates the locations data with the new [locations] data + Future updateLocations(List locations); + /// Deletes all the reactions by [messageIds] Future deleteReactionsByMessageId(List messageIds); @@ -292,6 +308,8 @@ abstract class ChatPersistenceClient { final drafts = []; final draftsToDeleteCids = []; + final locations = []; + for (final state in channelStates) { final channel = state.channel; // Continue if channel is not available. @@ -342,6 +360,11 @@ abstract class ChatPersistenceClient { ...?pinnedMessages?.map((it) => it.draft), ].nonNulls); + locations.addAll([ + ...?messages?.map((it) => it.sharedLocation), + ...?pinnedMessages?.map((it) => it.sharedLocation), + ].nonNulls); + users.addAll([ channel.createdBy, ...?messages?.map((it) => it.user), @@ -386,6 +409,7 @@ abstract class ChatPersistenceClient { updatePinnedMessageReactions(pinnedReactions), updatePollVotes(pollVotes), updateDraftMessages(drafts), + updateLocations(locations), ]); } diff --git a/packages/stream_chat/test/src/db/chat_persistence_client_test.dart b/packages/stream_chat/test/src/db/chat_persistence_client_test.dart index a3036a2fde..4305d762c0 100644 --- a/packages/stream_chat/test/src/db/chat_persistence_client_test.dart +++ b/packages/stream_chat/test/src/db/chat_persistence_client_test.dart @@ -6,6 +6,7 @@ import 'package:stream_chat/src/core/models/draft.dart'; import 'package:stream_chat/src/core/models/draft_message.dart'; import 'package:stream_chat/src/core/models/event.dart'; import 'package:stream_chat/src/core/models/filter.dart'; +import 'package:stream_chat/src/core/models/location.dart'; import 'package:stream_chat/src/core/models/member.dart'; import 'package:stream_chat/src/core/models/message.dart'; import 'package:stream_chat/src/core/models/poll.dart'; @@ -176,6 +177,22 @@ class TestPersistenceClient extends ChatPersistenceClient { @override Future updateDraftMessages(List draftMessages) => Future.value(); + + @override + Future> getLocationsByCid(String cid) async => []; + + @override + Future getLocationByMessageId(String messageId) async => null; + + @override + Future updateLocations(List locations) => Future.value(); + + @override + Future deleteLocationsByCid(String cid) => Future.value(); + + @override + Future deleteLocationsByMessageIds(List messageIds) => + Future.value(); } void main() { diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index e6017567c8..b752f40f12 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,3 +1,7 @@ +## Upcoming Beta + +- Added support for `Location` entity in the database. + ## Upcoming 🐞 Fixed diff --git a/packages/stream_chat_persistence/lib/src/dao/dao.dart b/packages/stream_chat_persistence/lib/src/dao/dao.dart index d0aab7b212..d2f088c399 100644 --- a/packages/stream_chat_persistence/lib/src/dao/dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/dao.dart @@ -2,6 +2,7 @@ export 'channel_dao.dart'; export 'channel_query_dao.dart'; export 'connection_event_dao.dart'; export 'draft_message_dao.dart'; +export 'location_dao.dart'; export 'member_dao.dart'; export 'message_dao.dart'; export 'pinned_message_dao.dart'; diff --git a/packages/stream_chat_persistence/lib/src/dao/draft_message_dao.dart b/packages/stream_chat_persistence/lib/src/dao/draft_message_dao.dart index b5a5cb6fc9..5065b3bda4 100644 --- a/packages/stream_chat_persistence/lib/src/dao/draft_message_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/draft_message_dao.dart @@ -18,18 +18,27 @@ class DraftMessageDao extends DatabaseAccessor final DriftChatDatabase _db; Future _draftFromEntity(DraftMessageEntity entity) async { - // We do not want to fetch the draft message of the parent and quoted - // message because it will create a circular dependency and will + // We do not want to fetch the draft and shared location of the parent and + // quoted message because it will create a circular dependency and will // result in infinite loop. const fetchDraft = false; + const fetchSharedLocation = false; final parentMessage = await switch (entity.parentId) { - final id? => _db.messageDao.getMessageById(id, fetchDraft: fetchDraft), + final id? => _db.messageDao.getMessageById( + id, + fetchDraft: fetchDraft, + fetchSharedLocation: fetchSharedLocation, + ), _ => null, }; final quotedMessage = await switch (entity.quotedMessageId) { - final id? => _db.messageDao.getMessageById(id, fetchDraft: fetchDraft), + final id? => _db.messageDao.getMessageById( + id, + fetchDraft: fetchDraft, + fetchSharedLocation: fetchSharedLocation, + ), _ => null, }; diff --git a/packages/stream_chat_persistence/lib/src/dao/location_dao.dart b/packages/stream_chat_persistence/lib/src/dao/location_dao.dart new file mode 100644 index 0000000000..6e12421179 --- /dev/null +++ b/packages/stream_chat_persistence/lib/src/dao/location_dao.dart @@ -0,0 +1,83 @@ +// ignore_for_file: join_return_with_assignment + +import 'package:drift/drift.dart'; +import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; +import 'package:stream_chat_persistence/src/entity/locations.dart'; +import 'package:stream_chat_persistence/src/mapper/mapper.dart'; + +part 'location_dao.g.dart'; + +/// The Data Access Object for operations in [Locations] table. +@DriftAccessor(tables: [Locations]) +class LocationDao extends DatabaseAccessor + with _$LocationDaoMixin { + /// Creates a new location dao instance + LocationDao(this._db) : super(_db); + + final DriftChatDatabase _db; + + Future _locationFromEntity(LocationEntity entity) async { + // We do not want to fetch the location of the parent and quoted + // message because it will create a circular dependency and will + // result in infinite loop. + const fetchDraft = false; + const fetchSharedLocation = false; + + final channel = await switch (entity.channelCid) { + final cid? => db.channelDao.getChannelByCid(cid), + _ => null, + }; + + final message = await switch (entity.messageId) { + final id? => _db.messageDao.getMessageById( + id, + fetchDraft: fetchDraft, + fetchSharedLocation: fetchSharedLocation, + ), + _ => null, + }; + + return entity.toLocation( + channel: channel, + message: message, + ); + } + + /// Get all locations for a channel + Future> getLocationsByCid(String cid) async { + final query = select(locations)..where((tbl) => tbl.channelCid.equals(cid)); + + final result = await query.map(_locationFromEntity).get(); + return Future.wait(result); + } + + /// Get location by message ID + Future getLocationByMessageId(String messageId) async { + final query = select(locations) // + ..where((tbl) => tbl.messageId.equals(messageId)); + + final result = await query.getSingleOrNull(); + if (result == null) return null; + + return _locationFromEntity(result); + } + + /// Update multiple locations + Future updateLocations(List locationList) { + return batch( + (it) => it.insertAllOnConflictUpdate( + locations, + locationList.map((it) => it.toEntity()), + ), + ); + } + + /// Delete locations by channel ID + Future deleteLocationsByCid(String cid) => + (delete(locations)..where((tbl) => tbl.channelCid.equals(cid))).go(); + + /// Delete locations by message IDs + Future deleteLocationsByMessageIds(List messageIds) => + (delete(locations)..where((tbl) => tbl.messageId.isIn(messageIds))).go(); +} diff --git a/packages/stream_chat_persistence/lib/src/dao/location_dao.g.dart b/packages/stream_chat_persistence/lib/src/dao/location_dao.g.dart new file mode 100644 index 0000000000..240b3b4b83 --- /dev/null +++ b/packages/stream_chat_persistence/lib/src/dao/location_dao.g.dart @@ -0,0 +1,10 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'location_dao.dart'; + +// ignore_for_file: type=lint +mixin _$LocationDaoMixin on DatabaseAccessor { + $ChannelsTable get channels => attachedDatabase.channels; + $MessagesTable get messages => attachedDatabase.messages; + $LocationsTable get locations => attachedDatabase.locations; +} diff --git a/packages/stream_chat_persistence/lib/src/dao/message_dao.dart b/packages/stream_chat_persistence/lib/src/dao/message_dao.dart index 8a947a7429..1a8e409b95 100644 --- a/packages/stream_chat_persistence/lib/src/dao/message_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/message_dao.dart @@ -39,6 +39,7 @@ class MessageDao extends DatabaseAccessor Future _messageFromJoinRow( TypedResult rows, { bool fetchDraft = false, + bool fetchSharedLocation = false, }) async { final userEntity = rows.readTableOrNull(_users); final pinnedByEntity = rows.readTableOrNull(_pinnedByUsers); @@ -67,6 +68,11 @@ class MessageDao extends DatabaseAccessor _ => null, }; + final sharedLocation = await switch (fetchSharedLocation) { + true => _db.locationDao.getLocationByMessageId(msgEntity.id), + _ => null, + }; + return msgEntity.toMessage( user: userEntity?.toUser(), pinnedBy: pinnedByEntity?.toUser(), @@ -75,6 +81,7 @@ class MessageDao extends DatabaseAccessor quotedMessage: quotedMessage, poll: poll, draft: draft, + sharedLocation: sharedLocation, ); } @@ -85,6 +92,7 @@ class MessageDao extends DatabaseAccessor Future getMessageById( String id, { bool fetchDraft = true, + bool fetchSharedLocation = true, }) async { final query = select(messages).join([ leftOuterJoin(_users, messages.userId.equalsExp(_users.id)), @@ -101,6 +109,7 @@ class MessageDao extends DatabaseAccessor return _messageFromJoinRow( result, fetchDraft: fetchDraft, + fetchSharedLocation: fetchSharedLocation, ); } @@ -169,6 +178,7 @@ class MessageDao extends DatabaseAccessor Future> getMessagesByCid( String cid, { bool fetchDraft = true, + bool fetchSharedLocation = true, PaginationParams? messagePagination, }) async { final query = select(messages).join([ @@ -190,6 +200,7 @@ class MessageDao extends DatabaseAccessor (row) => _messageFromJoinRow( row, fetchDraft: fetchDraft, + fetchSharedLocation: fetchSharedLocation, ), ), ); diff --git a/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart b/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart index ac8576b338..c22b6ddba3 100644 --- a/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart @@ -38,6 +38,7 @@ class PinnedMessageDao extends DatabaseAccessor Future _messageFromJoinRow( TypedResult rows, { bool fetchDraft = false, + bool fetchSharedLocation = false, }) async { final userEntity = rows.readTableOrNull(_users); final pinnedByEntity = rows.readTableOrNull(_pinnedByUsers); @@ -68,6 +69,11 @@ class PinnedMessageDao extends DatabaseAccessor _ => null, }; + final sharedLocation = await switch (fetchSharedLocation) { + true => _db.locationDao.getLocationByMessageId(msgEntity.id), + _ => null, + }; + return msgEntity.toMessage( user: userEntity?.toUser(), pinnedBy: pinnedByEntity?.toUser(), @@ -76,6 +82,7 @@ class PinnedMessageDao extends DatabaseAccessor quotedMessage: quotedMessage, poll: poll, draft: draft, + sharedLocation: sharedLocation, ); } @@ -83,6 +90,7 @@ class PinnedMessageDao extends DatabaseAccessor Future getMessageById( String id, { bool fetchDraft = true, + bool fetchSharedLocation = true, }) async { final query = select(pinnedMessages).join([ leftOuterJoin(_users, pinnedMessages.userId.equalsExp(_users.id)), @@ -99,6 +107,7 @@ class PinnedMessageDao extends DatabaseAccessor return _messageFromJoinRow( result, fetchDraft: fetchDraft, + fetchSharedLocation: fetchSharedLocation, ); } @@ -166,6 +175,7 @@ class PinnedMessageDao extends DatabaseAccessor Future> getMessagesByCid( String cid, { bool fetchDraft = true, + bool fetchSharedLocation = true, PaginationParams? messagePagination, }) async { final query = select(pinnedMessages).join([ @@ -188,6 +198,7 @@ class PinnedMessageDao extends DatabaseAccessor (row) => _messageFromJoinRow( row, fetchDraft: fetchDraft, + fetchSharedLocation: fetchSharedLocation, ), ), ); diff --git a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart index 7aaeee4b2e..eaca779f8e 100644 --- a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart +++ b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart @@ -13,6 +13,7 @@ part 'drift_chat_database.g.dart'; tables: [ Channels, DraftMessages, + Locations, Messages, PinnedMessages, Polls, @@ -30,6 +31,7 @@ part 'drift_chat_database.g.dart'; ChannelDao, MessageDao, DraftMessageDao, + LocationDao, PinnedMessageDao, PinnedMessageReactionDao, MemberDao, @@ -55,7 +57,7 @@ class DriftChatDatabase extends _$DriftChatDatabase { // you should bump this number whenever you change or add a table definition. @override - int get schemaVersion => 22; + int get schemaVersion => 1000 + 23; @override MigrationStrategy get migration => MigrationStrategy( diff --git a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart index fdf044d674..6d380c1c7a 100644 --- a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart +++ b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart @@ -2764,960 +2764,684 @@ class DraftMessagesCompanion extends UpdateCompanion { } } -class $PinnedMessagesTable extends PinnedMessages - with TableInfo<$PinnedMessagesTable, PinnedMessageEntity> { +class $LocationsTable extends Locations + with TableInfo<$LocationsTable, LocationEntity> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $PinnedMessagesTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _messageTextMeta = - const VerificationMeta('messageText'); - @override - late final GeneratedColumn messageText = GeneratedColumn( - 'message_text', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - @override - late final GeneratedColumnWithTypeConverter, String> - attachments = GeneratedColumn('attachments', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true) - .withConverter>( - $PinnedMessagesTable.$converterattachments); - static const VerificationMeta _stateMeta = const VerificationMeta('state'); - @override - late final GeneratedColumn state = GeneratedColumn( - 'state', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _typeMeta = const VerificationMeta('type'); + $LocationsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _channelCidMeta = + const VerificationMeta('channelCid'); @override - late final GeneratedColumn type = GeneratedColumn( - 'type', aliasedName, false, + late final GeneratedColumn channelCid = GeneratedColumn( + 'channel_cid', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false, - defaultValue: const Constant('regular')); - @override - late final GeneratedColumnWithTypeConverter, String> - mentionedUsers = GeneratedColumn( - 'mentioned_users', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true) - .withConverter>( - $PinnedMessagesTable.$convertermentionedUsers); - @override - late final GeneratedColumnWithTypeConverter?, - String> reactionGroups = GeneratedColumn( - 'reaction_groups', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $PinnedMessagesTable.$converterreactionGroupsn); - static const VerificationMeta _parentIdMeta = - const VerificationMeta('parentId'); - @override - late final GeneratedColumn parentId = GeneratedColumn( - 'parent_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _quotedMessageIdMeta = - const VerificationMeta('quotedMessageId'); - @override - late final GeneratedColumn quotedMessageId = GeneratedColumn( - 'quoted_message_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _pollIdMeta = const VerificationMeta('pollId'); - @override - late final GeneratedColumn pollId = GeneratedColumn( - 'poll_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _replyCountMeta = - const VerificationMeta('replyCount'); - @override - late final GeneratedColumn replyCount = GeneratedColumn( - 'reply_count', aliasedName, true, - type: DriftSqlType.int, requiredDuringInsert: false); - static const VerificationMeta _showInChannelMeta = - const VerificationMeta('showInChannel'); - @override - late final GeneratedColumn showInChannel = GeneratedColumn( - 'show_in_channel', aliasedName, true, - type: DriftSqlType.bool, - requiredDuringInsert: false, defaultConstraints: GeneratedColumn.constraintIsAlways( - 'CHECK ("show_in_channel" IN (0, 1))')); - static const VerificationMeta _shadowedMeta = - const VerificationMeta('shadowed'); + 'REFERENCES channels (cid) ON DELETE CASCADE')); + static const VerificationMeta _messageIdMeta = + const VerificationMeta('messageId'); @override - late final GeneratedColumn shadowed = GeneratedColumn( - 'shadowed', aliasedName, false, - type: DriftSqlType.bool, + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('CHECK ("shadowed" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _commandMeta = - const VerificationMeta('command'); - @override - late final GeneratedColumn command = GeneratedColumn( - 'command', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _localCreatedAtMeta = - const VerificationMeta('localCreatedAt'); - @override - late final GeneratedColumn localCreatedAt = - GeneratedColumn('local_created_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _remoteCreatedAtMeta = - const VerificationMeta('remoteCreatedAt'); - @override - late final GeneratedColumn remoteCreatedAt = - GeneratedColumn('remote_created_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _localUpdatedAtMeta = - const VerificationMeta('localUpdatedAt'); - @override - late final GeneratedColumn localUpdatedAt = - GeneratedColumn('local_updated_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _remoteUpdatedAtMeta = - const VerificationMeta('remoteUpdatedAt'); - @override - late final GeneratedColumn remoteUpdatedAt = - GeneratedColumn('remote_updated_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _localDeletedAtMeta = - const VerificationMeta('localDeletedAt'); - @override - late final GeneratedColumn localDeletedAt = - GeneratedColumn('local_deleted_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _remoteDeletedAtMeta = - const VerificationMeta('remoteDeletedAt'); - @override - late final GeneratedColumn remoteDeletedAt = - GeneratedColumn('remote_deleted_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _messageTextUpdatedAtMeta = - const VerificationMeta('messageTextUpdatedAt'); - @override - late final GeneratedColumn messageTextUpdatedAt = - GeneratedColumn('message_text_updated_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES messages (id) ON DELETE CASCADE')); static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override late final GeneratedColumn userId = GeneratedColumn( 'user_id', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _pinnedMeta = const VerificationMeta('pinned'); - @override - late final GeneratedColumn pinned = GeneratedColumn( - 'pinned', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('CHECK ("pinned" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _pinnedAtMeta = - const VerificationMeta('pinnedAt'); - @override - late final GeneratedColumn pinnedAt = GeneratedColumn( - 'pinned_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _pinExpiresMeta = - const VerificationMeta('pinExpires'); + static const VerificationMeta _latitudeMeta = + const VerificationMeta('latitude'); + @override + late final GeneratedColumn latitude = GeneratedColumn( + 'latitude', aliasedName, false, + type: DriftSqlType.double, requiredDuringInsert: true); + static const VerificationMeta _longitudeMeta = + const VerificationMeta('longitude'); + @override + late final GeneratedColumn longitude = GeneratedColumn( + 'longitude', aliasedName, false, + type: DriftSqlType.double, requiredDuringInsert: true); + static const VerificationMeta _createdByDeviceIdMeta = + const VerificationMeta('createdByDeviceId'); + @override + late final GeneratedColumn createdByDeviceId = + GeneratedColumn('created_by_device_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _endAtMeta = const VerificationMeta('endAt'); @override - late final GeneratedColumn pinExpires = GeneratedColumn( - 'pin_expires', aliasedName, true, + late final GeneratedColumn endAt = GeneratedColumn( + 'end_at', aliasedName, true, type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _pinnedByUserIdMeta = - const VerificationMeta('pinnedByUserId'); - @override - late final GeneratedColumn pinnedByUserId = GeneratedColumn( - 'pinned_by_user_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _channelCidMeta = - const VerificationMeta('channelCid'); - @override - late final GeneratedColumn channelCid = GeneratedColumn( - 'channel_cid', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - @override - late final GeneratedColumnWithTypeConverter?, String> - i18n = GeneratedColumn('i18n', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $PinnedMessagesTable.$converteri18n); + static const VerificationMeta _createdAtMeta = + const VerificationMeta('createdAt'); @override - late final GeneratedColumnWithTypeConverter?, String> - restrictedVisibility = GeneratedColumn( - 'restricted_visibility', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $PinnedMessagesTable.$converterrestrictedVisibilityn); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + static const VerificationMeta _updatedAtMeta = + const VerificationMeta('updatedAt'); @override - late final GeneratedColumnWithTypeConverter?, String> - extraData = GeneratedColumn('extra_data', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $PinnedMessagesTable.$converterextraDatan); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); @override List get $columns => [ - id, - messageText, - attachments, - state, - type, - mentionedUsers, - reactionGroups, - parentId, - quotedMessageId, - pollId, - replyCount, - showInChannel, - shadowed, - command, - localCreatedAt, - remoteCreatedAt, - localUpdatedAt, - remoteUpdatedAt, - localDeletedAt, - remoteDeletedAt, - messageTextUpdatedAt, - userId, - pinned, - pinnedAt, - pinExpires, - pinnedByUserId, channelCid, - i18n, - restrictedVisibility, - extraData + messageId, + userId, + latitude, + longitude, + createdByDeviceId, + endAt, + createdAt, + updatedAt ]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'pinned_messages'; + static const String $name = 'locations'; @override - VerificationContext validateIntegrity( - Insertable instance, + VerificationContext validateIntegrity(Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } else if (isInserting) { - context.missing(_idMeta); - } - if (data.containsKey('message_text')) { + if (data.containsKey('channel_cid')) { context.handle( - _messageTextMeta, - messageText.isAcceptableOrUnknown( - data['message_text']!, _messageTextMeta)); + _channelCidMeta, + channelCid.isAcceptableOrUnknown( + data['channel_cid']!, _channelCidMeta)); } - if (data.containsKey('state')) { - context.handle( - _stateMeta, state.isAcceptableOrUnknown(data['state']!, _stateMeta)); - } else if (isInserting) { - context.missing(_stateMeta); - } - if (data.containsKey('type')) { - context.handle( - _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); - } - if (data.containsKey('parent_id')) { - context.handle(_parentIdMeta, - parentId.isAcceptableOrUnknown(data['parent_id']!, _parentIdMeta)); - } - if (data.containsKey('quoted_message_id')) { - context.handle( - _quotedMessageIdMeta, - quotedMessageId.isAcceptableOrUnknown( - data['quoted_message_id']!, _quotedMessageIdMeta)); - } - if (data.containsKey('poll_id')) { - context.handle(_pollIdMeta, - pollId.isAcceptableOrUnknown(data['poll_id']!, _pollIdMeta)); - } - if (data.containsKey('reply_count')) { - context.handle( - _replyCountMeta, - replyCount.isAcceptableOrUnknown( - data['reply_count']!, _replyCountMeta)); - } - if (data.containsKey('show_in_channel')) { - context.handle( - _showInChannelMeta, - showInChannel.isAcceptableOrUnknown( - data['show_in_channel']!, _showInChannelMeta)); - } - if (data.containsKey('shadowed')) { - context.handle(_shadowedMeta, - shadowed.isAcceptableOrUnknown(data['shadowed']!, _shadowedMeta)); - } - if (data.containsKey('command')) { - context.handle(_commandMeta, - command.isAcceptableOrUnknown(data['command']!, _commandMeta)); - } - if (data.containsKey('local_created_at')) { - context.handle( - _localCreatedAtMeta, - localCreatedAt.isAcceptableOrUnknown( - data['local_created_at']!, _localCreatedAtMeta)); - } - if (data.containsKey('remote_created_at')) { - context.handle( - _remoteCreatedAtMeta, - remoteCreatedAt.isAcceptableOrUnknown( - data['remote_created_at']!, _remoteCreatedAtMeta)); - } - if (data.containsKey('local_updated_at')) { - context.handle( - _localUpdatedAtMeta, - localUpdatedAt.isAcceptableOrUnknown( - data['local_updated_at']!, _localUpdatedAtMeta)); - } - if (data.containsKey('remote_updated_at')) { - context.handle( - _remoteUpdatedAtMeta, - remoteUpdatedAt.isAcceptableOrUnknown( - data['remote_updated_at']!, _remoteUpdatedAtMeta)); - } - if (data.containsKey('local_deleted_at')) { - context.handle( - _localDeletedAtMeta, - localDeletedAt.isAcceptableOrUnknown( - data['local_deleted_at']!, _localDeletedAtMeta)); - } - if (data.containsKey('remote_deleted_at')) { - context.handle( - _remoteDeletedAtMeta, - remoteDeletedAt.isAcceptableOrUnknown( - data['remote_deleted_at']!, _remoteDeletedAtMeta)); - } - if (data.containsKey('message_text_updated_at')) { - context.handle( - _messageTextUpdatedAtMeta, - messageTextUpdatedAt.isAcceptableOrUnknown( - data['message_text_updated_at']!, _messageTextUpdatedAtMeta)); + if (data.containsKey('message_id')) { + context.handle(_messageIdMeta, + messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta)); } if (data.containsKey('user_id')) { context.handle(_userIdMeta, userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); } - if (data.containsKey('pinned')) { - context.handle(_pinnedMeta, - pinned.isAcceptableOrUnknown(data['pinned']!, _pinnedMeta)); + if (data.containsKey('latitude')) { + context.handle(_latitudeMeta, + latitude.isAcceptableOrUnknown(data['latitude']!, _latitudeMeta)); + } else if (isInserting) { + context.missing(_latitudeMeta); } - if (data.containsKey('pinned_at')) { - context.handle(_pinnedAtMeta, - pinnedAt.isAcceptableOrUnknown(data['pinned_at']!, _pinnedAtMeta)); + if (data.containsKey('longitude')) { + context.handle(_longitudeMeta, + longitude.isAcceptableOrUnknown(data['longitude']!, _longitudeMeta)); + } else if (isInserting) { + context.missing(_longitudeMeta); } - if (data.containsKey('pin_expires')) { + if (data.containsKey('created_by_device_id')) { context.handle( - _pinExpiresMeta, - pinExpires.isAcceptableOrUnknown( - data['pin_expires']!, _pinExpiresMeta)); + _createdByDeviceIdMeta, + createdByDeviceId.isAcceptableOrUnknown( + data['created_by_device_id']!, _createdByDeviceIdMeta)); } - if (data.containsKey('pinned_by_user_id')) { + if (data.containsKey('end_at')) { context.handle( - _pinnedByUserIdMeta, - pinnedByUserId.isAcceptableOrUnknown( - data['pinned_by_user_id']!, _pinnedByUserIdMeta)); + _endAtMeta, endAt.isAcceptableOrUnknown(data['end_at']!, _endAtMeta)); } - if (data.containsKey('channel_cid')) { - context.handle( - _channelCidMeta, - channelCid.isAcceptableOrUnknown( - data['channel_cid']!, _channelCidMeta)); - } else if (isInserting) { - context.missing(_channelCidMeta); + if (data.containsKey('created_at')) { + context.handle(_createdAtMeta, + createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); + } + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); } return context; } @override - Set get $primaryKey => {id}; + Set get $primaryKey => {messageId}; @override - PinnedMessageEntity map(Map data, {String? tablePrefix}) { + LocationEntity map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return PinnedMessageEntity( - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - messageText: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}message_text']), - attachments: $PinnedMessagesTable.$converterattachments.fromSql( - attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}attachments'])!), - state: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}state'])!, - type: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}type'])!, - mentionedUsers: $PinnedMessagesTable.$convertermentionedUsers.fromSql( - attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}mentioned_users'])!), - reactionGroups: $PinnedMessagesTable.$converterreactionGroupsn.fromSql( - attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}reaction_groups'])), - parentId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}parent_id']), - quotedMessageId: attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}quoted_message_id']), - pollId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}poll_id']), - replyCount: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}reply_count']), - showInChannel: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}show_in_channel']), - shadowed: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}shadowed'])!, - command: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}command']), - localCreatedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}local_created_at']), - remoteCreatedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}remote_created_at']), - localUpdatedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}local_updated_at']), - remoteUpdatedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}remote_updated_at']), - localDeletedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}local_deleted_at']), - remoteDeletedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}remote_deleted_at']), - messageTextUpdatedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, - data['${effectivePrefix}message_text_updated_at']), + return LocationEntity( + channelCid: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}channel_cid']), + messageId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}message_id']), userId: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}user_id']), - pinned: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}pinned'])!, - pinnedAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}pinned_at']), - pinExpires: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}pin_expires']), - pinnedByUserId: attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}pinned_by_user_id']), - channelCid: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}channel_cid'])!, - i18n: $PinnedMessagesTable.$converteri18n.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}i18n'])), - restrictedVisibility: $PinnedMessagesTable.$converterrestrictedVisibilityn - .fromSql(attachedDatabase.typeMapping.read(DriftSqlType.string, - data['${effectivePrefix}restricted_visibility'])), - extraData: $PinnedMessagesTable.$converterextraDatan.fromSql( - attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), + latitude: attachedDatabase.typeMapping + .read(DriftSqlType.double, data['${effectivePrefix}latitude'])!, + longitude: attachedDatabase.typeMapping + .read(DriftSqlType.double, data['${effectivePrefix}longitude'])!, + createdByDeviceId: attachedDatabase.typeMapping.read( + DriftSqlType.string, data['${effectivePrefix}created_by_device_id']), + endAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}end_at']), + createdAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + updatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, ); } @override - $PinnedMessagesTable createAlias(String alias) { - return $PinnedMessagesTable(attachedDatabase, alias); + $LocationsTable createAlias(String alias) { + return $LocationsTable(attachedDatabase, alias); } - - static TypeConverter, String> $converterattachments = - ListConverter(); - static TypeConverter, String> $convertermentionedUsers = - ListConverter(); - static TypeConverter, String> - $converterreactionGroups = ReactionGroupsConverter(); - static TypeConverter?, String?> - $converterreactionGroupsn = - NullAwareTypeConverter.wrap($converterreactionGroups); - static TypeConverter?, String?> $converteri18n = - NullableMapConverter(); - static TypeConverter, String> $converterrestrictedVisibility = - ListConverter(); - static TypeConverter?, String?> $converterrestrictedVisibilityn = - NullAwareTypeConverter.wrap($converterrestrictedVisibility); - static TypeConverter, String> $converterextraData = - MapConverter(); - static TypeConverter?, String?> $converterextraDatan = - NullAwareTypeConverter.wrap($converterextraData); } -class PinnedMessageEntity extends DataClass - implements Insertable { - /// The message id - final String id; - - /// The text of this message - final String? messageText; - - /// The list of attachments, either provided by the user - /// or generated from a command or as a result of URL scraping. - final List attachments; +class LocationEntity extends DataClass implements Insertable { + /// The channel CID where the location is shared + final String? channelCid; - /// The current state of the message. - final String state; + /// The ID of the message that contains this shared location + final String? messageId; - /// The message type - final String type; + /// The ID of the user who shared the location + final String? userId; - /// The list of user mentioned in the message - final List mentionedUsers; + /// The latitude of the shared location + final double latitude; - /// A map describing the reaction group for every reaction - final Map? reactionGroups; + /// The longitude of the shared location + final double longitude; - /// The ID of the parent message, if the message is a thread reply. - final String? parentId; + /// The ID of the device that created the location + final String? createdByDeviceId; - /// The ID of the quoted message, if the message is a quoted reply. - final String? quotedMessageId; + /// The date at which the shared location will end (for live locations) + /// If null, this is a static location + final DateTime? endAt; - /// The ID of the poll, if the message is a poll. - final String? pollId; + /// The date at which the location was created + final DateTime createdAt; - /// Number of replies for this message. - final int? replyCount; + /// The date at which the location was last updated + final DateTime updatedAt; + const LocationEntity( + {this.channelCid, + this.messageId, + this.userId, + required this.latitude, + required this.longitude, + this.createdByDeviceId, + this.endAt, + required this.createdAt, + required this.updatedAt}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (!nullToAbsent || channelCid != null) { + map['channel_cid'] = Variable(channelCid); + } + if (!nullToAbsent || messageId != null) { + map['message_id'] = Variable(messageId); + } + if (!nullToAbsent || userId != null) { + map['user_id'] = Variable(userId); + } + map['latitude'] = Variable(latitude); + map['longitude'] = Variable(longitude); + if (!nullToAbsent || createdByDeviceId != null) { + map['created_by_device_id'] = Variable(createdByDeviceId); + } + if (!nullToAbsent || endAt != null) { + map['end_at'] = Variable(endAt); + } + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + return map; + } - /// Check if this message needs to show in the channel. - final bool? showInChannel; - - /// If true the message is shadowed - final bool shadowed; - - /// A used command name. - final String? command; - - /// The DateTime on which the message was created on the client. - final DateTime? localCreatedAt; - - /// The DateTime on which the message was created on the server. - final DateTime? remoteCreatedAt; - - /// The DateTime on which the message was updated on the client. - final DateTime? localUpdatedAt; - - /// The DateTime on which the message was updated on the server. - final DateTime? remoteUpdatedAt; - - /// The DateTime on which the message was deleted on the client. - final DateTime? localDeletedAt; - - /// The DateTime on which the message was deleted on the server. - final DateTime? remoteDeletedAt; - - /// The DateTime at which the message text was edited - final DateTime? messageTextUpdatedAt; - - /// Id of the User who sent the message - final String? userId; - - /// Whether the message is pinned or not - final bool pinned; - - /// The DateTime at which the message was pinned - final DateTime? pinnedAt; + factory LocationEntity.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LocationEntity( + channelCid: serializer.fromJson(json['channelCid']), + messageId: serializer.fromJson(json['messageId']), + userId: serializer.fromJson(json['userId']), + latitude: serializer.fromJson(json['latitude']), + longitude: serializer.fromJson(json['longitude']), + createdByDeviceId: + serializer.fromJson(json['createdByDeviceId']), + endAt: serializer.fromJson(json['endAt']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'channelCid': serializer.toJson(channelCid), + 'messageId': serializer.toJson(messageId), + 'userId': serializer.toJson(userId), + 'latitude': serializer.toJson(latitude), + 'longitude': serializer.toJson(longitude), + 'createdByDeviceId': serializer.toJson(createdByDeviceId), + 'endAt': serializer.toJson(endAt), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + }; + } - /// The DateTime on which the message pin expires - final DateTime? pinExpires; + LocationEntity copyWith( + {Value channelCid = const Value.absent(), + Value messageId = const Value.absent(), + Value userId = const Value.absent(), + double? latitude, + double? longitude, + Value createdByDeviceId = const Value.absent(), + Value endAt = const Value.absent(), + DateTime? createdAt, + DateTime? updatedAt}) => + LocationEntity( + channelCid: channelCid.present ? channelCid.value : this.channelCid, + messageId: messageId.present ? messageId.value : this.messageId, + userId: userId.present ? userId.value : this.userId, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + createdByDeviceId: createdByDeviceId.present + ? createdByDeviceId.value + : this.createdByDeviceId, + endAt: endAt.present ? endAt.value : this.endAt, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ); + LocationEntity copyWithCompanion(LocationsCompanion data) { + return LocationEntity( + channelCid: + data.channelCid.present ? data.channelCid.value : this.channelCid, + messageId: data.messageId.present ? data.messageId.value : this.messageId, + userId: data.userId.present ? data.userId.value : this.userId, + latitude: data.latitude.present ? data.latitude.value : this.latitude, + longitude: data.longitude.present ? data.longitude.value : this.longitude, + createdByDeviceId: data.createdByDeviceId.present + ? data.createdByDeviceId.value + : this.createdByDeviceId, + endAt: data.endAt.present ? data.endAt.value : this.endAt, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ); + } - /// Id of the User who pinned the message - final String? pinnedByUserId; + @override + String toString() { + return (StringBuffer('LocationEntity(') + ..write('channelCid: $channelCid, ') + ..write('messageId: $messageId, ') + ..write('userId: $userId, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('createdByDeviceId: $createdByDeviceId, ') + ..write('endAt: $endAt, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt') + ..write(')')) + .toString(); + } - /// The channel cid of which this message is part of - final String channelCid; + @override + int get hashCode => Object.hash(channelCid, messageId, userId, latitude, + longitude, createdByDeviceId, endAt, createdAt, updatedAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LocationEntity && + other.channelCid == this.channelCid && + other.messageId == this.messageId && + other.userId == this.userId && + other.latitude == this.latitude && + other.longitude == this.longitude && + other.createdByDeviceId == this.createdByDeviceId && + other.endAt == this.endAt && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt); +} - /// A Map of [messageText] translations. - final Map? i18n; +class LocationsCompanion extends UpdateCompanion { + final Value channelCid; + final Value messageId; + final Value userId; + final Value latitude; + final Value longitude; + final Value createdByDeviceId; + final Value endAt; + final Value createdAt; + final Value updatedAt; + final Value rowid; + const LocationsCompanion({ + this.channelCid = const Value.absent(), + this.messageId = const Value.absent(), + this.userId = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + this.createdByDeviceId = const Value.absent(), + this.endAt = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + LocationsCompanion.insert({ + this.channelCid = const Value.absent(), + this.messageId = const Value.absent(), + this.userId = const Value.absent(), + required double latitude, + required double longitude, + this.createdByDeviceId = const Value.absent(), + this.endAt = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : latitude = Value(latitude), + longitude = Value(longitude); + static Insertable custom({ + Expression? channelCid, + Expression? messageId, + Expression? userId, + Expression? latitude, + Expression? longitude, + Expression? createdByDeviceId, + Expression? endAt, + Expression? createdAt, + Expression? updatedAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (channelCid != null) 'channel_cid': channelCid, + if (messageId != null) 'message_id': messageId, + if (userId != null) 'user_id': userId, + if (latitude != null) 'latitude': latitude, + if (longitude != null) 'longitude': longitude, + if (createdByDeviceId != null) 'created_by_device_id': createdByDeviceId, + if (endAt != null) 'end_at': endAt, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (rowid != null) 'rowid': rowid, + }); + } - /// The list of user ids that should be able to see the message. - final List? restrictedVisibility; + LocationsCompanion copyWith( + {Value? channelCid, + Value? messageId, + Value? userId, + Value? latitude, + Value? longitude, + Value? createdByDeviceId, + Value? endAt, + Value? createdAt, + Value? updatedAt, + Value? rowid}) { + return LocationsCompanion( + channelCid: channelCid ?? this.channelCid, + messageId: messageId ?? this.messageId, + userId: userId ?? this.userId, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + createdByDeviceId: createdByDeviceId ?? this.createdByDeviceId, + endAt: endAt ?? this.endAt, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + rowid: rowid ?? this.rowid, + ); + } - /// Message custom extraData - final Map? extraData; - const PinnedMessageEntity( - {required this.id, - this.messageText, - required this.attachments, - required this.state, - required this.type, - required this.mentionedUsers, - this.reactionGroups, - this.parentId, - this.quotedMessageId, - this.pollId, - this.replyCount, - this.showInChannel, - required this.shadowed, - this.command, - this.localCreatedAt, - this.remoteCreatedAt, - this.localUpdatedAt, - this.remoteUpdatedAt, - this.localDeletedAt, - this.remoteDeletedAt, - this.messageTextUpdatedAt, - this.userId, - required this.pinned, - this.pinnedAt, - this.pinExpires, - this.pinnedByUserId, - required this.channelCid, - this.i18n, - this.restrictedVisibility, - this.extraData}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id); - if (!nullToAbsent || messageText != null) { - map['message_text'] = Variable(messageText); - } - { - map['attachments'] = Variable( - $PinnedMessagesTable.$converterattachments.toSql(attachments)); - } - map['state'] = Variable(state); - map['type'] = Variable(type); - { - map['mentioned_users'] = Variable( - $PinnedMessagesTable.$convertermentionedUsers.toSql(mentionedUsers)); - } - if (!nullToAbsent || reactionGroups != null) { - map['reaction_groups'] = Variable( - $PinnedMessagesTable.$converterreactionGroupsn.toSql(reactionGroups)); - } - if (!nullToAbsent || parentId != null) { - map['parent_id'] = Variable(parentId); - } - if (!nullToAbsent || quotedMessageId != null) { - map['quoted_message_id'] = Variable(quotedMessageId); - } - if (!nullToAbsent || pollId != null) { - map['poll_id'] = Variable(pollId); - } - if (!nullToAbsent || replyCount != null) { - map['reply_count'] = Variable(replyCount); - } - if (!nullToAbsent || showInChannel != null) { - map['show_in_channel'] = Variable(showInChannel); - } - map['shadowed'] = Variable(shadowed); - if (!nullToAbsent || command != null) { - map['command'] = Variable(command); - } - if (!nullToAbsent || localCreatedAt != null) { - map['local_created_at'] = Variable(localCreatedAt); - } - if (!nullToAbsent || remoteCreatedAt != null) { - map['remote_created_at'] = Variable(remoteCreatedAt); - } - if (!nullToAbsent || localUpdatedAt != null) { - map['local_updated_at'] = Variable(localUpdatedAt); + if (channelCid.present) { + map['channel_cid'] = Variable(channelCid.value); } - if (!nullToAbsent || remoteUpdatedAt != null) { - map['remote_updated_at'] = Variable(remoteUpdatedAt); + if (messageId.present) { + map['message_id'] = Variable(messageId.value); } - if (!nullToAbsent || localDeletedAt != null) { - map['local_deleted_at'] = Variable(localDeletedAt); + if (userId.present) { + map['user_id'] = Variable(userId.value); } - if (!nullToAbsent || remoteDeletedAt != null) { - map['remote_deleted_at'] = Variable(remoteDeletedAt); + if (latitude.present) { + map['latitude'] = Variable(latitude.value); } - if (!nullToAbsent || messageTextUpdatedAt != null) { - map['message_text_updated_at'] = Variable(messageTextUpdatedAt); + if (longitude.present) { + map['longitude'] = Variable(longitude.value); } - if (!nullToAbsent || userId != null) { - map['user_id'] = Variable(userId); + if (createdByDeviceId.present) { + map['created_by_device_id'] = Variable(createdByDeviceId.value); } - map['pinned'] = Variable(pinned); - if (!nullToAbsent || pinnedAt != null) { - map['pinned_at'] = Variable(pinnedAt); + if (endAt.present) { + map['end_at'] = Variable(endAt.value); } - if (!nullToAbsent || pinExpires != null) { - map['pin_expires'] = Variable(pinExpires); + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); } - if (!nullToAbsent || pinnedByUserId != null) { - map['pinned_by_user_id'] = Variable(pinnedByUserId); + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); } - map['channel_cid'] = Variable(channelCid); - if (!nullToAbsent || i18n != null) { - map['i18n'] = - Variable($PinnedMessagesTable.$converteri18n.toSql(i18n)); - } - if (!nullToAbsent || restrictedVisibility != null) { - map['restricted_visibility'] = Variable($PinnedMessagesTable - .$converterrestrictedVisibilityn - .toSql(restrictedVisibility)); - } - if (!nullToAbsent || extraData != null) { - map['extra_data'] = Variable( - $PinnedMessagesTable.$converterextraDatan.toSql(extraData)); + if (rowid.present) { + map['rowid'] = Variable(rowid.value); } return map; } - factory PinnedMessageEntity.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return PinnedMessageEntity( - id: serializer.fromJson(json['id']), - messageText: serializer.fromJson(json['messageText']), - attachments: serializer.fromJson>(json['attachments']), - state: serializer.fromJson(json['state']), - type: serializer.fromJson(json['type']), - mentionedUsers: serializer.fromJson>(json['mentionedUsers']), - reactionGroups: serializer - .fromJson?>(json['reactionGroups']), - parentId: serializer.fromJson(json['parentId']), - quotedMessageId: serializer.fromJson(json['quotedMessageId']), - pollId: serializer.fromJson(json['pollId']), - replyCount: serializer.fromJson(json['replyCount']), - showInChannel: serializer.fromJson(json['showInChannel']), - shadowed: serializer.fromJson(json['shadowed']), - command: serializer.fromJson(json['command']), - localCreatedAt: serializer.fromJson(json['localCreatedAt']), - remoteCreatedAt: serializer.fromJson(json['remoteCreatedAt']), - localUpdatedAt: serializer.fromJson(json['localUpdatedAt']), - remoteUpdatedAt: serializer.fromJson(json['remoteUpdatedAt']), - localDeletedAt: serializer.fromJson(json['localDeletedAt']), - remoteDeletedAt: serializer.fromJson(json['remoteDeletedAt']), - messageTextUpdatedAt: - serializer.fromJson(json['messageTextUpdatedAt']), - userId: serializer.fromJson(json['userId']), - pinned: serializer.fromJson(json['pinned']), - pinnedAt: serializer.fromJson(json['pinnedAt']), - pinExpires: serializer.fromJson(json['pinExpires']), - pinnedByUserId: serializer.fromJson(json['pinnedByUserId']), - channelCid: serializer.fromJson(json['channelCid']), - i18n: serializer.fromJson?>(json['i18n']), - restrictedVisibility: - serializer.fromJson?>(json['restrictedVisibility']), - extraData: serializer.fromJson?>(json['extraData']), - ); - } @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'id': serializer.toJson(id), - 'messageText': serializer.toJson(messageText), - 'attachments': serializer.toJson>(attachments), - 'state': serializer.toJson(state), - 'type': serializer.toJson(type), - 'mentionedUsers': serializer.toJson>(mentionedUsers), - 'reactionGroups': - serializer.toJson?>(reactionGroups), - 'parentId': serializer.toJson(parentId), - 'quotedMessageId': serializer.toJson(quotedMessageId), - 'pollId': serializer.toJson(pollId), - 'replyCount': serializer.toJson(replyCount), - 'showInChannel': serializer.toJson(showInChannel), - 'shadowed': serializer.toJson(shadowed), - 'command': serializer.toJson(command), - 'localCreatedAt': serializer.toJson(localCreatedAt), - 'remoteCreatedAt': serializer.toJson(remoteCreatedAt), - 'localUpdatedAt': serializer.toJson(localUpdatedAt), - 'remoteUpdatedAt': serializer.toJson(remoteUpdatedAt), - 'localDeletedAt': serializer.toJson(localDeletedAt), - 'remoteDeletedAt': serializer.toJson(remoteDeletedAt), - 'messageTextUpdatedAt': - serializer.toJson(messageTextUpdatedAt), - 'userId': serializer.toJson(userId), - 'pinned': serializer.toJson(pinned), - 'pinnedAt': serializer.toJson(pinnedAt), - 'pinExpires': serializer.toJson(pinExpires), - 'pinnedByUserId': serializer.toJson(pinnedByUserId), - 'channelCid': serializer.toJson(channelCid), - 'i18n': serializer.toJson?>(i18n), - 'restrictedVisibility': - serializer.toJson?>(restrictedVisibility), - 'extraData': serializer.toJson?>(extraData), - }; - } - - PinnedMessageEntity copyWith( - {String? id, - Value messageText = const Value.absent(), - List? attachments, - String? state, - String? type, - List? mentionedUsers, - Value?> reactionGroups = - const Value.absent(), - Value parentId = const Value.absent(), - Value quotedMessageId = const Value.absent(), - Value pollId = const Value.absent(), - Value replyCount = const Value.absent(), - Value showInChannel = const Value.absent(), - bool? shadowed, - Value command = const Value.absent(), - Value localCreatedAt = const Value.absent(), - Value remoteCreatedAt = const Value.absent(), - Value localUpdatedAt = const Value.absent(), - Value remoteUpdatedAt = const Value.absent(), - Value localDeletedAt = const Value.absent(), - Value remoteDeletedAt = const Value.absent(), - Value messageTextUpdatedAt = const Value.absent(), - Value userId = const Value.absent(), - bool? pinned, - Value pinnedAt = const Value.absent(), - Value pinExpires = const Value.absent(), - Value pinnedByUserId = const Value.absent(), - String? channelCid, - Value?> i18n = const Value.absent(), - Value?> restrictedVisibility = const Value.absent(), - Value?> extraData = const Value.absent()}) => - PinnedMessageEntity( - id: id ?? this.id, - messageText: messageText.present ? messageText.value : this.messageText, - attachments: attachments ?? this.attachments, - state: state ?? this.state, - type: type ?? this.type, - mentionedUsers: mentionedUsers ?? this.mentionedUsers, - reactionGroups: - reactionGroups.present ? reactionGroups.value : this.reactionGroups, - parentId: parentId.present ? parentId.value : this.parentId, - quotedMessageId: quotedMessageId.present - ? quotedMessageId.value - : this.quotedMessageId, - pollId: pollId.present ? pollId.value : this.pollId, - replyCount: replyCount.present ? replyCount.value : this.replyCount, - showInChannel: - showInChannel.present ? showInChannel.value : this.showInChannel, - shadowed: shadowed ?? this.shadowed, - command: command.present ? command.value : this.command, - localCreatedAt: - localCreatedAt.present ? localCreatedAt.value : this.localCreatedAt, - remoteCreatedAt: remoteCreatedAt.present - ? remoteCreatedAt.value - : this.remoteCreatedAt, - localUpdatedAt: - localUpdatedAt.present ? localUpdatedAt.value : this.localUpdatedAt, - remoteUpdatedAt: remoteUpdatedAt.present - ? remoteUpdatedAt.value - : this.remoteUpdatedAt, - localDeletedAt: - localDeletedAt.present ? localDeletedAt.value : this.localDeletedAt, - remoteDeletedAt: remoteDeletedAt.present - ? remoteDeletedAt.value - : this.remoteDeletedAt, - messageTextUpdatedAt: messageTextUpdatedAt.present - ? messageTextUpdatedAt.value - : this.messageTextUpdatedAt, - userId: userId.present ? userId.value : this.userId, - pinned: pinned ?? this.pinned, - pinnedAt: pinnedAt.present ? pinnedAt.value : this.pinnedAt, - pinExpires: pinExpires.present ? pinExpires.value : this.pinExpires, - pinnedByUserId: - pinnedByUserId.present ? pinnedByUserId.value : this.pinnedByUserId, - channelCid: channelCid ?? this.channelCid, - i18n: i18n.present ? i18n.value : this.i18n, - restrictedVisibility: restrictedVisibility.present - ? restrictedVisibility.value - : this.restrictedVisibility, - extraData: extraData.present ? extraData.value : this.extraData, - ); - PinnedMessageEntity copyWithCompanion(PinnedMessagesCompanion data) { - return PinnedMessageEntity( - id: data.id.present ? data.id.value : this.id, - messageText: - data.messageText.present ? data.messageText.value : this.messageText, - attachments: - data.attachments.present ? data.attachments.value : this.attachments, - state: data.state.present ? data.state.value : this.state, - type: data.type.present ? data.type.value : this.type, - mentionedUsers: data.mentionedUsers.present - ? data.mentionedUsers.value - : this.mentionedUsers, - reactionGroups: data.reactionGroups.present - ? data.reactionGroups.value - : this.reactionGroups, - parentId: data.parentId.present ? data.parentId.value : this.parentId, - quotedMessageId: data.quotedMessageId.present - ? data.quotedMessageId.value - : this.quotedMessageId, - pollId: data.pollId.present ? data.pollId.value : this.pollId, - replyCount: - data.replyCount.present ? data.replyCount.value : this.replyCount, - showInChannel: data.showInChannel.present - ? data.showInChannel.value - : this.showInChannel, - shadowed: data.shadowed.present ? data.shadowed.value : this.shadowed, - command: data.command.present ? data.command.value : this.command, - localCreatedAt: data.localCreatedAt.present - ? data.localCreatedAt.value - : this.localCreatedAt, - remoteCreatedAt: data.remoteCreatedAt.present - ? data.remoteCreatedAt.value - : this.remoteCreatedAt, - localUpdatedAt: data.localUpdatedAt.present - ? data.localUpdatedAt.value - : this.localUpdatedAt, - remoteUpdatedAt: data.remoteUpdatedAt.present - ? data.remoteUpdatedAt.value - : this.remoteUpdatedAt, - localDeletedAt: data.localDeletedAt.present - ? data.localDeletedAt.value - : this.localDeletedAt, - remoteDeletedAt: data.remoteDeletedAt.present - ? data.remoteDeletedAt.value - : this.remoteDeletedAt, - messageTextUpdatedAt: data.messageTextUpdatedAt.present - ? data.messageTextUpdatedAt.value - : this.messageTextUpdatedAt, - userId: data.userId.present ? data.userId.value : this.userId, - pinned: data.pinned.present ? data.pinned.value : this.pinned, - pinnedAt: data.pinnedAt.present ? data.pinnedAt.value : this.pinnedAt, - pinExpires: - data.pinExpires.present ? data.pinExpires.value : this.pinExpires, - pinnedByUserId: data.pinnedByUserId.present - ? data.pinnedByUserId.value - : this.pinnedByUserId, - channelCid: - data.channelCid.present ? data.channelCid.value : this.channelCid, - i18n: data.i18n.present ? data.i18n.value : this.i18n, - restrictedVisibility: data.restrictedVisibility.present - ? data.restrictedVisibility.value - : this.restrictedVisibility, - extraData: data.extraData.present ? data.extraData.value : this.extraData, - ); + String toString() { + return (StringBuffer('LocationsCompanion(') + ..write('channelCid: $channelCid, ') + ..write('messageId: $messageId, ') + ..write('userId: $userId, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('createdByDeviceId: $createdByDeviceId, ') + ..write('endAt: $endAt, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); } +} +class $PinnedMessagesTable extends PinnedMessages + with TableInfo<$PinnedMessagesTable, PinnedMessageEntity> { @override - String toString() { - return (StringBuffer('PinnedMessageEntity(') - ..write('id: $id, ') - ..write('messageText: $messageText, ') - ..write('attachments: $attachments, ') - ..write('state: $state, ') - ..write('type: $type, ') - ..write('mentionedUsers: $mentionedUsers, ') - ..write('reactionGroups: $reactionGroups, ') - ..write('parentId: $parentId, ') - ..write('quotedMessageId: $quotedMessageId, ') - ..write('pollId: $pollId, ') - ..write('replyCount: $replyCount, ') - ..write('showInChannel: $showInChannel, ') - ..write('shadowed: $shadowed, ') - ..write('command: $command, ') - ..write('localCreatedAt: $localCreatedAt, ') - ..write('remoteCreatedAt: $remoteCreatedAt, ') - ..write('localUpdatedAt: $localUpdatedAt, ') - ..write('remoteUpdatedAt: $remoteUpdatedAt, ') - ..write('localDeletedAt: $localDeletedAt, ') - ..write('remoteDeletedAt: $remoteDeletedAt, ') - ..write('messageTextUpdatedAt: $messageTextUpdatedAt, ') - ..write('userId: $userId, ') - ..write('pinned: $pinned, ') - ..write('pinnedAt: $pinnedAt, ') - ..write('pinExpires: $pinExpires, ') - ..write('pinnedByUserId: $pinnedByUserId, ') - ..write('channelCid: $channelCid, ') - ..write('i18n: $i18n, ') - ..write('restrictedVisibility: $restrictedVisibility, ') - ..write('extraData: $extraData') - ..write(')')) - .toString(); - } - + final GeneratedDatabase attachedDatabase; + final String? _alias; + $PinnedMessagesTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); @override - int get hashCode => Object.hashAll([ + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _messageTextMeta = + const VerificationMeta('messageText'); + @override + late final GeneratedColumn messageText = GeneratedColumn( + 'message_text', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + @override + late final GeneratedColumnWithTypeConverter, String> + attachments = GeneratedColumn('attachments', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true) + .withConverter>( + $PinnedMessagesTable.$converterattachments); + static const VerificationMeta _stateMeta = const VerificationMeta('state'); + @override + late final GeneratedColumn state = GeneratedColumn( + 'state', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _typeMeta = const VerificationMeta('type'); + @override + late final GeneratedColumn type = GeneratedColumn( + 'type', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultValue: const Constant('regular')); + @override + late final GeneratedColumnWithTypeConverter, String> + mentionedUsers = GeneratedColumn( + 'mentioned_users', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true) + .withConverter>( + $PinnedMessagesTable.$convertermentionedUsers); + @override + late final GeneratedColumnWithTypeConverter?, + String> reactionGroups = GeneratedColumn( + 'reaction_groups', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false) + .withConverter?>( + $PinnedMessagesTable.$converterreactionGroupsn); + static const VerificationMeta _parentIdMeta = + const VerificationMeta('parentId'); + @override + late final GeneratedColumn parentId = GeneratedColumn( + 'parent_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _quotedMessageIdMeta = + const VerificationMeta('quotedMessageId'); + @override + late final GeneratedColumn quotedMessageId = GeneratedColumn( + 'quoted_message_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _pollIdMeta = const VerificationMeta('pollId'); + @override + late final GeneratedColumn pollId = GeneratedColumn( + 'poll_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _replyCountMeta = + const VerificationMeta('replyCount'); + @override + late final GeneratedColumn replyCount = GeneratedColumn( + 'reply_count', aliasedName, true, + type: DriftSqlType.int, requiredDuringInsert: false); + static const VerificationMeta _showInChannelMeta = + const VerificationMeta('showInChannel'); + @override + late final GeneratedColumn showInChannel = GeneratedColumn( + 'show_in_channel', aliasedName, true, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("show_in_channel" IN (0, 1))')); + static const VerificationMeta _shadowedMeta = + const VerificationMeta('shadowed'); + @override + late final GeneratedColumn shadowed = GeneratedColumn( + 'shadowed', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("shadowed" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _commandMeta = + const VerificationMeta('command'); + @override + late final GeneratedColumn command = GeneratedColumn( + 'command', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _localCreatedAtMeta = + const VerificationMeta('localCreatedAt'); + @override + late final GeneratedColumn localCreatedAt = + GeneratedColumn('local_created_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _remoteCreatedAtMeta = + const VerificationMeta('remoteCreatedAt'); + @override + late final GeneratedColumn remoteCreatedAt = + GeneratedColumn('remote_created_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _localUpdatedAtMeta = + const VerificationMeta('localUpdatedAt'); + @override + late final GeneratedColumn localUpdatedAt = + GeneratedColumn('local_updated_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _remoteUpdatedAtMeta = + const VerificationMeta('remoteUpdatedAt'); + @override + late final GeneratedColumn remoteUpdatedAt = + GeneratedColumn('remote_updated_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _localDeletedAtMeta = + const VerificationMeta('localDeletedAt'); + @override + late final GeneratedColumn localDeletedAt = + GeneratedColumn('local_deleted_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _remoteDeletedAtMeta = + const VerificationMeta('remoteDeletedAt'); + @override + late final GeneratedColumn remoteDeletedAt = + GeneratedColumn('remote_deleted_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _messageTextUpdatedAtMeta = + const VerificationMeta('messageTextUpdatedAt'); + @override + late final GeneratedColumn messageTextUpdatedAt = + GeneratedColumn('message_text_updated_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + @override + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _pinnedMeta = const VerificationMeta('pinned'); + @override + late final GeneratedColumn pinned = GeneratedColumn( + 'pinned', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("pinned" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _pinnedAtMeta = + const VerificationMeta('pinnedAt'); + @override + late final GeneratedColumn pinnedAt = GeneratedColumn( + 'pinned_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _pinExpiresMeta = + const VerificationMeta('pinExpires'); + @override + late final GeneratedColumn pinExpires = GeneratedColumn( + 'pin_expires', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _pinnedByUserIdMeta = + const VerificationMeta('pinnedByUserId'); + @override + late final GeneratedColumn pinnedByUserId = GeneratedColumn( + 'pinned_by_user_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _channelCidMeta = + const VerificationMeta('channelCid'); + @override + late final GeneratedColumn channelCid = GeneratedColumn( + 'channel_cid', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + @override + late final GeneratedColumnWithTypeConverter?, String> + i18n = GeneratedColumn('i18n', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false) + .withConverter?>( + $PinnedMessagesTable.$converteri18n); + @override + late final GeneratedColumnWithTypeConverter?, String> + restrictedVisibility = GeneratedColumn( + 'restricted_visibility', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false) + .withConverter?>( + $PinnedMessagesTable.$converterrestrictedVisibilityn); + @override + late final GeneratedColumnWithTypeConverter?, String> + extraData = GeneratedColumn('extra_data', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false) + .withConverter?>( + $PinnedMessagesTable.$converterextraDatan); + @override + List get $columns => [ id, messageText, attachments, @@ -3748,278 +3472,2380 @@ class PinnedMessageEntity extends DataClass i18n, restrictedVisibility, extraData - ]); + ]; @override - bool operator ==(Object other) => - identical(this, other) || - (other is PinnedMessageEntity && - other.id == this.id && - other.messageText == this.messageText && - other.attachments == this.attachments && - other.state == this.state && - other.type == this.type && - other.mentionedUsers == this.mentionedUsers && - other.reactionGroups == this.reactionGroups && - other.parentId == this.parentId && - other.quotedMessageId == this.quotedMessageId && - other.pollId == this.pollId && - other.replyCount == this.replyCount && - other.showInChannel == this.showInChannel && - other.shadowed == this.shadowed && - other.command == this.command && - other.localCreatedAt == this.localCreatedAt && - other.remoteCreatedAt == this.remoteCreatedAt && - other.localUpdatedAt == this.localUpdatedAt && - other.remoteUpdatedAt == this.remoteUpdatedAt && - other.localDeletedAt == this.localDeletedAt && - other.remoteDeletedAt == this.remoteDeletedAt && - other.messageTextUpdatedAt == this.messageTextUpdatedAt && - other.userId == this.userId && - other.pinned == this.pinned && - other.pinnedAt == this.pinnedAt && - other.pinExpires == this.pinExpires && - other.pinnedByUserId == this.pinnedByUserId && - other.channelCid == this.channelCid && - other.i18n == this.i18n && - other.restrictedVisibility == this.restrictedVisibility && - other.extraData == this.extraData); -} - + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'pinned_messages'; + @override + VerificationContext validateIntegrity( + Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } else if (isInserting) { + context.missing(_idMeta); + } + if (data.containsKey('message_text')) { + context.handle( + _messageTextMeta, + messageText.isAcceptableOrUnknown( + data['message_text']!, _messageTextMeta)); + } + if (data.containsKey('state')) { + context.handle( + _stateMeta, state.isAcceptableOrUnknown(data['state']!, _stateMeta)); + } else if (isInserting) { + context.missing(_stateMeta); + } + if (data.containsKey('type')) { + context.handle( + _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); + } + if (data.containsKey('parent_id')) { + context.handle(_parentIdMeta, + parentId.isAcceptableOrUnknown(data['parent_id']!, _parentIdMeta)); + } + if (data.containsKey('quoted_message_id')) { + context.handle( + _quotedMessageIdMeta, + quotedMessageId.isAcceptableOrUnknown( + data['quoted_message_id']!, _quotedMessageIdMeta)); + } + if (data.containsKey('poll_id')) { + context.handle(_pollIdMeta, + pollId.isAcceptableOrUnknown(data['poll_id']!, _pollIdMeta)); + } + if (data.containsKey('reply_count')) { + context.handle( + _replyCountMeta, + replyCount.isAcceptableOrUnknown( + data['reply_count']!, _replyCountMeta)); + } + if (data.containsKey('show_in_channel')) { + context.handle( + _showInChannelMeta, + showInChannel.isAcceptableOrUnknown( + data['show_in_channel']!, _showInChannelMeta)); + } + if (data.containsKey('shadowed')) { + context.handle(_shadowedMeta, + shadowed.isAcceptableOrUnknown(data['shadowed']!, _shadowedMeta)); + } + if (data.containsKey('command')) { + context.handle(_commandMeta, + command.isAcceptableOrUnknown(data['command']!, _commandMeta)); + } + if (data.containsKey('local_created_at')) { + context.handle( + _localCreatedAtMeta, + localCreatedAt.isAcceptableOrUnknown( + data['local_created_at']!, _localCreatedAtMeta)); + } + if (data.containsKey('remote_created_at')) { + context.handle( + _remoteCreatedAtMeta, + remoteCreatedAt.isAcceptableOrUnknown( + data['remote_created_at']!, _remoteCreatedAtMeta)); + } + if (data.containsKey('local_updated_at')) { + context.handle( + _localUpdatedAtMeta, + localUpdatedAt.isAcceptableOrUnknown( + data['local_updated_at']!, _localUpdatedAtMeta)); + } + if (data.containsKey('remote_updated_at')) { + context.handle( + _remoteUpdatedAtMeta, + remoteUpdatedAt.isAcceptableOrUnknown( + data['remote_updated_at']!, _remoteUpdatedAtMeta)); + } + if (data.containsKey('local_deleted_at')) { + context.handle( + _localDeletedAtMeta, + localDeletedAt.isAcceptableOrUnknown( + data['local_deleted_at']!, _localDeletedAtMeta)); + } + if (data.containsKey('remote_deleted_at')) { + context.handle( + _remoteDeletedAtMeta, + remoteDeletedAt.isAcceptableOrUnknown( + data['remote_deleted_at']!, _remoteDeletedAtMeta)); + } + if (data.containsKey('message_text_updated_at')) { + context.handle( + _messageTextUpdatedAtMeta, + messageTextUpdatedAt.isAcceptableOrUnknown( + data['message_text_updated_at']!, _messageTextUpdatedAtMeta)); + } + if (data.containsKey('user_id')) { + context.handle(_userIdMeta, + userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); + } + if (data.containsKey('pinned')) { + context.handle(_pinnedMeta, + pinned.isAcceptableOrUnknown(data['pinned']!, _pinnedMeta)); + } + if (data.containsKey('pinned_at')) { + context.handle(_pinnedAtMeta, + pinnedAt.isAcceptableOrUnknown(data['pinned_at']!, _pinnedAtMeta)); + } + if (data.containsKey('pin_expires')) { + context.handle( + _pinExpiresMeta, + pinExpires.isAcceptableOrUnknown( + data['pin_expires']!, _pinExpiresMeta)); + } + if (data.containsKey('pinned_by_user_id')) { + context.handle( + _pinnedByUserIdMeta, + pinnedByUserId.isAcceptableOrUnknown( + data['pinned_by_user_id']!, _pinnedByUserIdMeta)); + } + if (data.containsKey('channel_cid')) { + context.handle( + _channelCidMeta, + channelCid.isAcceptableOrUnknown( + data['channel_cid']!, _channelCidMeta)); + } else if (isInserting) { + context.missing(_channelCidMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + PinnedMessageEntity map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PinnedMessageEntity( + id: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}id'])!, + messageText: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}message_text']), + attachments: $PinnedMessagesTable.$converterattachments.fromSql( + attachedDatabase.typeMapping.read( + DriftSqlType.string, data['${effectivePrefix}attachments'])!), + state: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}state'])!, + type: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}type'])!, + mentionedUsers: $PinnedMessagesTable.$convertermentionedUsers.fromSql( + attachedDatabase.typeMapping.read( + DriftSqlType.string, data['${effectivePrefix}mentioned_users'])!), + reactionGroups: $PinnedMessagesTable.$converterreactionGroupsn.fromSql( + attachedDatabase.typeMapping.read( + DriftSqlType.string, data['${effectivePrefix}reaction_groups'])), + parentId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}parent_id']), + quotedMessageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, data['${effectivePrefix}quoted_message_id']), + pollId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}poll_id']), + replyCount: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}reply_count']), + showInChannel: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}show_in_channel']), + shadowed: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}shadowed'])!, + command: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}command']), + localCreatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}local_created_at']), + remoteCreatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}remote_created_at']), + localUpdatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}local_updated_at']), + remoteUpdatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}remote_updated_at']), + localDeletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}local_deleted_at']), + remoteDeletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}remote_deleted_at']), + messageTextUpdatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}message_text_updated_at']), + userId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}user_id']), + pinned: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}pinned'])!, + pinnedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}pinned_at']), + pinExpires: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}pin_expires']), + pinnedByUserId: attachedDatabase.typeMapping.read( + DriftSqlType.string, data['${effectivePrefix}pinned_by_user_id']), + channelCid: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}channel_cid'])!, + i18n: $PinnedMessagesTable.$converteri18n.fromSql(attachedDatabase + .typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}i18n'])), + restrictedVisibility: $PinnedMessagesTable.$converterrestrictedVisibilityn + .fromSql(attachedDatabase.typeMapping.read(DriftSqlType.string, + data['${effectivePrefix}restricted_visibility'])), + extraData: $PinnedMessagesTable.$converterextraDatan.fromSql( + attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), + ); + } + + @override + $PinnedMessagesTable createAlias(String alias) { + return $PinnedMessagesTable(attachedDatabase, alias); + } + + static TypeConverter, String> $converterattachments = + ListConverter(); + static TypeConverter, String> $convertermentionedUsers = + ListConverter(); + static TypeConverter, String> + $converterreactionGroups = ReactionGroupsConverter(); + static TypeConverter?, String?> + $converterreactionGroupsn = + NullAwareTypeConverter.wrap($converterreactionGroups); + static TypeConverter?, String?> $converteri18n = + NullableMapConverter(); + static TypeConverter, String> $converterrestrictedVisibility = + ListConverter(); + static TypeConverter?, String?> $converterrestrictedVisibilityn = + NullAwareTypeConverter.wrap($converterrestrictedVisibility); + static TypeConverter, String> $converterextraData = + MapConverter(); + static TypeConverter?, String?> $converterextraDatan = + NullAwareTypeConverter.wrap($converterextraData); +} + +class PinnedMessageEntity extends DataClass + implements Insertable { + /// The message id + final String id; + + /// The text of this message + final String? messageText; + + /// The list of attachments, either provided by the user + /// or generated from a command or as a result of URL scraping. + final List attachments; + + /// The current state of the message. + final String state; + + /// The message type + final String type; + + /// The list of user mentioned in the message + final List mentionedUsers; + + /// A map describing the reaction group for every reaction + final Map? reactionGroups; + + /// The ID of the parent message, if the message is a thread reply. + final String? parentId; + + /// The ID of the quoted message, if the message is a quoted reply. + final String? quotedMessageId; + + /// The ID of the poll, if the message is a poll. + final String? pollId; + + /// Number of replies for this message. + final int? replyCount; + + /// Check if this message needs to show in the channel. + final bool? showInChannel; + + /// If true the message is shadowed + final bool shadowed; + + /// A used command name. + final String? command; + + /// The DateTime on which the message was created on the client. + final DateTime? localCreatedAt; + + /// The DateTime on which the message was created on the server. + final DateTime? remoteCreatedAt; + + /// The DateTime on which the message was updated on the client. + final DateTime? localUpdatedAt; + + /// The DateTime on which the message was updated on the server. + final DateTime? remoteUpdatedAt; + + /// The DateTime on which the message was deleted on the client. + final DateTime? localDeletedAt; + + /// The DateTime on which the message was deleted on the server. + final DateTime? remoteDeletedAt; + + /// The DateTime at which the message text was edited + final DateTime? messageTextUpdatedAt; + + /// Id of the User who sent the message + final String? userId; + + /// Whether the message is pinned or not + final bool pinned; + + /// The DateTime at which the message was pinned + final DateTime? pinnedAt; + + /// The DateTime on which the message pin expires + final DateTime? pinExpires; + + /// Id of the User who pinned the message + final String? pinnedByUserId; + + /// The channel cid of which this message is part of + final String channelCid; + + /// A Map of [messageText] translations. + final Map? i18n; + + /// The list of user ids that should be able to see the message. + final List? restrictedVisibility; + + /// Message custom extraData + final Map? extraData; + const PinnedMessageEntity( + {required this.id, + this.messageText, + required this.attachments, + required this.state, + required this.type, + required this.mentionedUsers, + this.reactionGroups, + this.parentId, + this.quotedMessageId, + this.pollId, + this.replyCount, + this.showInChannel, + required this.shadowed, + this.command, + this.localCreatedAt, + this.remoteCreatedAt, + this.localUpdatedAt, + this.remoteUpdatedAt, + this.localDeletedAt, + this.remoteDeletedAt, + this.messageTextUpdatedAt, + this.userId, + required this.pinned, + this.pinnedAt, + this.pinExpires, + this.pinnedByUserId, + required this.channelCid, + this.i18n, + this.restrictedVisibility, + this.extraData}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + if (!nullToAbsent || messageText != null) { + map['message_text'] = Variable(messageText); + } + { + map['attachments'] = Variable( + $PinnedMessagesTable.$converterattachments.toSql(attachments)); + } + map['state'] = Variable(state); + map['type'] = Variable(type); + { + map['mentioned_users'] = Variable( + $PinnedMessagesTable.$convertermentionedUsers.toSql(mentionedUsers)); + } + if (!nullToAbsent || reactionGroups != null) { + map['reaction_groups'] = Variable( + $PinnedMessagesTable.$converterreactionGroupsn.toSql(reactionGroups)); + } + if (!nullToAbsent || parentId != null) { + map['parent_id'] = Variable(parentId); + } + if (!nullToAbsent || quotedMessageId != null) { + map['quoted_message_id'] = Variable(quotedMessageId); + } + if (!nullToAbsent || pollId != null) { + map['poll_id'] = Variable(pollId); + } + if (!nullToAbsent || replyCount != null) { + map['reply_count'] = Variable(replyCount); + } + if (!nullToAbsent || showInChannel != null) { + map['show_in_channel'] = Variable(showInChannel); + } + map['shadowed'] = Variable(shadowed); + if (!nullToAbsent || command != null) { + map['command'] = Variable(command); + } + if (!nullToAbsent || localCreatedAt != null) { + map['local_created_at'] = Variable(localCreatedAt); + } + if (!nullToAbsent || remoteCreatedAt != null) { + map['remote_created_at'] = Variable(remoteCreatedAt); + } + if (!nullToAbsent || localUpdatedAt != null) { + map['local_updated_at'] = Variable(localUpdatedAt); + } + if (!nullToAbsent || remoteUpdatedAt != null) { + map['remote_updated_at'] = Variable(remoteUpdatedAt); + } + if (!nullToAbsent || localDeletedAt != null) { + map['local_deleted_at'] = Variable(localDeletedAt); + } + if (!nullToAbsent || remoteDeletedAt != null) { + map['remote_deleted_at'] = Variable(remoteDeletedAt); + } + if (!nullToAbsent || messageTextUpdatedAt != null) { + map['message_text_updated_at'] = Variable(messageTextUpdatedAt); + } + if (!nullToAbsent || userId != null) { + map['user_id'] = Variable(userId); + } + map['pinned'] = Variable(pinned); + if (!nullToAbsent || pinnedAt != null) { + map['pinned_at'] = Variable(pinnedAt); + } + if (!nullToAbsent || pinExpires != null) { + map['pin_expires'] = Variable(pinExpires); + } + if (!nullToAbsent || pinnedByUserId != null) { + map['pinned_by_user_id'] = Variable(pinnedByUserId); + } + map['channel_cid'] = Variable(channelCid); + if (!nullToAbsent || i18n != null) { + map['i18n'] = + Variable($PinnedMessagesTable.$converteri18n.toSql(i18n)); + } + if (!nullToAbsent || restrictedVisibility != null) { + map['restricted_visibility'] = Variable($PinnedMessagesTable + .$converterrestrictedVisibilityn + .toSql(restrictedVisibility)); + } + if (!nullToAbsent || extraData != null) { + map['extra_data'] = Variable( + $PinnedMessagesTable.$converterextraDatan.toSql(extraData)); + } + return map; + } + + factory PinnedMessageEntity.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PinnedMessageEntity( + id: serializer.fromJson(json['id']), + messageText: serializer.fromJson(json['messageText']), + attachments: serializer.fromJson>(json['attachments']), + state: serializer.fromJson(json['state']), + type: serializer.fromJson(json['type']), + mentionedUsers: serializer.fromJson>(json['mentionedUsers']), + reactionGroups: serializer + .fromJson?>(json['reactionGroups']), + parentId: serializer.fromJson(json['parentId']), + quotedMessageId: serializer.fromJson(json['quotedMessageId']), + pollId: serializer.fromJson(json['pollId']), + replyCount: serializer.fromJson(json['replyCount']), + showInChannel: serializer.fromJson(json['showInChannel']), + shadowed: serializer.fromJson(json['shadowed']), + command: serializer.fromJson(json['command']), + localCreatedAt: serializer.fromJson(json['localCreatedAt']), + remoteCreatedAt: serializer.fromJson(json['remoteCreatedAt']), + localUpdatedAt: serializer.fromJson(json['localUpdatedAt']), + remoteUpdatedAt: serializer.fromJson(json['remoteUpdatedAt']), + localDeletedAt: serializer.fromJson(json['localDeletedAt']), + remoteDeletedAt: serializer.fromJson(json['remoteDeletedAt']), + messageTextUpdatedAt: + serializer.fromJson(json['messageTextUpdatedAt']), + userId: serializer.fromJson(json['userId']), + pinned: serializer.fromJson(json['pinned']), + pinnedAt: serializer.fromJson(json['pinnedAt']), + pinExpires: serializer.fromJson(json['pinExpires']), + pinnedByUserId: serializer.fromJson(json['pinnedByUserId']), + channelCid: serializer.fromJson(json['channelCid']), + i18n: serializer.fromJson?>(json['i18n']), + restrictedVisibility: + serializer.fromJson?>(json['restrictedVisibility']), + extraData: serializer.fromJson?>(json['extraData']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'messageText': serializer.toJson(messageText), + 'attachments': serializer.toJson>(attachments), + 'state': serializer.toJson(state), + 'type': serializer.toJson(type), + 'mentionedUsers': serializer.toJson>(mentionedUsers), + 'reactionGroups': + serializer.toJson?>(reactionGroups), + 'parentId': serializer.toJson(parentId), + 'quotedMessageId': serializer.toJson(quotedMessageId), + 'pollId': serializer.toJson(pollId), + 'replyCount': serializer.toJson(replyCount), + 'showInChannel': serializer.toJson(showInChannel), + 'shadowed': serializer.toJson(shadowed), + 'command': serializer.toJson(command), + 'localCreatedAt': serializer.toJson(localCreatedAt), + 'remoteCreatedAt': serializer.toJson(remoteCreatedAt), + 'localUpdatedAt': serializer.toJson(localUpdatedAt), + 'remoteUpdatedAt': serializer.toJson(remoteUpdatedAt), + 'localDeletedAt': serializer.toJson(localDeletedAt), + 'remoteDeletedAt': serializer.toJson(remoteDeletedAt), + 'messageTextUpdatedAt': + serializer.toJson(messageTextUpdatedAt), + 'userId': serializer.toJson(userId), + 'pinned': serializer.toJson(pinned), + 'pinnedAt': serializer.toJson(pinnedAt), + 'pinExpires': serializer.toJson(pinExpires), + 'pinnedByUserId': serializer.toJson(pinnedByUserId), + 'channelCid': serializer.toJson(channelCid), + 'i18n': serializer.toJson?>(i18n), + 'restrictedVisibility': + serializer.toJson?>(restrictedVisibility), + 'extraData': serializer.toJson?>(extraData), + }; + } + + PinnedMessageEntity copyWith( + {String? id, + Value messageText = const Value.absent(), + List? attachments, + String? state, + String? type, + List? mentionedUsers, + Value?> reactionGroups = + const Value.absent(), + Value parentId = const Value.absent(), + Value quotedMessageId = const Value.absent(), + Value pollId = const Value.absent(), + Value replyCount = const Value.absent(), + Value showInChannel = const Value.absent(), + bool? shadowed, + Value command = const Value.absent(), + Value localCreatedAt = const Value.absent(), + Value remoteCreatedAt = const Value.absent(), + Value localUpdatedAt = const Value.absent(), + Value remoteUpdatedAt = const Value.absent(), + Value localDeletedAt = const Value.absent(), + Value remoteDeletedAt = const Value.absent(), + Value messageTextUpdatedAt = const Value.absent(), + Value userId = const Value.absent(), + bool? pinned, + Value pinnedAt = const Value.absent(), + Value pinExpires = const Value.absent(), + Value pinnedByUserId = const Value.absent(), + String? channelCid, + Value?> i18n = const Value.absent(), + Value?> restrictedVisibility = const Value.absent(), + Value?> extraData = const Value.absent()}) => + PinnedMessageEntity( + id: id ?? this.id, + messageText: messageText.present ? messageText.value : this.messageText, + attachments: attachments ?? this.attachments, + state: state ?? this.state, + type: type ?? this.type, + mentionedUsers: mentionedUsers ?? this.mentionedUsers, + reactionGroups: + reactionGroups.present ? reactionGroups.value : this.reactionGroups, + parentId: parentId.present ? parentId.value : this.parentId, + quotedMessageId: quotedMessageId.present + ? quotedMessageId.value + : this.quotedMessageId, + pollId: pollId.present ? pollId.value : this.pollId, + replyCount: replyCount.present ? replyCount.value : this.replyCount, + showInChannel: + showInChannel.present ? showInChannel.value : this.showInChannel, + shadowed: shadowed ?? this.shadowed, + command: command.present ? command.value : this.command, + localCreatedAt: + localCreatedAt.present ? localCreatedAt.value : this.localCreatedAt, + remoteCreatedAt: remoteCreatedAt.present + ? remoteCreatedAt.value + : this.remoteCreatedAt, + localUpdatedAt: + localUpdatedAt.present ? localUpdatedAt.value : this.localUpdatedAt, + remoteUpdatedAt: remoteUpdatedAt.present + ? remoteUpdatedAt.value + : this.remoteUpdatedAt, + localDeletedAt: + localDeletedAt.present ? localDeletedAt.value : this.localDeletedAt, + remoteDeletedAt: remoteDeletedAt.present + ? remoteDeletedAt.value + : this.remoteDeletedAt, + messageTextUpdatedAt: messageTextUpdatedAt.present + ? messageTextUpdatedAt.value + : this.messageTextUpdatedAt, + userId: userId.present ? userId.value : this.userId, + pinned: pinned ?? this.pinned, + pinnedAt: pinnedAt.present ? pinnedAt.value : this.pinnedAt, + pinExpires: pinExpires.present ? pinExpires.value : this.pinExpires, + pinnedByUserId: + pinnedByUserId.present ? pinnedByUserId.value : this.pinnedByUserId, + channelCid: channelCid ?? this.channelCid, + i18n: i18n.present ? i18n.value : this.i18n, + restrictedVisibility: restrictedVisibility.present + ? restrictedVisibility.value + : this.restrictedVisibility, + extraData: extraData.present ? extraData.value : this.extraData, + ); + PinnedMessageEntity copyWithCompanion(PinnedMessagesCompanion data) { + return PinnedMessageEntity( + id: data.id.present ? data.id.value : this.id, + messageText: + data.messageText.present ? data.messageText.value : this.messageText, + attachments: + data.attachments.present ? data.attachments.value : this.attachments, + state: data.state.present ? data.state.value : this.state, + type: data.type.present ? data.type.value : this.type, + mentionedUsers: data.mentionedUsers.present + ? data.mentionedUsers.value + : this.mentionedUsers, + reactionGroups: data.reactionGroups.present + ? data.reactionGroups.value + : this.reactionGroups, + parentId: data.parentId.present ? data.parentId.value : this.parentId, + quotedMessageId: data.quotedMessageId.present + ? data.quotedMessageId.value + : this.quotedMessageId, + pollId: data.pollId.present ? data.pollId.value : this.pollId, + replyCount: + data.replyCount.present ? data.replyCount.value : this.replyCount, + showInChannel: data.showInChannel.present + ? data.showInChannel.value + : this.showInChannel, + shadowed: data.shadowed.present ? data.shadowed.value : this.shadowed, + command: data.command.present ? data.command.value : this.command, + localCreatedAt: data.localCreatedAt.present + ? data.localCreatedAt.value + : this.localCreatedAt, + remoteCreatedAt: data.remoteCreatedAt.present + ? data.remoteCreatedAt.value + : this.remoteCreatedAt, + localUpdatedAt: data.localUpdatedAt.present + ? data.localUpdatedAt.value + : this.localUpdatedAt, + remoteUpdatedAt: data.remoteUpdatedAt.present + ? data.remoteUpdatedAt.value + : this.remoteUpdatedAt, + localDeletedAt: data.localDeletedAt.present + ? data.localDeletedAt.value + : this.localDeletedAt, + remoteDeletedAt: data.remoteDeletedAt.present + ? data.remoteDeletedAt.value + : this.remoteDeletedAt, + messageTextUpdatedAt: data.messageTextUpdatedAt.present + ? data.messageTextUpdatedAt.value + : this.messageTextUpdatedAt, + userId: data.userId.present ? data.userId.value : this.userId, + pinned: data.pinned.present ? data.pinned.value : this.pinned, + pinnedAt: data.pinnedAt.present ? data.pinnedAt.value : this.pinnedAt, + pinExpires: + data.pinExpires.present ? data.pinExpires.value : this.pinExpires, + pinnedByUserId: data.pinnedByUserId.present + ? data.pinnedByUserId.value + : this.pinnedByUserId, + channelCid: + data.channelCid.present ? data.channelCid.value : this.channelCid, + i18n: data.i18n.present ? data.i18n.value : this.i18n, + restrictedVisibility: data.restrictedVisibility.present + ? data.restrictedVisibility.value + : this.restrictedVisibility, + extraData: data.extraData.present ? data.extraData.value : this.extraData, + ); + } + + @override + String toString() { + return (StringBuffer('PinnedMessageEntity(') + ..write('id: $id, ') + ..write('messageText: $messageText, ') + ..write('attachments: $attachments, ') + ..write('state: $state, ') + ..write('type: $type, ') + ..write('mentionedUsers: $mentionedUsers, ') + ..write('reactionGroups: $reactionGroups, ') + ..write('parentId: $parentId, ') + ..write('quotedMessageId: $quotedMessageId, ') + ..write('pollId: $pollId, ') + ..write('replyCount: $replyCount, ') + ..write('showInChannel: $showInChannel, ') + ..write('shadowed: $shadowed, ') + ..write('command: $command, ') + ..write('localCreatedAt: $localCreatedAt, ') + ..write('remoteCreatedAt: $remoteCreatedAt, ') + ..write('localUpdatedAt: $localUpdatedAt, ') + ..write('remoteUpdatedAt: $remoteUpdatedAt, ') + ..write('localDeletedAt: $localDeletedAt, ') + ..write('remoteDeletedAt: $remoteDeletedAt, ') + ..write('messageTextUpdatedAt: $messageTextUpdatedAt, ') + ..write('userId: $userId, ') + ..write('pinned: $pinned, ') + ..write('pinnedAt: $pinnedAt, ') + ..write('pinExpires: $pinExpires, ') + ..write('pinnedByUserId: $pinnedByUserId, ') + ..write('channelCid: $channelCid, ') + ..write('i18n: $i18n, ') + ..write('restrictedVisibility: $restrictedVisibility, ') + ..write('extraData: $extraData') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hashAll([ + id, + messageText, + attachments, + state, + type, + mentionedUsers, + reactionGroups, + parentId, + quotedMessageId, + pollId, + replyCount, + showInChannel, + shadowed, + command, + localCreatedAt, + remoteCreatedAt, + localUpdatedAt, + remoteUpdatedAt, + localDeletedAt, + remoteDeletedAt, + messageTextUpdatedAt, + userId, + pinned, + pinnedAt, + pinExpires, + pinnedByUserId, + channelCid, + i18n, + restrictedVisibility, + extraData + ]); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PinnedMessageEntity && + other.id == this.id && + other.messageText == this.messageText && + other.attachments == this.attachments && + other.state == this.state && + other.type == this.type && + other.mentionedUsers == this.mentionedUsers && + other.reactionGroups == this.reactionGroups && + other.parentId == this.parentId && + other.quotedMessageId == this.quotedMessageId && + other.pollId == this.pollId && + other.replyCount == this.replyCount && + other.showInChannel == this.showInChannel && + other.shadowed == this.shadowed && + other.command == this.command && + other.localCreatedAt == this.localCreatedAt && + other.remoteCreatedAt == this.remoteCreatedAt && + other.localUpdatedAt == this.localUpdatedAt && + other.remoteUpdatedAt == this.remoteUpdatedAt && + other.localDeletedAt == this.localDeletedAt && + other.remoteDeletedAt == this.remoteDeletedAt && + other.messageTextUpdatedAt == this.messageTextUpdatedAt && + other.userId == this.userId && + other.pinned == this.pinned && + other.pinnedAt == this.pinnedAt && + other.pinExpires == this.pinExpires && + other.pinnedByUserId == this.pinnedByUserId && + other.channelCid == this.channelCid && + other.i18n == this.i18n && + other.restrictedVisibility == this.restrictedVisibility && + other.extraData == this.extraData); +} + class PinnedMessagesCompanion extends UpdateCompanion { final Value id; - final Value messageText; - final Value> attachments; - final Value state; - final Value type; - final Value> mentionedUsers; - final Value?> reactionGroups; - final Value parentId; - final Value quotedMessageId; + final Value messageText; + final Value> attachments; + final Value state; + final Value type; + final Value> mentionedUsers; + final Value?> reactionGroups; + final Value parentId; + final Value quotedMessageId; + final Value pollId; + final Value replyCount; + final Value showInChannel; + final Value shadowed; + final Value command; + final Value localCreatedAt; + final Value remoteCreatedAt; + final Value localUpdatedAt; + final Value remoteUpdatedAt; + final Value localDeletedAt; + final Value remoteDeletedAt; + final Value messageTextUpdatedAt; + final Value userId; + final Value pinned; + final Value pinnedAt; + final Value pinExpires; + final Value pinnedByUserId; + final Value channelCid; + final Value?> i18n; + final Value?> restrictedVisibility; + final Value?> extraData; + final Value rowid; + const PinnedMessagesCompanion({ + this.id = const Value.absent(), + this.messageText = const Value.absent(), + this.attachments = const Value.absent(), + this.state = const Value.absent(), + this.type = const Value.absent(), + this.mentionedUsers = const Value.absent(), + this.reactionGroups = const Value.absent(), + this.parentId = const Value.absent(), + this.quotedMessageId = const Value.absent(), + this.pollId = const Value.absent(), + this.replyCount = const Value.absent(), + this.showInChannel = const Value.absent(), + this.shadowed = const Value.absent(), + this.command = const Value.absent(), + this.localCreatedAt = const Value.absent(), + this.remoteCreatedAt = const Value.absent(), + this.localUpdatedAt = const Value.absent(), + this.remoteUpdatedAt = const Value.absent(), + this.localDeletedAt = const Value.absent(), + this.remoteDeletedAt = const Value.absent(), + this.messageTextUpdatedAt = const Value.absent(), + this.userId = const Value.absent(), + this.pinned = const Value.absent(), + this.pinnedAt = const Value.absent(), + this.pinExpires = const Value.absent(), + this.pinnedByUserId = const Value.absent(), + this.channelCid = const Value.absent(), + this.i18n = const Value.absent(), + this.restrictedVisibility = const Value.absent(), + this.extraData = const Value.absent(), + this.rowid = const Value.absent(), + }); + PinnedMessagesCompanion.insert({ + required String id, + this.messageText = const Value.absent(), + required List attachments, + required String state, + this.type = const Value.absent(), + required List mentionedUsers, + this.reactionGroups = const Value.absent(), + this.parentId = const Value.absent(), + this.quotedMessageId = const Value.absent(), + this.pollId = const Value.absent(), + this.replyCount = const Value.absent(), + this.showInChannel = const Value.absent(), + this.shadowed = const Value.absent(), + this.command = const Value.absent(), + this.localCreatedAt = const Value.absent(), + this.remoteCreatedAt = const Value.absent(), + this.localUpdatedAt = const Value.absent(), + this.remoteUpdatedAt = const Value.absent(), + this.localDeletedAt = const Value.absent(), + this.remoteDeletedAt = const Value.absent(), + this.messageTextUpdatedAt = const Value.absent(), + this.userId = const Value.absent(), + this.pinned = const Value.absent(), + this.pinnedAt = const Value.absent(), + this.pinExpires = const Value.absent(), + this.pinnedByUserId = const Value.absent(), + required String channelCid, + this.i18n = const Value.absent(), + this.restrictedVisibility = const Value.absent(), + this.extraData = const Value.absent(), + this.rowid = const Value.absent(), + }) : id = Value(id), + attachments = Value(attachments), + state = Value(state), + mentionedUsers = Value(mentionedUsers), + channelCid = Value(channelCid); + static Insertable custom({ + Expression? id, + Expression? messageText, + Expression? attachments, + Expression? state, + Expression? type, + Expression? mentionedUsers, + Expression? reactionGroups, + Expression? parentId, + Expression? quotedMessageId, + Expression? pollId, + Expression? replyCount, + Expression? showInChannel, + Expression? shadowed, + Expression? command, + Expression? localCreatedAt, + Expression? remoteCreatedAt, + Expression? localUpdatedAt, + Expression? remoteUpdatedAt, + Expression? localDeletedAt, + Expression? remoteDeletedAt, + Expression? messageTextUpdatedAt, + Expression? userId, + Expression? pinned, + Expression? pinnedAt, + Expression? pinExpires, + Expression? pinnedByUserId, + Expression? channelCid, + Expression? i18n, + Expression? restrictedVisibility, + Expression? extraData, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (messageText != null) 'message_text': messageText, + if (attachments != null) 'attachments': attachments, + if (state != null) 'state': state, + if (type != null) 'type': type, + if (mentionedUsers != null) 'mentioned_users': mentionedUsers, + if (reactionGroups != null) 'reaction_groups': reactionGroups, + if (parentId != null) 'parent_id': parentId, + if (quotedMessageId != null) 'quoted_message_id': quotedMessageId, + if (pollId != null) 'poll_id': pollId, + if (replyCount != null) 'reply_count': replyCount, + if (showInChannel != null) 'show_in_channel': showInChannel, + if (shadowed != null) 'shadowed': shadowed, + if (command != null) 'command': command, + if (localCreatedAt != null) 'local_created_at': localCreatedAt, + if (remoteCreatedAt != null) 'remote_created_at': remoteCreatedAt, + if (localUpdatedAt != null) 'local_updated_at': localUpdatedAt, + if (remoteUpdatedAt != null) 'remote_updated_at': remoteUpdatedAt, + if (localDeletedAt != null) 'local_deleted_at': localDeletedAt, + if (remoteDeletedAt != null) 'remote_deleted_at': remoteDeletedAt, + if (messageTextUpdatedAt != null) + 'message_text_updated_at': messageTextUpdatedAt, + if (userId != null) 'user_id': userId, + if (pinned != null) 'pinned': pinned, + if (pinnedAt != null) 'pinned_at': pinnedAt, + if (pinExpires != null) 'pin_expires': pinExpires, + if (pinnedByUserId != null) 'pinned_by_user_id': pinnedByUserId, + if (channelCid != null) 'channel_cid': channelCid, + if (i18n != null) 'i18n': i18n, + if (restrictedVisibility != null) + 'restricted_visibility': restrictedVisibility, + if (extraData != null) 'extra_data': extraData, + if (rowid != null) 'rowid': rowid, + }); + } + + PinnedMessagesCompanion copyWith( + {Value? id, + Value? messageText, + Value>? attachments, + Value? state, + Value? type, + Value>? mentionedUsers, + Value?>? reactionGroups, + Value? parentId, + Value? quotedMessageId, + Value? pollId, + Value? replyCount, + Value? showInChannel, + Value? shadowed, + Value? command, + Value? localCreatedAt, + Value? remoteCreatedAt, + Value? localUpdatedAt, + Value? remoteUpdatedAt, + Value? localDeletedAt, + Value? remoteDeletedAt, + Value? messageTextUpdatedAt, + Value? userId, + Value? pinned, + Value? pinnedAt, + Value? pinExpires, + Value? pinnedByUserId, + Value? channelCid, + Value?>? i18n, + Value?>? restrictedVisibility, + Value?>? extraData, + Value? rowid}) { + return PinnedMessagesCompanion( + id: id ?? this.id, + messageText: messageText ?? this.messageText, + attachments: attachments ?? this.attachments, + state: state ?? this.state, + type: type ?? this.type, + mentionedUsers: mentionedUsers ?? this.mentionedUsers, + reactionGroups: reactionGroups ?? this.reactionGroups, + parentId: parentId ?? this.parentId, + quotedMessageId: quotedMessageId ?? this.quotedMessageId, + pollId: pollId ?? this.pollId, + replyCount: replyCount ?? this.replyCount, + showInChannel: showInChannel ?? this.showInChannel, + shadowed: shadowed ?? this.shadowed, + command: command ?? this.command, + localCreatedAt: localCreatedAt ?? this.localCreatedAt, + remoteCreatedAt: remoteCreatedAt ?? this.remoteCreatedAt, + localUpdatedAt: localUpdatedAt ?? this.localUpdatedAt, + remoteUpdatedAt: remoteUpdatedAt ?? this.remoteUpdatedAt, + localDeletedAt: localDeletedAt ?? this.localDeletedAt, + remoteDeletedAt: remoteDeletedAt ?? this.remoteDeletedAt, + messageTextUpdatedAt: messageTextUpdatedAt ?? this.messageTextUpdatedAt, + userId: userId ?? this.userId, + pinned: pinned ?? this.pinned, + pinnedAt: pinnedAt ?? this.pinnedAt, + pinExpires: pinExpires ?? this.pinExpires, + pinnedByUserId: pinnedByUserId ?? this.pinnedByUserId, + channelCid: channelCid ?? this.channelCid, + i18n: i18n ?? this.i18n, + restrictedVisibility: restrictedVisibility ?? this.restrictedVisibility, + extraData: extraData ?? this.extraData, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (messageText.present) { + map['message_text'] = Variable(messageText.value); + } + if (attachments.present) { + map['attachments'] = Variable( + $PinnedMessagesTable.$converterattachments.toSql(attachments.value)); + } + if (state.present) { + map['state'] = Variable(state.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (mentionedUsers.present) { + map['mentioned_users'] = Variable($PinnedMessagesTable + .$convertermentionedUsers + .toSql(mentionedUsers.value)); + } + if (reactionGroups.present) { + map['reaction_groups'] = Variable($PinnedMessagesTable + .$converterreactionGroupsn + .toSql(reactionGroups.value)); + } + if (parentId.present) { + map['parent_id'] = Variable(parentId.value); + } + if (quotedMessageId.present) { + map['quoted_message_id'] = Variable(quotedMessageId.value); + } + if (pollId.present) { + map['poll_id'] = Variable(pollId.value); + } + if (replyCount.present) { + map['reply_count'] = Variable(replyCount.value); + } + if (showInChannel.present) { + map['show_in_channel'] = Variable(showInChannel.value); + } + if (shadowed.present) { + map['shadowed'] = Variable(shadowed.value); + } + if (command.present) { + map['command'] = Variable(command.value); + } + if (localCreatedAt.present) { + map['local_created_at'] = Variable(localCreatedAt.value); + } + if (remoteCreatedAt.present) { + map['remote_created_at'] = Variable(remoteCreatedAt.value); + } + if (localUpdatedAt.present) { + map['local_updated_at'] = Variable(localUpdatedAt.value); + } + if (remoteUpdatedAt.present) { + map['remote_updated_at'] = Variable(remoteUpdatedAt.value); + } + if (localDeletedAt.present) { + map['local_deleted_at'] = Variable(localDeletedAt.value); + } + if (remoteDeletedAt.present) { + map['remote_deleted_at'] = Variable(remoteDeletedAt.value); + } + if (messageTextUpdatedAt.present) { + map['message_text_updated_at'] = + Variable(messageTextUpdatedAt.value); + } + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (pinned.present) { + map['pinned'] = Variable(pinned.value); + } + if (pinnedAt.present) { + map['pinned_at'] = Variable(pinnedAt.value); + } + if (pinExpires.present) { + map['pin_expires'] = Variable(pinExpires.value); + } + if (pinnedByUserId.present) { + map['pinned_by_user_id'] = Variable(pinnedByUserId.value); + } + if (channelCid.present) { + map['channel_cid'] = Variable(channelCid.value); + } + if (i18n.present) { + map['i18n'] = Variable( + $PinnedMessagesTable.$converteri18n.toSql(i18n.value)); + } + if (restrictedVisibility.present) { + map['restricted_visibility'] = Variable($PinnedMessagesTable + .$converterrestrictedVisibilityn + .toSql(restrictedVisibility.value)); + } + if (extraData.present) { + map['extra_data'] = Variable( + $PinnedMessagesTable.$converterextraDatan.toSql(extraData.value)); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PinnedMessagesCompanion(') + ..write('id: $id, ') + ..write('messageText: $messageText, ') + ..write('attachments: $attachments, ') + ..write('state: $state, ') + ..write('type: $type, ') + ..write('mentionedUsers: $mentionedUsers, ') + ..write('reactionGroups: $reactionGroups, ') + ..write('parentId: $parentId, ') + ..write('quotedMessageId: $quotedMessageId, ') + ..write('pollId: $pollId, ') + ..write('replyCount: $replyCount, ') + ..write('showInChannel: $showInChannel, ') + ..write('shadowed: $shadowed, ') + ..write('command: $command, ') + ..write('localCreatedAt: $localCreatedAt, ') + ..write('remoteCreatedAt: $remoteCreatedAt, ') + ..write('localUpdatedAt: $localUpdatedAt, ') + ..write('remoteUpdatedAt: $remoteUpdatedAt, ') + ..write('localDeletedAt: $localDeletedAt, ') + ..write('remoteDeletedAt: $remoteDeletedAt, ') + ..write('messageTextUpdatedAt: $messageTextUpdatedAt, ') + ..write('userId: $userId, ') + ..write('pinned: $pinned, ') + ..write('pinnedAt: $pinnedAt, ') + ..write('pinExpires: $pinExpires, ') + ..write('pinnedByUserId: $pinnedByUserId, ') + ..write('channelCid: $channelCid, ') + ..write('i18n: $i18n, ') + ..write('restrictedVisibility: $restrictedVisibility, ') + ..write('extraData: $extraData, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $PollsTable extends Polls with TableInfo<$PollsTable, PollEntity> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $PollsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _nameMeta = const VerificationMeta('name'); + @override + late final GeneratedColumn name = GeneratedColumn( + 'name', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _descriptionMeta = + const VerificationMeta('description'); + @override + late final GeneratedColumn description = GeneratedColumn( + 'description', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + @override + late final GeneratedColumnWithTypeConverter, String> options = + GeneratedColumn('options', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true) + .withConverter>($PollsTable.$converteroptions); + @override + late final GeneratedColumnWithTypeConverter + votingVisibility = GeneratedColumn( + 'voting_visibility', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultValue: const Constant('public')) + .withConverter( + $PollsTable.$convertervotingVisibility); + static const VerificationMeta _enforceUniqueVoteMeta = + const VerificationMeta('enforceUniqueVote'); + @override + late final GeneratedColumn enforceUniqueVote = GeneratedColumn( + 'enforce_unique_vote', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("enforce_unique_vote" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _maxVotesAllowedMeta = + const VerificationMeta('maxVotesAllowed'); + @override + late final GeneratedColumn maxVotesAllowed = GeneratedColumn( + 'max_votes_allowed', aliasedName, true, + type: DriftSqlType.int, requiredDuringInsert: false); + static const VerificationMeta _allowUserSuggestedOptionsMeta = + const VerificationMeta('allowUserSuggestedOptions'); + @override + late final GeneratedColumn allowUserSuggestedOptions = + GeneratedColumn('allow_user_suggested_options', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("allow_user_suggested_options" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _allowAnswersMeta = + const VerificationMeta('allowAnswers'); + @override + late final GeneratedColumn allowAnswers = GeneratedColumn( + 'allow_answers', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("allow_answers" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _isClosedMeta = + const VerificationMeta('isClosed'); + @override + late final GeneratedColumn isClosed = GeneratedColumn( + 'is_closed', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("is_closed" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _answersCountMeta = + const VerificationMeta('answersCount'); + @override + late final GeneratedColumn answersCount = GeneratedColumn( + 'answers_count', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const Constant(0)); + @override + late final GeneratedColumnWithTypeConverter, String> + voteCountsByOption = GeneratedColumn( + 'vote_counts_by_option', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true) + .withConverter>( + $PollsTable.$convertervoteCountsByOption); + static const VerificationMeta _voteCountMeta = + const VerificationMeta('voteCount'); + @override + late final GeneratedColumn voteCount = GeneratedColumn( + 'vote_count', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const Constant(0)); + static const VerificationMeta _createdByIdMeta = + const VerificationMeta('createdById'); + @override + late final GeneratedColumn createdById = GeneratedColumn( + 'created_by_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _createdAtMeta = + const VerificationMeta('createdAt'); + @override + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + static const VerificationMeta _updatedAtMeta = + const VerificationMeta('updatedAt'); + @override + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + @override + late final GeneratedColumnWithTypeConverter?, String> + extraData = GeneratedColumn('extra_data', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false) + .withConverter?>( + $PollsTable.$converterextraDatan); + @override + List get $columns => [ + id, + name, + description, + options, + votingVisibility, + enforceUniqueVote, + maxVotesAllowed, + allowUserSuggestedOptions, + allowAnswers, + isClosed, + answersCount, + voteCountsByOption, + voteCount, + createdById, + createdAt, + updatedAt, + extraData + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'polls'; + @override + VerificationContext validateIntegrity(Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } else if (isInserting) { + context.missing(_idMeta); + } + if (data.containsKey('name')) { + context.handle( + _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); + } else if (isInserting) { + context.missing(_nameMeta); + } + if (data.containsKey('description')) { + context.handle( + _descriptionMeta, + description.isAcceptableOrUnknown( + data['description']!, _descriptionMeta)); + } + if (data.containsKey('enforce_unique_vote')) { + context.handle( + _enforceUniqueVoteMeta, + enforceUniqueVote.isAcceptableOrUnknown( + data['enforce_unique_vote']!, _enforceUniqueVoteMeta)); + } + if (data.containsKey('max_votes_allowed')) { + context.handle( + _maxVotesAllowedMeta, + maxVotesAllowed.isAcceptableOrUnknown( + data['max_votes_allowed']!, _maxVotesAllowedMeta)); + } + if (data.containsKey('allow_user_suggested_options')) { + context.handle( + _allowUserSuggestedOptionsMeta, + allowUserSuggestedOptions.isAcceptableOrUnknown( + data['allow_user_suggested_options']!, + _allowUserSuggestedOptionsMeta)); + } + if (data.containsKey('allow_answers')) { + context.handle( + _allowAnswersMeta, + allowAnswers.isAcceptableOrUnknown( + data['allow_answers']!, _allowAnswersMeta)); + } + if (data.containsKey('is_closed')) { + context.handle(_isClosedMeta, + isClosed.isAcceptableOrUnknown(data['is_closed']!, _isClosedMeta)); + } + if (data.containsKey('answers_count')) { + context.handle( + _answersCountMeta, + answersCount.isAcceptableOrUnknown( + data['answers_count']!, _answersCountMeta)); + } + if (data.containsKey('vote_count')) { + context.handle(_voteCountMeta, + voteCount.isAcceptableOrUnknown(data['vote_count']!, _voteCountMeta)); + } + if (data.containsKey('created_by_id')) { + context.handle( + _createdByIdMeta, + createdById.isAcceptableOrUnknown( + data['created_by_id']!, _createdByIdMeta)); + } + if (data.containsKey('created_at')) { + context.handle(_createdAtMeta, + createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); + } + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + PollEntity map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PollEntity( + id: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}id'])!, + name: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}name'])!, + description: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}description']), + options: $PollsTable.$converteroptions.fromSql(attachedDatabase + .typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}options'])!), + votingVisibility: $PollsTable.$convertervotingVisibility.fromSql( + attachedDatabase.typeMapping.read(DriftSqlType.string, + data['${effectivePrefix}voting_visibility'])!), + enforceUniqueVote: attachedDatabase.typeMapping.read( + DriftSqlType.bool, data['${effectivePrefix}enforce_unique_vote'])!, + maxVotesAllowed: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}max_votes_allowed']), + allowUserSuggestedOptions: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}allow_user_suggested_options'])!, + allowAnswers: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}allow_answers'])!, + isClosed: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}is_closed'])!, + answersCount: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}answers_count'])!, + voteCountsByOption: $PollsTable.$convertervoteCountsByOption.fromSql( + attachedDatabase.typeMapping.read(DriftSqlType.string, + data['${effectivePrefix}vote_counts_by_option'])!), + voteCount: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}vote_count'])!, + createdById: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}created_by_id']), + createdAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + updatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, + extraData: $PollsTable.$converterextraDatan.fromSql(attachedDatabase + .typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), + ); + } + + @override + $PollsTable createAlias(String alias) { + return $PollsTable(attachedDatabase, alias); + } + + static TypeConverter, String> $converteroptions = + ListConverter(); + static TypeConverter $convertervotingVisibility = + const VotingVisibilityConverter(); + static TypeConverter, String> $convertervoteCountsByOption = + MapConverter(); + static TypeConverter, String> $converterextraData = + MapConverter(); + static TypeConverter?, String?> $converterextraDatan = + NullAwareTypeConverter.wrap($converterextraData); +} + +class PollEntity extends DataClass implements Insertable { + /// The unique identifier of the poll. + final String id; + + /// The name of the poll. + final String name; + + /// The description of the poll. + final String? description; + + /// The list of options available for the poll. + final List options; + + /// Represents the visibility of the voting process. + /// + /// Defaults to 'public'. + final VotingVisibility votingVisibility; + + /// If true, only unique votes are allowed. + /// + /// Defaults to false. + final bool enforceUniqueVote; + + /// The maximum number of votes allowed per user. + final int? maxVotesAllowed; + + /// If true, users can suggest their own options. + /// + /// Defaults to false. + final bool allowUserSuggestedOptions; + + /// If true, users can provide their own answers/comments. + /// + /// Defaults to false. + final bool allowAnswers; + + /// Indicates if the poll is closed. + final bool isClosed; + + /// The total number of answers received by the poll. + final int answersCount; + + /// Map of vote counts by option. + final Map voteCountsByOption; + + /// The total number of votes received by the poll. + final int voteCount; + + /// The id of the user who created the poll. + final String? createdById; + + /// The date when the poll was created. + final DateTime createdAt; + + /// The date when the poll was last updated. + final DateTime updatedAt; + + /// Map of custom poll extraData + final Map? extraData; + const PollEntity( + {required this.id, + required this.name, + this.description, + required this.options, + required this.votingVisibility, + required this.enforceUniqueVote, + this.maxVotesAllowed, + required this.allowUserSuggestedOptions, + required this.allowAnswers, + required this.isClosed, + required this.answersCount, + required this.voteCountsByOption, + required this.voteCount, + this.createdById, + required this.createdAt, + required this.updatedAt, + this.extraData}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + if (!nullToAbsent || description != null) { + map['description'] = Variable(description); + } + { + map['options'] = + Variable($PollsTable.$converteroptions.toSql(options)); + } + { + map['voting_visibility'] = Variable( + $PollsTable.$convertervotingVisibility.toSql(votingVisibility)); + } + map['enforce_unique_vote'] = Variable(enforceUniqueVote); + if (!nullToAbsent || maxVotesAllowed != null) { + map['max_votes_allowed'] = Variable(maxVotesAllowed); + } + map['allow_user_suggested_options'] = + Variable(allowUserSuggestedOptions); + map['allow_answers'] = Variable(allowAnswers); + map['is_closed'] = Variable(isClosed); + map['answers_count'] = Variable(answersCount); + { + map['vote_counts_by_option'] = Variable( + $PollsTable.$convertervoteCountsByOption.toSql(voteCountsByOption)); + } + map['vote_count'] = Variable(voteCount); + if (!nullToAbsent || createdById != null) { + map['created_by_id'] = Variable(createdById); + } + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || extraData != null) { + map['extra_data'] = + Variable($PollsTable.$converterextraDatan.toSql(extraData)); + } + return map; + } + + factory PollEntity.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PollEntity( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + description: serializer.fromJson(json['description']), + options: serializer.fromJson>(json['options']), + votingVisibility: + serializer.fromJson(json['votingVisibility']), + enforceUniqueVote: serializer.fromJson(json['enforceUniqueVote']), + maxVotesAllowed: serializer.fromJson(json['maxVotesAllowed']), + allowUserSuggestedOptions: + serializer.fromJson(json['allowUserSuggestedOptions']), + allowAnswers: serializer.fromJson(json['allowAnswers']), + isClosed: serializer.fromJson(json['isClosed']), + answersCount: serializer.fromJson(json['answersCount']), + voteCountsByOption: + serializer.fromJson>(json['voteCountsByOption']), + voteCount: serializer.fromJson(json['voteCount']), + createdById: serializer.fromJson(json['createdById']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + extraData: serializer.fromJson?>(json['extraData']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'description': serializer.toJson(description), + 'options': serializer.toJson>(options), + 'votingVisibility': serializer.toJson(votingVisibility), + 'enforceUniqueVote': serializer.toJson(enforceUniqueVote), + 'maxVotesAllowed': serializer.toJson(maxVotesAllowed), + 'allowUserSuggestedOptions': + serializer.toJson(allowUserSuggestedOptions), + 'allowAnswers': serializer.toJson(allowAnswers), + 'isClosed': serializer.toJson(isClosed), + 'answersCount': serializer.toJson(answersCount), + 'voteCountsByOption': + serializer.toJson>(voteCountsByOption), + 'voteCount': serializer.toJson(voteCount), + 'createdById': serializer.toJson(createdById), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'extraData': serializer.toJson?>(extraData), + }; + } + + PollEntity copyWith( + {String? id, + String? name, + Value description = const Value.absent(), + List? options, + VotingVisibility? votingVisibility, + bool? enforceUniqueVote, + Value maxVotesAllowed = const Value.absent(), + bool? allowUserSuggestedOptions, + bool? allowAnswers, + bool? isClosed, + int? answersCount, + Map? voteCountsByOption, + int? voteCount, + Value createdById = const Value.absent(), + DateTime? createdAt, + DateTime? updatedAt, + Value?> extraData = const Value.absent()}) => + PollEntity( + id: id ?? this.id, + name: name ?? this.name, + description: description.present ? description.value : this.description, + options: options ?? this.options, + votingVisibility: votingVisibility ?? this.votingVisibility, + enforceUniqueVote: enforceUniqueVote ?? this.enforceUniqueVote, + maxVotesAllowed: maxVotesAllowed.present + ? maxVotesAllowed.value + : this.maxVotesAllowed, + allowUserSuggestedOptions: + allowUserSuggestedOptions ?? this.allowUserSuggestedOptions, + allowAnswers: allowAnswers ?? this.allowAnswers, + isClosed: isClosed ?? this.isClosed, + answersCount: answersCount ?? this.answersCount, + voteCountsByOption: voteCountsByOption ?? this.voteCountsByOption, + voteCount: voteCount ?? this.voteCount, + createdById: createdById.present ? createdById.value : this.createdById, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + extraData: extraData.present ? extraData.value : this.extraData, + ); + PollEntity copyWithCompanion(PollsCompanion data) { + return PollEntity( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + description: + data.description.present ? data.description.value : this.description, + options: data.options.present ? data.options.value : this.options, + votingVisibility: data.votingVisibility.present + ? data.votingVisibility.value + : this.votingVisibility, + enforceUniqueVote: data.enforceUniqueVote.present + ? data.enforceUniqueVote.value + : this.enforceUniqueVote, + maxVotesAllowed: data.maxVotesAllowed.present + ? data.maxVotesAllowed.value + : this.maxVotesAllowed, + allowUserSuggestedOptions: data.allowUserSuggestedOptions.present + ? data.allowUserSuggestedOptions.value + : this.allowUserSuggestedOptions, + allowAnswers: data.allowAnswers.present + ? data.allowAnswers.value + : this.allowAnswers, + isClosed: data.isClosed.present ? data.isClosed.value : this.isClosed, + answersCount: data.answersCount.present + ? data.answersCount.value + : this.answersCount, + voteCountsByOption: data.voteCountsByOption.present + ? data.voteCountsByOption.value + : this.voteCountsByOption, + voteCount: data.voteCount.present ? data.voteCount.value : this.voteCount, + createdById: + data.createdById.present ? data.createdById.value : this.createdById, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + extraData: data.extraData.present ? data.extraData.value : this.extraData, + ); + } + + @override + String toString() { + return (StringBuffer('PollEntity(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('description: $description, ') + ..write('options: $options, ') + ..write('votingVisibility: $votingVisibility, ') + ..write('enforceUniqueVote: $enforceUniqueVote, ') + ..write('maxVotesAllowed: $maxVotesAllowed, ') + ..write('allowUserSuggestedOptions: $allowUserSuggestedOptions, ') + ..write('allowAnswers: $allowAnswers, ') + ..write('isClosed: $isClosed, ') + ..write('answersCount: $answersCount, ') + ..write('voteCountsByOption: $voteCountsByOption, ') + ..write('voteCount: $voteCount, ') + ..write('createdById: $createdById, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('extraData: $extraData') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + description, + options, + votingVisibility, + enforceUniqueVote, + maxVotesAllowed, + allowUserSuggestedOptions, + allowAnswers, + isClosed, + answersCount, + voteCountsByOption, + voteCount, + createdById, + createdAt, + updatedAt, + extraData); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PollEntity && + other.id == this.id && + other.name == this.name && + other.description == this.description && + other.options == this.options && + other.votingVisibility == this.votingVisibility && + other.enforceUniqueVote == this.enforceUniqueVote && + other.maxVotesAllowed == this.maxVotesAllowed && + other.allowUserSuggestedOptions == this.allowUserSuggestedOptions && + other.allowAnswers == this.allowAnswers && + other.isClosed == this.isClosed && + other.answersCount == this.answersCount && + other.voteCountsByOption == this.voteCountsByOption && + other.voteCount == this.voteCount && + other.createdById == this.createdById && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.extraData == this.extraData); +} + +class PollsCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value description; + final Value> options; + final Value votingVisibility; + final Value enforceUniqueVote; + final Value maxVotesAllowed; + final Value allowUserSuggestedOptions; + final Value allowAnswers; + final Value isClosed; + final Value answersCount; + final Value> voteCountsByOption; + final Value voteCount; + final Value createdById; + final Value createdAt; + final Value updatedAt; + final Value?> extraData; + final Value rowid; + const PollsCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.description = const Value.absent(), + this.options = const Value.absent(), + this.votingVisibility = const Value.absent(), + this.enforceUniqueVote = const Value.absent(), + this.maxVotesAllowed = const Value.absent(), + this.allowUserSuggestedOptions = const Value.absent(), + this.allowAnswers = const Value.absent(), + this.isClosed = const Value.absent(), + this.answersCount = const Value.absent(), + this.voteCountsByOption = const Value.absent(), + this.voteCount = const Value.absent(), + this.createdById = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.extraData = const Value.absent(), + this.rowid = const Value.absent(), + }); + PollsCompanion.insert({ + required String id, + required String name, + this.description = const Value.absent(), + required List options, + this.votingVisibility = const Value.absent(), + this.enforceUniqueVote = const Value.absent(), + this.maxVotesAllowed = const Value.absent(), + this.allowUserSuggestedOptions = const Value.absent(), + this.allowAnswers = const Value.absent(), + this.isClosed = const Value.absent(), + this.answersCount = const Value.absent(), + required Map voteCountsByOption, + this.voteCount = const Value.absent(), + this.createdById = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.extraData = const Value.absent(), + this.rowid = const Value.absent(), + }) : id = Value(id), + name = Value(name), + options = Value(options), + voteCountsByOption = Value(voteCountsByOption); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? description, + Expression? options, + Expression? votingVisibility, + Expression? enforceUniqueVote, + Expression? maxVotesAllowed, + Expression? allowUserSuggestedOptions, + Expression? allowAnswers, + Expression? isClosed, + Expression? answersCount, + Expression? voteCountsByOption, + Expression? voteCount, + Expression? createdById, + Expression? createdAt, + Expression? updatedAt, + Expression? extraData, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (description != null) 'description': description, + if (options != null) 'options': options, + if (votingVisibility != null) 'voting_visibility': votingVisibility, + if (enforceUniqueVote != null) 'enforce_unique_vote': enforceUniqueVote, + if (maxVotesAllowed != null) 'max_votes_allowed': maxVotesAllowed, + if (allowUserSuggestedOptions != null) + 'allow_user_suggested_options': allowUserSuggestedOptions, + if (allowAnswers != null) 'allow_answers': allowAnswers, + if (isClosed != null) 'is_closed': isClosed, + if (answersCount != null) 'answers_count': answersCount, + if (voteCountsByOption != null) + 'vote_counts_by_option': voteCountsByOption, + if (voteCount != null) 'vote_count': voteCount, + if (createdById != null) 'created_by_id': createdById, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (extraData != null) 'extra_data': extraData, + if (rowid != null) 'rowid': rowid, + }); + } + + PollsCompanion copyWith( + {Value? id, + Value? name, + Value? description, + Value>? options, + Value? votingVisibility, + Value? enforceUniqueVote, + Value? maxVotesAllowed, + Value? allowUserSuggestedOptions, + Value? allowAnswers, + Value? isClosed, + Value? answersCount, + Value>? voteCountsByOption, + Value? voteCount, + Value? createdById, + Value? createdAt, + Value? updatedAt, + Value?>? extraData, + Value? rowid}) { + return PollsCompanion( + id: id ?? this.id, + name: name ?? this.name, + description: description ?? this.description, + options: options ?? this.options, + votingVisibility: votingVisibility ?? this.votingVisibility, + enforceUniqueVote: enforceUniqueVote ?? this.enforceUniqueVote, + maxVotesAllowed: maxVotesAllowed ?? this.maxVotesAllowed, + allowUserSuggestedOptions: + allowUserSuggestedOptions ?? this.allowUserSuggestedOptions, + allowAnswers: allowAnswers ?? this.allowAnswers, + isClosed: isClosed ?? this.isClosed, + answersCount: answersCount ?? this.answersCount, + voteCountsByOption: voteCountsByOption ?? this.voteCountsByOption, + voteCount: voteCount ?? this.voteCount, + createdById: createdById ?? this.createdById, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + extraData: extraData ?? this.extraData, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (description.present) { + map['description'] = Variable(description.value); + } + if (options.present) { + map['options'] = + Variable($PollsTable.$converteroptions.toSql(options.value)); + } + if (votingVisibility.present) { + map['voting_visibility'] = Variable( + $PollsTable.$convertervotingVisibility.toSql(votingVisibility.value)); + } + if (enforceUniqueVote.present) { + map['enforce_unique_vote'] = Variable(enforceUniqueVote.value); + } + if (maxVotesAllowed.present) { + map['max_votes_allowed'] = Variable(maxVotesAllowed.value); + } + if (allowUserSuggestedOptions.present) { + map['allow_user_suggested_options'] = + Variable(allowUserSuggestedOptions.value); + } + if (allowAnswers.present) { + map['allow_answers'] = Variable(allowAnswers.value); + } + if (isClosed.present) { + map['is_closed'] = Variable(isClosed.value); + } + if (answersCount.present) { + map['answers_count'] = Variable(answersCount.value); + } + if (voteCountsByOption.present) { + map['vote_counts_by_option'] = Variable($PollsTable + .$convertervoteCountsByOption + .toSql(voteCountsByOption.value)); + } + if (voteCount.present) { + map['vote_count'] = Variable(voteCount.value); + } + if (createdById.present) { + map['created_by_id'] = Variable(createdById.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (extraData.present) { + map['extra_data'] = Variable( + $PollsTable.$converterextraDatan.toSql(extraData.value)); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PollsCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('description: $description, ') + ..write('options: $options, ') + ..write('votingVisibility: $votingVisibility, ') + ..write('enforceUniqueVote: $enforceUniqueVote, ') + ..write('maxVotesAllowed: $maxVotesAllowed, ') + ..write('allowUserSuggestedOptions: $allowUserSuggestedOptions, ') + ..write('allowAnswers: $allowAnswers, ') + ..write('isClosed: $isClosed, ') + ..write('answersCount: $answersCount, ') + ..write('voteCountsByOption: $voteCountsByOption, ') + ..write('voteCount: $voteCount, ') + ..write('createdById: $createdById, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('extraData: $extraData, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $PollVotesTable extends PollVotes + with TableInfo<$PollVotesTable, PollVoteEntity> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $PollVotesTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _pollIdMeta = const VerificationMeta('pollId'); + @override + late final GeneratedColumn pollId = GeneratedColumn( + 'poll_id', aliasedName, true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES polls (id) ON DELETE CASCADE')); + static const VerificationMeta _optionIdMeta = + const VerificationMeta('optionId'); + @override + late final GeneratedColumn optionId = GeneratedColumn( + 'option_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _answerTextMeta = + const VerificationMeta('answerText'); + @override + late final GeneratedColumn answerText = GeneratedColumn( + 'answer_text', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _createdAtMeta = + const VerificationMeta('createdAt'); + @override + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + static const VerificationMeta _updatedAtMeta = + const VerificationMeta('updatedAt'); + @override + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + @override + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + @override + List get $columns => + [id, pollId, optionId, answerText, createdAt, updatedAt, userId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'poll_votes'; + @override + VerificationContext validateIntegrity(Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } + if (data.containsKey('poll_id')) { + context.handle(_pollIdMeta, + pollId.isAcceptableOrUnknown(data['poll_id']!, _pollIdMeta)); + } + if (data.containsKey('option_id')) { + context.handle(_optionIdMeta, + optionId.isAcceptableOrUnknown(data['option_id']!, _optionIdMeta)); + } + if (data.containsKey('answer_text')) { + context.handle( + _answerTextMeta, + answerText.isAcceptableOrUnknown( + data['answer_text']!, _answerTextMeta)); + } + if (data.containsKey('created_at')) { + context.handle(_createdAtMeta, + createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); + } + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + } + if (data.containsKey('user_id')) { + context.handle(_userIdMeta, + userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); + } + return context; + } + + @override + Set get $primaryKey => {id, pollId}; + @override + PollVoteEntity map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PollVoteEntity( + id: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}id']), + pollId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}poll_id']), + optionId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}option_id']), + answerText: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}answer_text']), + createdAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + updatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, + userId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}user_id']), + ); + } + + @override + $PollVotesTable createAlias(String alias) { + return $PollVotesTable(attachedDatabase, alias); + } +} + +class PollVoteEntity extends DataClass implements Insertable { + /// The unique identifier of the poll vote. + final String? id; + + /// The unique identifier of the poll the vote belongs to. + final String? pollId; + + /// The unique identifier of the option selected in the poll. + /// + /// Nullable if the user provided an answer. + final String? optionId; + + /// The text of the answer provided in the poll. + /// + /// Nullable if the user selected an option. + final String? answerText; + + /// The date when the poll vote was created. + final DateTime createdAt; + + /// The date when the poll vote was last updated. + final DateTime updatedAt; + + /// The unique identifier of the user who voted. + /// + /// Nullable if the poll is anonymous. + final String? userId; + const PollVoteEntity( + {this.id, + this.pollId, + this.optionId, + this.answerText, + required this.createdAt, + required this.updatedAt, + this.userId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (!nullToAbsent || id != null) { + map['id'] = Variable(id); + } + if (!nullToAbsent || pollId != null) { + map['poll_id'] = Variable(pollId); + } + if (!nullToAbsent || optionId != null) { + map['option_id'] = Variable(optionId); + } + if (!nullToAbsent || answerText != null) { + map['answer_text'] = Variable(answerText); + } + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || userId != null) { + map['user_id'] = Variable(userId); + } + return map; + } + + factory PollVoteEntity.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PollVoteEntity( + id: serializer.fromJson(json['id']), + pollId: serializer.fromJson(json['pollId']), + optionId: serializer.fromJson(json['optionId']), + answerText: serializer.fromJson(json['answerText']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + userId: serializer.fromJson(json['userId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'pollId': serializer.toJson(pollId), + 'optionId': serializer.toJson(optionId), + 'answerText': serializer.toJson(answerText), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'userId': serializer.toJson(userId), + }; + } + + PollVoteEntity copyWith( + {Value id = const Value.absent(), + Value pollId = const Value.absent(), + Value optionId = const Value.absent(), + Value answerText = const Value.absent(), + DateTime? createdAt, + DateTime? updatedAt, + Value userId = const Value.absent()}) => + PollVoteEntity( + id: id.present ? id.value : this.id, + pollId: pollId.present ? pollId.value : this.pollId, + optionId: optionId.present ? optionId.value : this.optionId, + answerText: answerText.present ? answerText.value : this.answerText, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + userId: userId.present ? userId.value : this.userId, + ); + PollVoteEntity copyWithCompanion(PollVotesCompanion data) { + return PollVoteEntity( + id: data.id.present ? data.id.value : this.id, + pollId: data.pollId.present ? data.pollId.value : this.pollId, + optionId: data.optionId.present ? data.optionId.value : this.optionId, + answerText: + data.answerText.present ? data.answerText.value : this.answerText, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + userId: data.userId.present ? data.userId.value : this.userId, + ); + } + + @override + String toString() { + return (StringBuffer('PollVoteEntity(') + ..write('id: $id, ') + ..write('pollId: $pollId, ') + ..write('optionId: $optionId, ') + ..write('answerText: $answerText, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('userId: $userId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, pollId, optionId, answerText, createdAt, updatedAt, userId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PollVoteEntity && + other.id == this.id && + other.pollId == this.pollId && + other.optionId == this.optionId && + other.answerText == this.answerText && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.userId == this.userId); +} + +class PollVotesCompanion extends UpdateCompanion { + final Value id; final Value pollId; - final Value replyCount; - final Value showInChannel; - final Value shadowed; - final Value command; - final Value localCreatedAt; - final Value remoteCreatedAt; - final Value localUpdatedAt; - final Value remoteUpdatedAt; - final Value localDeletedAt; - final Value remoteDeletedAt; - final Value messageTextUpdatedAt; + final Value optionId; + final Value answerText; + final Value createdAt; + final Value updatedAt; final Value userId; - final Value pinned; - final Value pinnedAt; - final Value pinExpires; - final Value pinnedByUserId; - final Value channelCid; - final Value?> i18n; - final Value?> restrictedVisibility; - final Value?> extraData; final Value rowid; - const PinnedMessagesCompanion({ + const PollVotesCompanion({ this.id = const Value.absent(), - this.messageText = const Value.absent(), - this.attachments = const Value.absent(), - this.state = const Value.absent(), - this.type = const Value.absent(), - this.mentionedUsers = const Value.absent(), - this.reactionGroups = const Value.absent(), - this.parentId = const Value.absent(), - this.quotedMessageId = const Value.absent(), this.pollId = const Value.absent(), - this.replyCount = const Value.absent(), - this.showInChannel = const Value.absent(), - this.shadowed = const Value.absent(), - this.command = const Value.absent(), - this.localCreatedAt = const Value.absent(), - this.remoteCreatedAt = const Value.absent(), - this.localUpdatedAt = const Value.absent(), - this.remoteUpdatedAt = const Value.absent(), - this.localDeletedAt = const Value.absent(), - this.remoteDeletedAt = const Value.absent(), - this.messageTextUpdatedAt = const Value.absent(), + this.optionId = const Value.absent(), + this.answerText = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.userId = const Value.absent(), - this.pinned = const Value.absent(), - this.pinnedAt = const Value.absent(), - this.pinExpires = const Value.absent(), - this.pinnedByUserId = const Value.absent(), - this.channelCid = const Value.absent(), - this.i18n = const Value.absent(), - this.restrictedVisibility = const Value.absent(), - this.extraData = const Value.absent(), this.rowid = const Value.absent(), }); - PinnedMessagesCompanion.insert({ - required String id, - this.messageText = const Value.absent(), - required List attachments, - required String state, - this.type = const Value.absent(), - required List mentionedUsers, - this.reactionGroups = const Value.absent(), - this.parentId = const Value.absent(), - this.quotedMessageId = const Value.absent(), + PollVotesCompanion.insert({ + this.id = const Value.absent(), this.pollId = const Value.absent(), - this.replyCount = const Value.absent(), - this.showInChannel = const Value.absent(), - this.shadowed = const Value.absent(), - this.command = const Value.absent(), - this.localCreatedAt = const Value.absent(), - this.remoteCreatedAt = const Value.absent(), - this.localUpdatedAt = const Value.absent(), - this.remoteUpdatedAt = const Value.absent(), - this.localDeletedAt = const Value.absent(), - this.remoteDeletedAt = const Value.absent(), - this.messageTextUpdatedAt = const Value.absent(), + this.optionId = const Value.absent(), + this.answerText = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.userId = const Value.absent(), - this.pinned = const Value.absent(), - this.pinnedAt = const Value.absent(), - this.pinExpires = const Value.absent(), - this.pinnedByUserId = const Value.absent(), - required String channelCid, - this.i18n = const Value.absent(), - this.restrictedVisibility = const Value.absent(), - this.extraData = const Value.absent(), this.rowid = const Value.absent(), - }) : id = Value(id), - attachments = Value(attachments), - state = Value(state), - mentionedUsers = Value(mentionedUsers), - channelCid = Value(channelCid); - static Insertable custom({ + }); + static Insertable custom({ Expression? id, - Expression? messageText, - Expression? attachments, - Expression? state, - Expression? type, - Expression? mentionedUsers, - Expression? reactionGroups, - Expression? parentId, - Expression? quotedMessageId, Expression? pollId, - Expression? replyCount, - Expression? showInChannel, - Expression? shadowed, - Expression? command, - Expression? localCreatedAt, - Expression? remoteCreatedAt, - Expression? localUpdatedAt, - Expression? remoteUpdatedAt, - Expression? localDeletedAt, - Expression? remoteDeletedAt, - Expression? messageTextUpdatedAt, + Expression? optionId, + Expression? answerText, + Expression? createdAt, + Expression? updatedAt, Expression? userId, - Expression? pinned, - Expression? pinnedAt, - Expression? pinExpires, - Expression? pinnedByUserId, - Expression? channelCid, - Expression? i18n, - Expression? restrictedVisibility, - Expression? extraData, Expression? rowid, }) { return RawValuesInsertable({ if (id != null) 'id': id, - if (messageText != null) 'message_text': messageText, - if (attachments != null) 'attachments': attachments, - if (state != null) 'state': state, - if (type != null) 'type': type, - if (mentionedUsers != null) 'mentioned_users': mentionedUsers, - if (reactionGroups != null) 'reaction_groups': reactionGroups, - if (parentId != null) 'parent_id': parentId, - if (quotedMessageId != null) 'quoted_message_id': quotedMessageId, if (pollId != null) 'poll_id': pollId, - if (replyCount != null) 'reply_count': replyCount, - if (showInChannel != null) 'show_in_channel': showInChannel, - if (shadowed != null) 'shadowed': shadowed, - if (command != null) 'command': command, - if (localCreatedAt != null) 'local_created_at': localCreatedAt, - if (remoteCreatedAt != null) 'remote_created_at': remoteCreatedAt, - if (localUpdatedAt != null) 'local_updated_at': localUpdatedAt, - if (remoteUpdatedAt != null) 'remote_updated_at': remoteUpdatedAt, - if (localDeletedAt != null) 'local_deleted_at': localDeletedAt, - if (remoteDeletedAt != null) 'remote_deleted_at': remoteDeletedAt, - if (messageTextUpdatedAt != null) - 'message_text_updated_at': messageTextUpdatedAt, + if (optionId != null) 'option_id': optionId, + if (answerText != null) 'answer_text': answerText, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, if (userId != null) 'user_id': userId, - if (pinned != null) 'pinned': pinned, - if (pinnedAt != null) 'pinned_at': pinnedAt, - if (pinExpires != null) 'pin_expires': pinExpires, - if (pinnedByUserId != null) 'pinned_by_user_id': pinnedByUserId, - if (channelCid != null) 'channel_cid': channelCid, - if (i18n != null) 'i18n': i18n, - if (restrictedVisibility != null) - 'restricted_visibility': restrictedVisibility, - if (extraData != null) 'extra_data': extraData, if (rowid != null) 'rowid': rowid, }); } - PinnedMessagesCompanion copyWith( - {Value? id, - Value? messageText, - Value>? attachments, - Value? state, - Value? type, - Value>? mentionedUsers, - Value?>? reactionGroups, - Value? parentId, - Value? quotedMessageId, - Value? pollId, - Value? replyCount, - Value? showInChannel, - Value? shadowed, - Value? command, - Value? localCreatedAt, - Value? remoteCreatedAt, - Value? localUpdatedAt, - Value? remoteUpdatedAt, - Value? localDeletedAt, - Value? remoteDeletedAt, - Value? messageTextUpdatedAt, - Value? userId, - Value? pinned, - Value? pinnedAt, - Value? pinExpires, - Value? pinnedByUserId, - Value? channelCid, - Value?>? i18n, - Value?>? restrictedVisibility, - Value?>? extraData, + PollVotesCompanion copyWith( + {Value? id, + Value? pollId, + Value? optionId, + Value? answerText, + Value? createdAt, + Value? updatedAt, + Value? userId, Value? rowid}) { - return PinnedMessagesCompanion( + return PollVotesCompanion( id: id ?? this.id, - messageText: messageText ?? this.messageText, - attachments: attachments ?? this.attachments, - state: state ?? this.state, - type: type ?? this.type, - mentionedUsers: mentionedUsers ?? this.mentionedUsers, - reactionGroups: reactionGroups ?? this.reactionGroups, - parentId: parentId ?? this.parentId, - quotedMessageId: quotedMessageId ?? this.quotedMessageId, pollId: pollId ?? this.pollId, - replyCount: replyCount ?? this.replyCount, - showInChannel: showInChannel ?? this.showInChannel, - shadowed: shadowed ?? this.shadowed, - command: command ?? this.command, - localCreatedAt: localCreatedAt ?? this.localCreatedAt, - remoteCreatedAt: remoteCreatedAt ?? this.remoteCreatedAt, - localUpdatedAt: localUpdatedAt ?? this.localUpdatedAt, - remoteUpdatedAt: remoteUpdatedAt ?? this.remoteUpdatedAt, - localDeletedAt: localDeletedAt ?? this.localDeletedAt, - remoteDeletedAt: remoteDeletedAt ?? this.remoteDeletedAt, - messageTextUpdatedAt: messageTextUpdatedAt ?? this.messageTextUpdatedAt, + optionId: optionId ?? this.optionId, + answerText: answerText ?? this.answerText, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, userId: userId ?? this.userId, - pinned: pinned ?? this.pinned, - pinnedAt: pinnedAt ?? this.pinnedAt, - pinExpires: pinExpires ?? this.pinExpires, - pinnedByUserId: pinnedByUserId ?? this.pinnedByUserId, - channelCid: channelCid ?? this.channelCid, - i18n: i18n ?? this.i18n, - restrictedVisibility: restrictedVisibility ?? this.restrictedVisibility, - extraData: extraData ?? this.extraData, rowid: rowid ?? this.rowid, ); } @@ -4030,103 +5856,24 @@ class PinnedMessagesCompanion extends UpdateCompanion { if (id.present) { map['id'] = Variable(id.value); } - if (messageText.present) { - map['message_text'] = Variable(messageText.value); - } - if (attachments.present) { - map['attachments'] = Variable( - $PinnedMessagesTable.$converterattachments.toSql(attachments.value)); - } - if (state.present) { - map['state'] = Variable(state.value); - } - if (type.present) { - map['type'] = Variable(type.value); - } - if (mentionedUsers.present) { - map['mentioned_users'] = Variable($PinnedMessagesTable - .$convertermentionedUsers - .toSql(mentionedUsers.value)); - } - if (reactionGroups.present) { - map['reaction_groups'] = Variable($PinnedMessagesTable - .$converterreactionGroupsn - .toSql(reactionGroups.value)); - } - if (parentId.present) { - map['parent_id'] = Variable(parentId.value); - } - if (quotedMessageId.present) { - map['quoted_message_id'] = Variable(quotedMessageId.value); - } if (pollId.present) { map['poll_id'] = Variable(pollId.value); } - if (replyCount.present) { - map['reply_count'] = Variable(replyCount.value); - } - if (showInChannel.present) { - map['show_in_channel'] = Variable(showInChannel.value); - } - if (shadowed.present) { - map['shadowed'] = Variable(shadowed.value); - } - if (command.present) { - map['command'] = Variable(command.value); - } - if (localCreatedAt.present) { - map['local_created_at'] = Variable(localCreatedAt.value); - } - if (remoteCreatedAt.present) { - map['remote_created_at'] = Variable(remoteCreatedAt.value); - } - if (localUpdatedAt.present) { - map['local_updated_at'] = Variable(localUpdatedAt.value); - } - if (remoteUpdatedAt.present) { - map['remote_updated_at'] = Variable(remoteUpdatedAt.value); + if (optionId.present) { + map['option_id'] = Variable(optionId.value); } - if (localDeletedAt.present) { - map['local_deleted_at'] = Variable(localDeletedAt.value); + if (answerText.present) { + map['answer_text'] = Variable(answerText.value); } - if (remoteDeletedAt.present) { - map['remote_deleted_at'] = Variable(remoteDeletedAt.value); + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); } - if (messageTextUpdatedAt.present) { - map['message_text_updated_at'] = - Variable(messageTextUpdatedAt.value); + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); } if (userId.present) { map['user_id'] = Variable(userId.value); } - if (pinned.present) { - map['pinned'] = Variable(pinned.value); - } - if (pinnedAt.present) { - map['pinned_at'] = Variable(pinnedAt.value); - } - if (pinExpires.present) { - map['pin_expires'] = Variable(pinExpires.value); - } - if (pinnedByUserId.present) { - map['pinned_by_user_id'] = Variable(pinnedByUserId.value); - } - if (channelCid.present) { - map['channel_cid'] = Variable(channelCid.value); - } - if (i18n.present) { - map['i18n'] = Variable( - $PinnedMessagesTable.$converteri18n.toSql(i18n.value)); - } - if (restrictedVisibility.present) { - map['restricted_visibility'] = Variable($PinnedMessagesTable - .$converterrestrictedVisibilityn - .toSql(restrictedVisibility.value)); - } - if (extraData.present) { - map['extra_data'] = Variable( - $PinnedMessagesTable.$converterextraDatan.toSql(extraData.value)); - } if (rowid.present) { map['rowid'] = Variable(rowid.value); } @@ -4135,153 +5882,45 @@ class PinnedMessagesCompanion extends UpdateCompanion { @override String toString() { - return (StringBuffer('PinnedMessagesCompanion(') + return (StringBuffer('PollVotesCompanion(') ..write('id: $id, ') - ..write('messageText: $messageText, ') - ..write('attachments: $attachments, ') - ..write('state: $state, ') - ..write('type: $type, ') - ..write('mentionedUsers: $mentionedUsers, ') - ..write('reactionGroups: $reactionGroups, ') - ..write('parentId: $parentId, ') - ..write('quotedMessageId: $quotedMessageId, ') ..write('pollId: $pollId, ') - ..write('replyCount: $replyCount, ') - ..write('showInChannel: $showInChannel, ') - ..write('shadowed: $shadowed, ') - ..write('command: $command, ') - ..write('localCreatedAt: $localCreatedAt, ') - ..write('remoteCreatedAt: $remoteCreatedAt, ') - ..write('localUpdatedAt: $localUpdatedAt, ') - ..write('remoteUpdatedAt: $remoteUpdatedAt, ') - ..write('localDeletedAt: $localDeletedAt, ') - ..write('remoteDeletedAt: $remoteDeletedAt, ') - ..write('messageTextUpdatedAt: $messageTextUpdatedAt, ') + ..write('optionId: $optionId, ') + ..write('answerText: $answerText, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') ..write('userId: $userId, ') - ..write('pinned: $pinned, ') - ..write('pinnedAt: $pinnedAt, ') - ..write('pinExpires: $pinExpires, ') - ..write('pinnedByUserId: $pinnedByUserId, ') - ..write('channelCid: $channelCid, ') - ..write('i18n: $i18n, ') - ..write('restrictedVisibility: $restrictedVisibility, ') - ..write('extraData: $extraData, ') ..write('rowid: $rowid') ..write(')')) .toString(); } } -class $PollsTable extends Polls with TableInfo<$PollsTable, PollEntity> { +class $PinnedMessageReactionsTable extends PinnedMessageReactions + with TableInfo<$PinnedMessageReactionsTable, PinnedMessageReactionEntity> { @override final GeneratedDatabase attachedDatabase; - final String? _alias; - $PollsTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _nameMeta = const VerificationMeta('name'); - @override - late final GeneratedColumn name = GeneratedColumn( - 'name', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _descriptionMeta = - const VerificationMeta('description'); - @override - late final GeneratedColumn description = GeneratedColumn( - 'description', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - @override - late final GeneratedColumnWithTypeConverter, String> options = - GeneratedColumn('options', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true) - .withConverter>($PollsTable.$converteroptions); - @override - late final GeneratedColumnWithTypeConverter - votingVisibility = GeneratedColumn( - 'voting_visibility', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: false, - defaultValue: const Constant('public')) - .withConverter( - $PollsTable.$convertervotingVisibility); - static const VerificationMeta _enforceUniqueVoteMeta = - const VerificationMeta('enforceUniqueVote'); - @override - late final GeneratedColumn enforceUniqueVote = GeneratedColumn( - 'enforce_unique_vote', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'CHECK ("enforce_unique_vote" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _maxVotesAllowedMeta = - const VerificationMeta('maxVotesAllowed'); - @override - late final GeneratedColumn maxVotesAllowed = GeneratedColumn( - 'max_votes_allowed', aliasedName, true, - type: DriftSqlType.int, requiredDuringInsert: false); - static const VerificationMeta _allowUserSuggestedOptionsMeta = - const VerificationMeta('allowUserSuggestedOptions'); - @override - late final GeneratedColumn allowUserSuggestedOptions = - GeneratedColumn('allow_user_suggested_options', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'CHECK ("allow_user_suggested_options" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _allowAnswersMeta = - const VerificationMeta('allowAnswers'); - @override - late final GeneratedColumn allowAnswers = GeneratedColumn( - 'allow_answers', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'CHECK ("allow_answers" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _isClosedMeta = - const VerificationMeta('isClosed'); - @override - late final GeneratedColumn isClosed = GeneratedColumn( - 'is_closed', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('CHECK ("is_closed" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _answersCountMeta = - const VerificationMeta('answersCount'); - @override - late final GeneratedColumn answersCount = GeneratedColumn( - 'answers_count', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - defaultValue: const Constant(0)); + final String? _alias; + $PinnedMessageReactionsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override - late final GeneratedColumnWithTypeConverter, String> - voteCountsByOption = GeneratedColumn( - 'vote_counts_by_option', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true) - .withConverter>( - $PollsTable.$convertervoteCountsByOption); - static const VerificationMeta _voteCountMeta = - const VerificationMeta('voteCount'); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _messageIdMeta = + const VerificationMeta('messageId'); @override - late final GeneratedColumn voteCount = GeneratedColumn( - 'vote_count', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - defaultValue: const Constant(0)); - static const VerificationMeta _createdByIdMeta = - const VerificationMeta('createdById'); + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES pinned_messages (id) ON DELETE CASCADE')); + static const VerificationMeta _typeMeta = const VerificationMeta('type'); @override - late final GeneratedColumn createdById = GeneratedColumn( - 'created_by_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); + late final GeneratedColumn type = GeneratedColumn( + 'type', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); static const VerificationMeta _createdAtMeta = const VerificationMeta('createdAt'); @override @@ -4290,330 +5929,146 @@ class $PollsTable extends Polls with TableInfo<$PollsTable, PollEntity> { type: DriftSqlType.dateTime, requiredDuringInsert: false, defaultValue: currentDateAndTime); - static const VerificationMeta _updatedAtMeta = - const VerificationMeta('updatedAt'); + static const VerificationMeta _scoreMeta = const VerificationMeta('score'); @override - late final GeneratedColumn updatedAt = GeneratedColumn( - 'updated_at', aliasedName, false, - type: DriftSqlType.dateTime, + late final GeneratedColumn score = GeneratedColumn( + 'score', aliasedName, false, + type: DriftSqlType.int, requiredDuringInsert: false, - defaultValue: currentDateAndTime); + defaultValue: const Constant(0)); @override late final GeneratedColumnWithTypeConverter?, String> extraData = GeneratedColumn('extra_data', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false) .withConverter?>( - $PollsTable.$converterextraDatan); + $PinnedMessageReactionsTable.$converterextraDatan); @override - List get $columns => [ - id, - name, - description, - options, - votingVisibility, - enforceUniqueVote, - maxVotesAllowed, - allowUserSuggestedOptions, - allowAnswers, - isClosed, - answersCount, - voteCountsByOption, - voteCount, - createdById, - createdAt, - updatedAt, - extraData - ]; + List get $columns => + [userId, messageId, type, createdAt, score, extraData]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'polls'; + static const String $name = 'pinned_message_reactions'; @override - VerificationContext validateIntegrity(Insertable instance, + VerificationContext validateIntegrity( + Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + if (data.containsKey('user_id')) { + context.handle(_userIdMeta, + userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); } else if (isInserting) { - context.missing(_idMeta); + context.missing(_userIdMeta); } - if (data.containsKey('name')) { - context.handle( - _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); + if (data.containsKey('message_id')) { + context.handle(_messageIdMeta, + messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta)); } else if (isInserting) { - context.missing(_nameMeta); - } - if (data.containsKey('description')) { - context.handle( - _descriptionMeta, - description.isAcceptableOrUnknown( - data['description']!, _descriptionMeta)); - } - if (data.containsKey('enforce_unique_vote')) { - context.handle( - _enforceUniqueVoteMeta, - enforceUniqueVote.isAcceptableOrUnknown( - data['enforce_unique_vote']!, _enforceUniqueVoteMeta)); - } - if (data.containsKey('max_votes_allowed')) { - context.handle( - _maxVotesAllowedMeta, - maxVotesAllowed.isAcceptableOrUnknown( - data['max_votes_allowed']!, _maxVotesAllowedMeta)); - } - if (data.containsKey('allow_user_suggested_options')) { - context.handle( - _allowUserSuggestedOptionsMeta, - allowUserSuggestedOptions.isAcceptableOrUnknown( - data['allow_user_suggested_options']!, - _allowUserSuggestedOptionsMeta)); - } - if (data.containsKey('allow_answers')) { - context.handle( - _allowAnswersMeta, - allowAnswers.isAcceptableOrUnknown( - data['allow_answers']!, _allowAnswersMeta)); - } - if (data.containsKey('is_closed')) { - context.handle(_isClosedMeta, - isClosed.isAcceptableOrUnknown(data['is_closed']!, _isClosedMeta)); - } - if (data.containsKey('answers_count')) { - context.handle( - _answersCountMeta, - answersCount.isAcceptableOrUnknown( - data['answers_count']!, _answersCountMeta)); - } - if (data.containsKey('vote_count')) { - context.handle(_voteCountMeta, - voteCount.isAcceptableOrUnknown(data['vote_count']!, _voteCountMeta)); + context.missing(_messageIdMeta); } - if (data.containsKey('created_by_id')) { + if (data.containsKey('type')) { context.handle( - _createdByIdMeta, - createdById.isAcceptableOrUnknown( - data['created_by_id']!, _createdByIdMeta)); + _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); + } else if (isInserting) { + context.missing(_typeMeta); } if (data.containsKey('created_at')) { context.handle(_createdAtMeta, createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); } - if (data.containsKey('updated_at')) { - context.handle(_updatedAtMeta, - updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + if (data.containsKey('score')) { + context.handle( + _scoreMeta, score.isAcceptableOrUnknown(data['score']!, _scoreMeta)); } return context; } @override - Set get $primaryKey => {id}; + Set get $primaryKey => {messageId, type, userId}; @override - PollEntity map(Map data, {String? tablePrefix}) { + PinnedMessageReactionEntity map(Map data, + {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return PollEntity( - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - name: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}name'])!, - description: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}description']), - options: $PollsTable.$converteroptions.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}options'])!), - votingVisibility: $PollsTable.$convertervotingVisibility.fromSql( - attachedDatabase.typeMapping.read(DriftSqlType.string, - data['${effectivePrefix}voting_visibility'])!), - enforceUniqueVote: attachedDatabase.typeMapping.read( - DriftSqlType.bool, data['${effectivePrefix}enforce_unique_vote'])!, - maxVotesAllowed: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}max_votes_allowed']), - allowUserSuggestedOptions: attachedDatabase.typeMapping.read( - DriftSqlType.bool, - data['${effectivePrefix}allow_user_suggested_options'])!, - allowAnswers: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}allow_answers'])!, - isClosed: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}is_closed'])!, - answersCount: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}answers_count'])!, - voteCountsByOption: $PollsTable.$convertervoteCountsByOption.fromSql( - attachedDatabase.typeMapping.read(DriftSqlType.string, - data['${effectivePrefix}vote_counts_by_option'])!), - voteCount: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}vote_count'])!, - createdById: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}created_by_id']), - createdAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, - updatedAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, - extraData: $PollsTable.$converterextraDatan.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), - ); - } - - @override - $PollsTable createAlias(String alias) { - return $PollsTable(attachedDatabase, alias); - } - - static TypeConverter, String> $converteroptions = - ListConverter(); - static TypeConverter $convertervotingVisibility = - const VotingVisibilityConverter(); - static TypeConverter, String> $convertervoteCountsByOption = - MapConverter(); - static TypeConverter, String> $converterextraData = - MapConverter(); - static TypeConverter?, String?> $converterextraDatan = - NullAwareTypeConverter.wrap($converterextraData); -} - -class PollEntity extends DataClass implements Insertable { - /// The unique identifier of the poll. - final String id; - - /// The name of the poll. - final String name; - - /// The description of the poll. - final String? description; - - /// The list of options available for the poll. - final List options; - - /// Represents the visibility of the voting process. - /// - /// Defaults to 'public'. - final VotingVisibility votingVisibility; - - /// If true, only unique votes are allowed. - /// - /// Defaults to false. - final bool enforceUniqueVote; - - /// The maximum number of votes allowed per user. - final int? maxVotesAllowed; - - /// If true, users can suggest their own options. - /// - /// Defaults to false. - final bool allowUserSuggestedOptions; - - /// If true, users can provide their own answers/comments. - /// - /// Defaults to false. - final bool allowAnswers; + return PinnedMessageReactionEntity( + userId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, + messageId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}message_id'])!, + type: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}type'])!, + createdAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + score: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}score'])!, + extraData: $PinnedMessageReactionsTable.$converterextraDatan.fromSql( + attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), + ); + } - /// Indicates if the poll is closed. - final bool isClosed; + @override + $PinnedMessageReactionsTable createAlias(String alias) { + return $PinnedMessageReactionsTable(attachedDatabase, alias); + } - /// The total number of answers received by the poll. - final int answersCount; + static TypeConverter, String> $converterextraData = + MapConverter(); + static TypeConverter?, String?> $converterextraDatan = + NullAwareTypeConverter.wrap($converterextraData); +} - /// Map of vote counts by option. - final Map voteCountsByOption; +class PinnedMessageReactionEntity extends DataClass + implements Insertable { + /// The id of the user that sent the reaction + final String userId; - /// The total number of votes received by the poll. - final int voteCount; + /// The messageId to which the reaction belongs + final String messageId; - /// The id of the user who created the poll. - final String? createdById; + /// The type of the reaction + final String type; - /// The date when the poll was created. + /// The DateTime on which the reaction is created final DateTime createdAt; - /// The date when the poll was last updated. - final DateTime updatedAt; + /// The score of the reaction (ie. number of reactions sent) + final int score; - /// Map of custom poll extraData + /// Reaction custom extraData final Map? extraData; - const PollEntity( - {required this.id, - required this.name, - this.description, - required this.options, - required this.votingVisibility, - required this.enforceUniqueVote, - this.maxVotesAllowed, - required this.allowUserSuggestedOptions, - required this.allowAnswers, - required this.isClosed, - required this.answersCount, - required this.voteCountsByOption, - required this.voteCount, - this.createdById, + const PinnedMessageReactionEntity( + {required this.userId, + required this.messageId, + required this.type, required this.createdAt, - required this.updatedAt, + required this.score, this.extraData}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id); - map['name'] = Variable(name); - if (!nullToAbsent || description != null) { - map['description'] = Variable(description); - } - { - map['options'] = - Variable($PollsTable.$converteroptions.toSql(options)); - } - { - map['voting_visibility'] = Variable( - $PollsTable.$convertervotingVisibility.toSql(votingVisibility)); - } - map['enforce_unique_vote'] = Variable(enforceUniqueVote); - if (!nullToAbsent || maxVotesAllowed != null) { - map['max_votes_allowed'] = Variable(maxVotesAllowed); - } - map['allow_user_suggested_options'] = - Variable(allowUserSuggestedOptions); - map['allow_answers'] = Variable(allowAnswers); - map['is_closed'] = Variable(isClosed); - map['answers_count'] = Variable(answersCount); - { - map['vote_counts_by_option'] = Variable( - $PollsTable.$convertervoteCountsByOption.toSql(voteCountsByOption)); - } - map['vote_count'] = Variable(voteCount); - if (!nullToAbsent || createdById != null) { - map['created_by_id'] = Variable(createdById); - } + map['user_id'] = Variable(userId); + map['message_id'] = Variable(messageId); + map['type'] = Variable(type); map['created_at'] = Variable(createdAt); - map['updated_at'] = Variable(updatedAt); + map['score'] = Variable(score); if (!nullToAbsent || extraData != null) { - map['extra_data'] = - Variable($PollsTable.$converterextraDatan.toSql(extraData)); + map['extra_data'] = Variable( + $PinnedMessageReactionsTable.$converterextraDatan.toSql(extraData)); } return map; } - factory PollEntity.fromJson(Map json, + factory PinnedMessageReactionEntity.fromJson(Map json, {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; - return PollEntity( - id: serializer.fromJson(json['id']), - name: serializer.fromJson(json['name']), - description: serializer.fromJson(json['description']), - options: serializer.fromJson>(json['options']), - votingVisibility: - serializer.fromJson(json['votingVisibility']), - enforceUniqueVote: serializer.fromJson(json['enforceUniqueVote']), - maxVotesAllowed: serializer.fromJson(json['maxVotesAllowed']), - allowUserSuggestedOptions: - serializer.fromJson(json['allowUserSuggestedOptions']), - allowAnswers: serializer.fromJson(json['allowAnswers']), - isClosed: serializer.fromJson(json['isClosed']), - answersCount: serializer.fromJson(json['answersCount']), - voteCountsByOption: - serializer.fromJson>(json['voteCountsByOption']), - voteCount: serializer.fromJson(json['voteCount']), - createdById: serializer.fromJson(json['createdById']), + return PinnedMessageReactionEntity( + userId: serializer.fromJson(json['userId']), + messageId: serializer.fromJson(json['messageId']), + type: serializer.fromJson(json['type']), createdAt: serializer.fromJson(json['createdAt']), - updatedAt: serializer.fromJson(json['updatedAt']), + score: serializer.fromJson(json['score']), extraData: serializer.fromJson?>(json['extraData']), ); } @@ -4621,315 +6076,133 @@ class PollEntity extends DataClass implements Insertable { Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'id': serializer.toJson(id), - 'name': serializer.toJson(name), - 'description': serializer.toJson(description), - 'options': serializer.toJson>(options), - 'votingVisibility': serializer.toJson(votingVisibility), - 'enforceUniqueVote': serializer.toJson(enforceUniqueVote), - 'maxVotesAllowed': serializer.toJson(maxVotesAllowed), - 'allowUserSuggestedOptions': - serializer.toJson(allowUserSuggestedOptions), - 'allowAnswers': serializer.toJson(allowAnswers), - 'isClosed': serializer.toJson(isClosed), - 'answersCount': serializer.toJson(answersCount), - 'voteCountsByOption': - serializer.toJson>(voteCountsByOption), - 'voteCount': serializer.toJson(voteCount), - 'createdById': serializer.toJson(createdById), + 'userId': serializer.toJson(userId), + 'messageId': serializer.toJson(messageId), + 'type': serializer.toJson(type), 'createdAt': serializer.toJson(createdAt), - 'updatedAt': serializer.toJson(updatedAt), + 'score': serializer.toJson(score), 'extraData': serializer.toJson?>(extraData), }; } - PollEntity copyWith( - {String? id, - String? name, - Value description = const Value.absent(), - List? options, - VotingVisibility? votingVisibility, - bool? enforceUniqueVote, - Value maxVotesAllowed = const Value.absent(), - bool? allowUserSuggestedOptions, - bool? allowAnswers, - bool? isClosed, - int? answersCount, - Map? voteCountsByOption, - int? voteCount, - Value createdById = const Value.absent(), + PinnedMessageReactionEntity copyWith( + {String? userId, + String? messageId, + String? type, DateTime? createdAt, - DateTime? updatedAt, + int? score, Value?> extraData = const Value.absent()}) => - PollEntity( - id: id ?? this.id, - name: name ?? this.name, - description: description.present ? description.value : this.description, - options: options ?? this.options, - votingVisibility: votingVisibility ?? this.votingVisibility, - enforceUniqueVote: enforceUniqueVote ?? this.enforceUniqueVote, - maxVotesAllowed: maxVotesAllowed.present - ? maxVotesAllowed.value - : this.maxVotesAllowed, - allowUserSuggestedOptions: - allowUserSuggestedOptions ?? this.allowUserSuggestedOptions, - allowAnswers: allowAnswers ?? this.allowAnswers, - isClosed: isClosed ?? this.isClosed, - answersCount: answersCount ?? this.answersCount, - voteCountsByOption: voteCountsByOption ?? this.voteCountsByOption, - voteCount: voteCount ?? this.voteCount, - createdById: createdById.present ? createdById.value : this.createdById, + PinnedMessageReactionEntity( + userId: userId ?? this.userId, + messageId: messageId ?? this.messageId, + type: type ?? this.type, createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, + score: score ?? this.score, extraData: extraData.present ? extraData.value : this.extraData, ); - PollEntity copyWithCompanion(PollsCompanion data) { - return PollEntity( - id: data.id.present ? data.id.value : this.id, - name: data.name.present ? data.name.value : this.name, - description: - data.description.present ? data.description.value : this.description, - options: data.options.present ? data.options.value : this.options, - votingVisibility: data.votingVisibility.present - ? data.votingVisibility.value - : this.votingVisibility, - enforceUniqueVote: data.enforceUniqueVote.present - ? data.enforceUniqueVote.value - : this.enforceUniqueVote, - maxVotesAllowed: data.maxVotesAllowed.present - ? data.maxVotesAllowed.value - : this.maxVotesAllowed, - allowUserSuggestedOptions: data.allowUserSuggestedOptions.present - ? data.allowUserSuggestedOptions.value - : this.allowUserSuggestedOptions, - allowAnswers: data.allowAnswers.present - ? data.allowAnswers.value - : this.allowAnswers, - isClosed: data.isClosed.present ? data.isClosed.value : this.isClosed, - answersCount: data.answersCount.present - ? data.answersCount.value - : this.answersCount, - voteCountsByOption: data.voteCountsByOption.present - ? data.voteCountsByOption.value - : this.voteCountsByOption, - voteCount: data.voteCount.present ? data.voteCount.value : this.voteCount, - createdById: - data.createdById.present ? data.createdById.value : this.createdById, + PinnedMessageReactionEntity copyWithCompanion( + PinnedMessageReactionsCompanion data) { + return PinnedMessageReactionEntity( + userId: data.userId.present ? data.userId.value : this.userId, + messageId: data.messageId.present ? data.messageId.value : this.messageId, + type: data.type.present ? data.type.value : this.type, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, - updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, - extraData: data.extraData.present ? data.extraData.value : this.extraData, - ); - } - - @override - String toString() { - return (StringBuffer('PollEntity(') - ..write('id: $id, ') - ..write('name: $name, ') - ..write('description: $description, ') - ..write('options: $options, ') - ..write('votingVisibility: $votingVisibility, ') - ..write('enforceUniqueVote: $enforceUniqueVote, ') - ..write('maxVotesAllowed: $maxVotesAllowed, ') - ..write('allowUserSuggestedOptions: $allowUserSuggestedOptions, ') - ..write('allowAnswers: $allowAnswers, ') - ..write('isClosed: $isClosed, ') - ..write('answersCount: $answersCount, ') - ..write('voteCountsByOption: $voteCountsByOption, ') - ..write('voteCount: $voteCount, ') - ..write('createdById: $createdById, ') + score: data.score.present ? data.score.value : this.score, + extraData: data.extraData.present ? data.extraData.value : this.extraData, + ); + } + + @override + String toString() { + return (StringBuffer('PinnedMessageReactionEntity(') + ..write('userId: $userId, ') + ..write('messageId: $messageId, ') + ..write('type: $type, ') ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt, ') + ..write('score: $score, ') ..write('extraData: $extraData') ..write(')')) .toString(); } @override - int get hashCode => Object.hash( - id, - name, - description, - options, - votingVisibility, - enforceUniqueVote, - maxVotesAllowed, - allowUserSuggestedOptions, - allowAnswers, - isClosed, - answersCount, - voteCountsByOption, - voteCount, - createdById, - createdAt, - updatedAt, - extraData); + int get hashCode => + Object.hash(userId, messageId, type, createdAt, score, extraData); @override bool operator ==(Object other) => identical(this, other) || - (other is PollEntity && - other.id == this.id && - other.name == this.name && - other.description == this.description && - other.options == this.options && - other.votingVisibility == this.votingVisibility && - other.enforceUniqueVote == this.enforceUniqueVote && - other.maxVotesAllowed == this.maxVotesAllowed && - other.allowUserSuggestedOptions == this.allowUserSuggestedOptions && - other.allowAnswers == this.allowAnswers && - other.isClosed == this.isClosed && - other.answersCount == this.answersCount && - other.voteCountsByOption == this.voteCountsByOption && - other.voteCount == this.voteCount && - other.createdById == this.createdById && + (other is PinnedMessageReactionEntity && + other.userId == this.userId && + other.messageId == this.messageId && + other.type == this.type && other.createdAt == this.createdAt && - other.updatedAt == this.updatedAt && + other.score == this.score && other.extraData == this.extraData); } -class PollsCompanion extends UpdateCompanion { - final Value id; - final Value name; - final Value description; - final Value> options; - final Value votingVisibility; - final Value enforceUniqueVote; - final Value maxVotesAllowed; - final Value allowUserSuggestedOptions; - final Value allowAnswers; - final Value isClosed; - final Value answersCount; - final Value> voteCountsByOption; - final Value voteCount; - final Value createdById; +class PinnedMessageReactionsCompanion + extends UpdateCompanion { + final Value userId; + final Value messageId; + final Value type; final Value createdAt; - final Value updatedAt; + final Value score; final Value?> extraData; final Value rowid; - const PollsCompanion({ - this.id = const Value.absent(), - this.name = const Value.absent(), - this.description = const Value.absent(), - this.options = const Value.absent(), - this.votingVisibility = const Value.absent(), - this.enforceUniqueVote = const Value.absent(), - this.maxVotesAllowed = const Value.absent(), - this.allowUserSuggestedOptions = const Value.absent(), - this.allowAnswers = const Value.absent(), - this.isClosed = const Value.absent(), - this.answersCount = const Value.absent(), - this.voteCountsByOption = const Value.absent(), - this.voteCount = const Value.absent(), - this.createdById = const Value.absent(), + const PinnedMessageReactionsCompanion({ + this.userId = const Value.absent(), + this.messageId = const Value.absent(), + this.type = const Value.absent(), this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), + this.score = const Value.absent(), this.extraData = const Value.absent(), this.rowid = const Value.absent(), }); - PollsCompanion.insert({ - required String id, - required String name, - this.description = const Value.absent(), - required List options, - this.votingVisibility = const Value.absent(), - this.enforceUniqueVote = const Value.absent(), - this.maxVotesAllowed = const Value.absent(), - this.allowUserSuggestedOptions = const Value.absent(), - this.allowAnswers = const Value.absent(), - this.isClosed = const Value.absent(), - this.answersCount = const Value.absent(), - required Map voteCountsByOption, - this.voteCount = const Value.absent(), - this.createdById = const Value.absent(), + PinnedMessageReactionsCompanion.insert({ + required String userId, + required String messageId, + required String type, this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), + this.score = const Value.absent(), this.extraData = const Value.absent(), this.rowid = const Value.absent(), - }) : id = Value(id), - name = Value(name), - options = Value(options), - voteCountsByOption = Value(voteCountsByOption); - static Insertable custom({ - Expression? id, - Expression? name, - Expression? description, - Expression? options, - Expression? votingVisibility, - Expression? enforceUniqueVote, - Expression? maxVotesAllowed, - Expression? allowUserSuggestedOptions, - Expression? allowAnswers, - Expression? isClosed, - Expression? answersCount, - Expression? voteCountsByOption, - Expression? voteCount, - Expression? createdById, + }) : userId = Value(userId), + messageId = Value(messageId), + type = Value(type); + static Insertable custom({ + Expression? userId, + Expression? messageId, + Expression? type, Expression? createdAt, - Expression? updatedAt, + Expression? score, Expression? extraData, Expression? rowid, }) { return RawValuesInsertable({ - if (id != null) 'id': id, - if (name != null) 'name': name, - if (description != null) 'description': description, - if (options != null) 'options': options, - if (votingVisibility != null) 'voting_visibility': votingVisibility, - if (enforceUniqueVote != null) 'enforce_unique_vote': enforceUniqueVote, - if (maxVotesAllowed != null) 'max_votes_allowed': maxVotesAllowed, - if (allowUserSuggestedOptions != null) - 'allow_user_suggested_options': allowUserSuggestedOptions, - if (allowAnswers != null) 'allow_answers': allowAnswers, - if (isClosed != null) 'is_closed': isClosed, - if (answersCount != null) 'answers_count': answersCount, - if (voteCountsByOption != null) - 'vote_counts_by_option': voteCountsByOption, - if (voteCount != null) 'vote_count': voteCount, - if (createdById != null) 'created_by_id': createdById, + if (userId != null) 'user_id': userId, + if (messageId != null) 'message_id': messageId, + if (type != null) 'type': type, if (createdAt != null) 'created_at': createdAt, - if (updatedAt != null) 'updated_at': updatedAt, + if (score != null) 'score': score, if (extraData != null) 'extra_data': extraData, if (rowid != null) 'rowid': rowid, }); } - PollsCompanion copyWith( - {Value? id, - Value? name, - Value? description, - Value>? options, - Value? votingVisibility, - Value? enforceUniqueVote, - Value? maxVotesAllowed, - Value? allowUserSuggestedOptions, - Value? allowAnswers, - Value? isClosed, - Value? answersCount, - Value>? voteCountsByOption, - Value? voteCount, - Value? createdById, + PinnedMessageReactionsCompanion copyWith( + {Value? userId, + Value? messageId, + Value? type, Value? createdAt, - Value? updatedAt, + Value? score, Value?>? extraData, Value? rowid}) { - return PollsCompanion( - id: id ?? this.id, - name: name ?? this.name, - description: description ?? this.description, - options: options ?? this.options, - votingVisibility: votingVisibility ?? this.votingVisibility, - enforceUniqueVote: enforceUniqueVote ?? this.enforceUniqueVote, - maxVotesAllowed: maxVotesAllowed ?? this.maxVotesAllowed, - allowUserSuggestedOptions: - allowUserSuggestedOptions ?? this.allowUserSuggestedOptions, - allowAnswers: allowAnswers ?? this.allowAnswers, - isClosed: isClosed ?? this.isClosed, - answersCount: answersCount ?? this.answersCount, - voteCountsByOption: voteCountsByOption ?? this.voteCountsByOption, - voteCount: voteCount ?? this.voteCount, - createdById: createdById ?? this.createdById, + return PinnedMessageReactionsCompanion( + userId: userId ?? this.userId, + messageId: messageId ?? this.messageId, + type: type ?? this.type, createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, + score: score ?? this.score, extraData: extraData ?? this.extraData, rowid: rowid ?? this.rowid, ); @@ -4938,62 +6211,25 @@ class PollsCompanion extends UpdateCompanion { @override Map toColumns(bool nullToAbsent) { final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (name.present) { - map['name'] = Variable(name.value); - } - if (description.present) { - map['description'] = Variable(description.value); - } - if (options.present) { - map['options'] = - Variable($PollsTable.$converteroptions.toSql(options.value)); - } - if (votingVisibility.present) { - map['voting_visibility'] = Variable( - $PollsTable.$convertervotingVisibility.toSql(votingVisibility.value)); - } - if (enforceUniqueVote.present) { - map['enforce_unique_vote'] = Variable(enforceUniqueVote.value); - } - if (maxVotesAllowed.present) { - map['max_votes_allowed'] = Variable(maxVotesAllowed.value); - } - if (allowUserSuggestedOptions.present) { - map['allow_user_suggested_options'] = - Variable(allowUserSuggestedOptions.value); - } - if (allowAnswers.present) { - map['allow_answers'] = Variable(allowAnswers.value); - } - if (isClosed.present) { - map['is_closed'] = Variable(isClosed.value); - } - if (answersCount.present) { - map['answers_count'] = Variable(answersCount.value); - } - if (voteCountsByOption.present) { - map['vote_counts_by_option'] = Variable($PollsTable - .$convertervoteCountsByOption - .toSql(voteCountsByOption.value)); + if (userId.present) { + map['user_id'] = Variable(userId.value); } - if (voteCount.present) { - map['vote_count'] = Variable(voteCount.value); + if (messageId.present) { + map['message_id'] = Variable(messageId.value); } - if (createdById.present) { - map['created_by_id'] = Variable(createdById.value); + if (type.present) { + map['type'] = Variable(type.value); } if (createdAt.present) { map['created_at'] = Variable(createdAt.value); } - if (updatedAt.present) { - map['updated_at'] = Variable(updatedAt.value); + if (score.present) { + map['score'] = Variable(score.value); } if (extraData.present) { - map['extra_data'] = Variable( - $PollsTable.$converterextraDatan.toSql(extraData.value)); + map['extra_data'] = Variable($PinnedMessageReactionsTable + .$converterextraDatan + .toSql(extraData.value)); } if (rowid.present) { map['rowid'] = Variable(rowid.value); @@ -5003,23 +6239,12 @@ class PollsCompanion extends UpdateCompanion { @override String toString() { - return (StringBuffer('PollsCompanion(') - ..write('id: $id, ') - ..write('name: $name, ') - ..write('description: $description, ') - ..write('options: $options, ') - ..write('votingVisibility: $votingVisibility, ') - ..write('enforceUniqueVote: $enforceUniqueVote, ') - ..write('maxVotesAllowed: $maxVotesAllowed, ') - ..write('allowUserSuggestedOptions: $allowUserSuggestedOptions, ') - ..write('allowAnswers: $allowAnswers, ') - ..write('isClosed: $isClosed, ') - ..write('answersCount: $answersCount, ') - ..write('voteCountsByOption: $voteCountsByOption, ') - ..write('voteCount: $voteCount, ') - ..write('createdById: $createdById, ') + return (StringBuffer('PinnedMessageReactionsCompanion(') + ..write('userId: $userId, ') + ..write('messageId: $messageId, ') + ..write('type: $type, ') ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt, ') + ..write('score: $score, ') ..write('extraData: $extraData, ') ..write('rowid: $rowid') ..write(')')) @@ -5027,37 +6252,31 @@ class PollsCompanion extends UpdateCompanion { } } -class $PollVotesTable extends PollVotes - with TableInfo<$PollVotesTable, PollVoteEntity> { +class $ReactionsTable extends Reactions + with TableInfo<$ReactionsTable, ReactionEntity> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $PollVotesTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); + $ReactionsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _pollIdMeta = const VerificationMeta('pollId'); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _messageIdMeta = + const VerificationMeta('messageId'); @override - late final GeneratedColumn pollId = GeneratedColumn( - 'poll_id', aliasedName, true, + late final GeneratedColumn messageId = GeneratedColumn( + 'message_id', aliasedName, false, type: DriftSqlType.string, - requiredDuringInsert: false, + requiredDuringInsert: true, defaultConstraints: GeneratedColumn.constraintIsAlways( - 'REFERENCES polls (id) ON DELETE CASCADE')); - static const VerificationMeta _optionIdMeta = - const VerificationMeta('optionId'); - @override - late final GeneratedColumn optionId = GeneratedColumn( - 'option_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _answerTextMeta = - const VerificationMeta('answerText'); + 'REFERENCES messages (id) ON DELETE CASCADE')); + static const VerificationMeta _typeMeta = const VerificationMeta('type'); @override - late final GeneratedColumn answerText = GeneratedColumn( - 'answer_text', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); + late final GeneratedColumn type = GeneratedColumn( + 'type', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); static const VerificationMeta _createdAtMeta = const VerificationMeta('createdAt'); @override @@ -5066,306 +6285,276 @@ class $PollVotesTable extends PollVotes type: DriftSqlType.dateTime, requiredDuringInsert: false, defaultValue: currentDateAndTime); - static const VerificationMeta _updatedAtMeta = - const VerificationMeta('updatedAt'); + static const VerificationMeta _scoreMeta = const VerificationMeta('score'); @override - late final GeneratedColumn updatedAt = GeneratedColumn( - 'updated_at', aliasedName, false, - type: DriftSqlType.dateTime, + late final GeneratedColumn score = GeneratedColumn( + 'score', aliasedName, false, + type: DriftSqlType.int, requiredDuringInsert: false, - defaultValue: currentDateAndTime); - static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + defaultValue: const Constant(0)); @override - late final GeneratedColumn userId = GeneratedColumn( - 'user_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); + late final GeneratedColumnWithTypeConverter?, String> + extraData = GeneratedColumn('extra_data', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false) + .withConverter?>( + $ReactionsTable.$converterextraDatan); @override List get $columns => - [id, pollId, optionId, answerText, createdAt, updatedAt, userId]; + [userId, messageId, type, createdAt, score, extraData]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'poll_votes'; + static const String $name = 'reactions'; @override - VerificationContext validateIntegrity(Insertable instance, + VerificationContext validateIntegrity(Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - if (data.containsKey('poll_id')) { - context.handle(_pollIdMeta, - pollId.isAcceptableOrUnknown(data['poll_id']!, _pollIdMeta)); + if (data.containsKey('user_id')) { + context.handle(_userIdMeta, + userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); + } else if (isInserting) { + context.missing(_userIdMeta); } - if (data.containsKey('option_id')) { - context.handle(_optionIdMeta, - optionId.isAcceptableOrUnknown(data['option_id']!, _optionIdMeta)); + if (data.containsKey('message_id')) { + context.handle(_messageIdMeta, + messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta)); + } else if (isInserting) { + context.missing(_messageIdMeta); } - if (data.containsKey('answer_text')) { + if (data.containsKey('type')) { context.handle( - _answerTextMeta, - answerText.isAcceptableOrUnknown( - data['answer_text']!, _answerTextMeta)); + _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); + } else if (isInserting) { + context.missing(_typeMeta); } if (data.containsKey('created_at')) { context.handle(_createdAtMeta, createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); } - if (data.containsKey('updated_at')) { - context.handle(_updatedAtMeta, - updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); - } - if (data.containsKey('user_id')) { - context.handle(_userIdMeta, - userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); + if (data.containsKey('score')) { + context.handle( + _scoreMeta, score.isAcceptableOrUnknown(data['score']!, _scoreMeta)); } return context; } @override - Set get $primaryKey => {id, pollId}; + Set get $primaryKey => {messageId, type, userId}; @override - PollVoteEntity map(Map data, {String? tablePrefix}) { + ReactionEntity map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return PollVoteEntity( - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id']), - pollId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}poll_id']), - optionId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}option_id']), - answerText: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}answer_text']), + return ReactionEntity( + userId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, + messageId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}message_id'])!, + type: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}type'])!, createdAt: attachedDatabase.typeMapping .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, - updatedAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, - userId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}user_id']), + score: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}score'])!, + extraData: $ReactionsTable.$converterextraDatan.fromSql(attachedDatabase + .typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), ); } @override - $PollVotesTable createAlias(String alias) { - return $PollVotesTable(attachedDatabase, alias); + $ReactionsTable createAlias(String alias) { + return $ReactionsTable(attachedDatabase, alias); } -} -class PollVoteEntity extends DataClass implements Insertable { - /// The unique identifier of the poll vote. - final String? id; + static TypeConverter, String> $converterextraData = + MapConverter(); + static TypeConverter?, String?> $converterextraDatan = + NullAwareTypeConverter.wrap($converterextraData); +} - /// The unique identifier of the poll the vote belongs to. - final String? pollId; +class ReactionEntity extends DataClass implements Insertable { + /// The id of the user that sent the reaction + final String userId; - /// The unique identifier of the option selected in the poll. - /// - /// Nullable if the user provided an answer. - final String? optionId; + /// The messageId to which the reaction belongs + final String messageId; - /// The text of the answer provided in the poll. - /// - /// Nullable if the user selected an option. - final String? answerText; + /// The type of the reaction + final String type; - /// The date when the poll vote was created. + /// The DateTime on which the reaction is created final DateTime createdAt; - /// The date when the poll vote was last updated. - final DateTime updatedAt; + /// The score of the reaction (ie. number of reactions sent) + final int score; - /// The unique identifier of the user who voted. - /// - /// Nullable if the poll is anonymous. - final String? userId; - const PollVoteEntity( - {this.id, - this.pollId, - this.optionId, - this.answerText, + /// Reaction custom extraData + final Map? extraData; + const ReactionEntity( + {required this.userId, + required this.messageId, + required this.type, required this.createdAt, - required this.updatedAt, - this.userId}); + required this.score, + this.extraData}); @override Map toColumns(bool nullToAbsent) { final map = {}; - if (!nullToAbsent || id != null) { - map['id'] = Variable(id); - } - if (!nullToAbsent || pollId != null) { - map['poll_id'] = Variable(pollId); - } - if (!nullToAbsent || optionId != null) { - map['option_id'] = Variable(optionId); - } - if (!nullToAbsent || answerText != null) { - map['answer_text'] = Variable(answerText); - } + map['user_id'] = Variable(userId); + map['message_id'] = Variable(messageId); + map['type'] = Variable(type); map['created_at'] = Variable(createdAt); - map['updated_at'] = Variable(updatedAt); - if (!nullToAbsent || userId != null) { - map['user_id'] = Variable(userId); + map['score'] = Variable(score); + if (!nullToAbsent || extraData != null) { + map['extra_data'] = Variable( + $ReactionsTable.$converterextraDatan.toSql(extraData)); } return map; } - factory PollVoteEntity.fromJson(Map json, + factory ReactionEntity.fromJson(Map json, {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; - return PollVoteEntity( - id: serializer.fromJson(json['id']), - pollId: serializer.fromJson(json['pollId']), - optionId: serializer.fromJson(json['optionId']), - answerText: serializer.fromJson(json['answerText']), + return ReactionEntity( + userId: serializer.fromJson(json['userId']), + messageId: serializer.fromJson(json['messageId']), + type: serializer.fromJson(json['type']), createdAt: serializer.fromJson(json['createdAt']), - updatedAt: serializer.fromJson(json['updatedAt']), - userId: serializer.fromJson(json['userId']), + score: serializer.fromJson(json['score']), + extraData: serializer.fromJson?>(json['extraData']), ); } @override Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'id': serializer.toJson(id), - 'pollId': serializer.toJson(pollId), - 'optionId': serializer.toJson(optionId), - 'answerText': serializer.toJson(answerText), + 'userId': serializer.toJson(userId), + 'messageId': serializer.toJson(messageId), + 'type': serializer.toJson(type), 'createdAt': serializer.toJson(createdAt), - 'updatedAt': serializer.toJson(updatedAt), - 'userId': serializer.toJson(userId), + 'score': serializer.toJson(score), + 'extraData': serializer.toJson?>(extraData), }; } - PollVoteEntity copyWith( - {Value id = const Value.absent(), - Value pollId = const Value.absent(), - Value optionId = const Value.absent(), - Value answerText = const Value.absent(), + ReactionEntity copyWith( + {String? userId, + String? messageId, + String? type, DateTime? createdAt, - DateTime? updatedAt, - Value userId = const Value.absent()}) => - PollVoteEntity( - id: id.present ? id.value : this.id, - pollId: pollId.present ? pollId.value : this.pollId, - optionId: optionId.present ? optionId.value : this.optionId, - answerText: answerText.present ? answerText.value : this.answerText, + int? score, + Value?> extraData = const Value.absent()}) => + ReactionEntity( + userId: userId ?? this.userId, + messageId: messageId ?? this.messageId, + type: type ?? this.type, createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, - userId: userId.present ? userId.value : this.userId, + score: score ?? this.score, + extraData: extraData.present ? extraData.value : this.extraData, ); - PollVoteEntity copyWithCompanion(PollVotesCompanion data) { - return PollVoteEntity( - id: data.id.present ? data.id.value : this.id, - pollId: data.pollId.present ? data.pollId.value : this.pollId, - optionId: data.optionId.present ? data.optionId.value : this.optionId, - answerText: - data.answerText.present ? data.answerText.value : this.answerText, - createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, - updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ReactionEntity copyWithCompanion(ReactionsCompanion data) { + return ReactionEntity( userId: data.userId.present ? data.userId.value : this.userId, + messageId: data.messageId.present ? data.messageId.value : this.messageId, + type: data.type.present ? data.type.value : this.type, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + score: data.score.present ? data.score.value : this.score, + extraData: data.extraData.present ? data.extraData.value : this.extraData, ); } @override String toString() { - return (StringBuffer('PollVoteEntity(') - ..write('id: $id, ') - ..write('pollId: $pollId, ') - ..write('optionId: $optionId, ') - ..write('answerText: $answerText, ') + return (StringBuffer('ReactionEntity(') + ..write('userId: $userId, ') + ..write('messageId: $messageId, ') + ..write('type: $type, ') ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt, ') - ..write('userId: $userId') + ..write('score: $score, ') + ..write('extraData: $extraData') ..write(')')) .toString(); } @override - int get hashCode => Object.hash( - id, pollId, optionId, answerText, createdAt, updatedAt, userId); + int get hashCode => + Object.hash(userId, messageId, type, createdAt, score, extraData); @override bool operator ==(Object other) => identical(this, other) || - (other is PollVoteEntity && - other.id == this.id && - other.pollId == this.pollId && - other.optionId == this.optionId && - other.answerText == this.answerText && + (other is ReactionEntity && + other.userId == this.userId && + other.messageId == this.messageId && + other.type == this.type && other.createdAt == this.createdAt && - other.updatedAt == this.updatedAt && - other.userId == this.userId); + other.score == this.score && + other.extraData == this.extraData); } -class PollVotesCompanion extends UpdateCompanion { - final Value id; - final Value pollId; - final Value optionId; - final Value answerText; +class ReactionsCompanion extends UpdateCompanion { + final Value userId; + final Value messageId; + final Value type; final Value createdAt; - final Value updatedAt; - final Value userId; + final Value score; + final Value?> extraData; final Value rowid; - const PollVotesCompanion({ - this.id = const Value.absent(), - this.pollId = const Value.absent(), - this.optionId = const Value.absent(), - this.answerText = const Value.absent(), - this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), + const ReactionsCompanion({ this.userId = const Value.absent(), + this.messageId = const Value.absent(), + this.type = const Value.absent(), + this.createdAt = const Value.absent(), + this.score = const Value.absent(), + this.extraData = const Value.absent(), this.rowid = const Value.absent(), }); - PollVotesCompanion.insert({ - this.id = const Value.absent(), - this.pollId = const Value.absent(), - this.optionId = const Value.absent(), - this.answerText = const Value.absent(), + ReactionsCompanion.insert({ + required String userId, + required String messageId, + required String type, this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), - this.userId = const Value.absent(), + this.score = const Value.absent(), + this.extraData = const Value.absent(), this.rowid = const Value.absent(), - }); - static Insertable custom({ - Expression? id, - Expression? pollId, - Expression? optionId, - Expression? answerText, - Expression? createdAt, - Expression? updatedAt, + }) : userId = Value(userId), + messageId = Value(messageId), + type = Value(type); + static Insertable custom({ Expression? userId, + Expression? messageId, + Expression? type, + Expression? createdAt, + Expression? score, + Expression? extraData, Expression? rowid, }) { return RawValuesInsertable({ - if (id != null) 'id': id, - if (pollId != null) 'poll_id': pollId, - if (optionId != null) 'option_id': optionId, - if (answerText != null) 'answer_text': answerText, - if (createdAt != null) 'created_at': createdAt, - if (updatedAt != null) 'updated_at': updatedAt, if (userId != null) 'user_id': userId, + if (messageId != null) 'message_id': messageId, + if (type != null) 'type': type, + if (createdAt != null) 'created_at': createdAt, + if (score != null) 'score': score, + if (extraData != null) 'extra_data': extraData, if (rowid != null) 'rowid': rowid, }); } - PollVotesCompanion copyWith( - {Value? id, - Value? pollId, - Value? optionId, - Value? answerText, + ReactionsCompanion copyWith( + {Value? userId, + Value? messageId, + Value? type, Value? createdAt, - Value? updatedAt, - Value? userId, + Value? score, + Value?>? extraData, Value? rowid}) { - return PollVotesCompanion( - id: id ?? this.id, - pollId: pollId ?? this.pollId, - optionId: optionId ?? this.optionId, - answerText: answerText ?? this.answerText, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, + return ReactionsCompanion( userId: userId ?? this.userId, + messageId: messageId ?? this.messageId, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + score: score ?? this.score, + extraData: extraData ?? this.extraData, rowid: rowid ?? this.rowid, ); } @@ -5373,26 +6562,24 @@ class PollVotesCompanion extends UpdateCompanion { @override Map toColumns(bool nullToAbsent) { final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (pollId.present) { - map['poll_id'] = Variable(pollId.value); + if (userId.present) { + map['user_id'] = Variable(userId.value); } - if (optionId.present) { - map['option_id'] = Variable(optionId.value); + if (messageId.present) { + map['message_id'] = Variable(messageId.value); } - if (answerText.present) { - map['answer_text'] = Variable(answerText.value); + if (type.present) { + map['type'] = Variable(type.value); } if (createdAt.present) { map['created_at'] = Variable(createdAt.value); } - if (updatedAt.present) { - map['updated_at'] = Variable(updatedAt.value); + if (score.present) { + map['score'] = Variable(score.value); } - if (userId.present) { - map['user_id'] = Variable(userId.value); + if (extraData.present) { + map['extra_data'] = Variable( + $ReactionsTable.$converterextraDatan.toSql(extraData.value)); } if (rowid.present) { map['rowid'] = Variable(rowid.value); @@ -5402,327 +6589,464 @@ class PollVotesCompanion extends UpdateCompanion { @override String toString() { - return (StringBuffer('PollVotesCompanion(') - ..write('id: $id, ') - ..write('pollId: $pollId, ') - ..write('optionId: $optionId, ') - ..write('answerText: $answerText, ') - ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt, ') + return (StringBuffer('ReactionsCompanion(') ..write('userId: $userId, ') + ..write('messageId: $messageId, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('score: $score, ') + ..write('extraData: $extraData, ') ..write('rowid: $rowid') ..write(')')) .toString(); } } -class $PinnedMessageReactionsTable extends PinnedMessageReactions - with TableInfo<$PinnedMessageReactionsTable, PinnedMessageReactionEntity> { +class $UsersTable extends Users with TableInfo<$UsersTable, UserEntity> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $PinnedMessageReactionsTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + $UsersTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); @override - late final GeneratedColumn userId = GeneratedColumn( - 'user_id', aliasedName, false, + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _messageIdMeta = - const VerificationMeta('messageId'); + static const VerificationMeta _roleMeta = const VerificationMeta('role'); @override - late final GeneratedColumn messageId = GeneratedColumn( - 'message_id', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'REFERENCES pinned_messages (id) ON DELETE CASCADE')); - static const VerificationMeta _typeMeta = const VerificationMeta('type'); + late final GeneratedColumn role = GeneratedColumn( + 'role', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _languageMeta = + const VerificationMeta('language'); @override - late final GeneratedColumn type = GeneratedColumn( - 'type', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); + late final GeneratedColumn language = GeneratedColumn( + 'language', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); static const VerificationMeta _createdAtMeta = const VerificationMeta('createdAt'); @override - late final GeneratedColumn createdAt = GeneratedColumn( - 'created_at', aliasedName, false, - type: DriftSqlType.dateTime, + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _updatedAtMeta = + const VerificationMeta('updatedAt'); + @override + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _lastActiveMeta = + const VerificationMeta('lastActive'); + @override + late final GeneratedColumn lastActive = GeneratedColumn( + 'last_active', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _onlineMeta = const VerificationMeta('online'); + @override + late final GeneratedColumn online = GeneratedColumn( + 'online', aliasedName, false, + type: DriftSqlType.bool, requiredDuringInsert: false, - defaultValue: currentDateAndTime); - static const VerificationMeta _scoreMeta = const VerificationMeta('score'); + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("online" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _bannedMeta = const VerificationMeta('banned'); @override - late final GeneratedColumn score = GeneratedColumn( - 'score', aliasedName, false, - type: DriftSqlType.int, + late final GeneratedColumn banned = GeneratedColumn( + 'banned', aliasedName, false, + type: DriftSqlType.bool, requiredDuringInsert: false, - defaultValue: const Constant(0)); + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("banned" IN (0, 1))'), + defaultValue: const Constant(false)); @override - late final GeneratedColumnWithTypeConverter?, String> - extraData = GeneratedColumn('extra_data', aliasedName, true, + late final GeneratedColumnWithTypeConverter?, String> + teamsRole = GeneratedColumn('teams_role', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $PinnedMessageReactionsTable.$converterextraDatan); + .withConverter?>( + $UsersTable.$converterteamsRolen); @override - List get $columns => - [userId, messageId, type, createdAt, score, extraData]; + late final GeneratedColumnWithTypeConverter, String> + extraData = GeneratedColumn('extra_data', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true) + .withConverter>($UsersTable.$converterextraData); + @override + List get $columns => [ + id, + role, + language, + createdAt, + updatedAt, + lastActive, + online, + banned, + teamsRole, + extraData + ]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'pinned_message_reactions'; + static const String $name = 'users'; @override - VerificationContext validateIntegrity( - Insertable instance, + VerificationContext validateIntegrity(Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('user_id')) { - context.handle(_userIdMeta, - userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); - } else if (isInserting) { - context.missing(_userIdMeta); - } - if (data.containsKey('message_id')) { - context.handle(_messageIdMeta, - messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta)); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); } else if (isInserting) { - context.missing(_messageIdMeta); + context.missing(_idMeta); } - if (data.containsKey('type')) { + if (data.containsKey('role')) { context.handle( - _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); - } else if (isInserting) { - context.missing(_typeMeta); + _roleMeta, role.isAcceptableOrUnknown(data['role']!, _roleMeta)); + } + if (data.containsKey('language')) { + context.handle(_languageMeta, + language.isAcceptableOrUnknown(data['language']!, _languageMeta)); } if (data.containsKey('created_at')) { context.handle(_createdAtMeta, createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); } - if (data.containsKey('score')) { + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + } + if (data.containsKey('last_active')) { context.handle( - _scoreMeta, score.isAcceptableOrUnknown(data['score']!, _scoreMeta)); + _lastActiveMeta, + lastActive.isAcceptableOrUnknown( + data['last_active']!, _lastActiveMeta)); + } + if (data.containsKey('online')) { + context.handle(_onlineMeta, + online.isAcceptableOrUnknown(data['online']!, _onlineMeta)); + } + if (data.containsKey('banned')) { + context.handle(_bannedMeta, + banned.isAcceptableOrUnknown(data['banned']!, _bannedMeta)); } return context; } @override - Set get $primaryKey => {messageId, type, userId}; + Set get $primaryKey => {id}; @override - PinnedMessageReactionEntity map(Map data, - {String? tablePrefix}) { + UserEntity map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return PinnedMessageReactionEntity( - userId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, - messageId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}message_id'])!, - type: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}type'])!, + return UserEntity( + id: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}id'])!, + role: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}role']), + language: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}language']), createdAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, - score: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}score'])!, - extraData: $PinnedMessageReactionsTable.$converterextraDatan.fromSql( - attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at']), + updatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at']), + lastActive: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}last_active']), + online: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}online'])!, + banned: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}banned'])!, + teamsRole: $UsersTable.$converterteamsRolen.fromSql(attachedDatabase + .typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}teams_role'])), + extraData: $UsersTable.$converterextraData.fromSql(attachedDatabase + .typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])!), ); } @override - $PinnedMessageReactionsTable createAlias(String alias) { - return $PinnedMessageReactionsTable(attachedDatabase, alias); + $UsersTable createAlias(String alias) { + return $UsersTable(attachedDatabase, alias); } + static TypeConverter, String> $converterteamsRole = + MapConverter(); + static TypeConverter?, String?> $converterteamsRolen = + NullAwareTypeConverter.wrap($converterteamsRole); static TypeConverter, String> $converterextraData = MapConverter(); - static TypeConverter?, String?> $converterextraDatan = - NullAwareTypeConverter.wrap($converterextraData); } -class PinnedMessageReactionEntity extends DataClass - implements Insertable { - /// The id of the user that sent the reaction - final String userId; +class UserEntity extends DataClass implements Insertable { + /// User id + final String id; - /// The messageId to which the reaction belongs - final String messageId; + /// User role + final String? role; - /// The type of the reaction - final String type; + /// The language this user prefers. + final String? language; - /// The DateTime on which the reaction is created - final DateTime createdAt; + /// Date of user creation + final DateTime? createdAt; - /// The score of the reaction (ie. number of reactions sent) - final int score; + /// Date of last user update + final DateTime? updatedAt; - /// Reaction custom extraData - final Map? extraData; - const PinnedMessageReactionEntity( - {required this.userId, - required this.messageId, - required this.type, - required this.createdAt, - required this.score, - this.extraData}); + /// Date of last user connection + final DateTime? lastActive; + + /// True if user is online + final bool online; + + /// True if user is banned from the chat + final bool banned; + + /// The roles for the user in the teams. + /// + /// eg: `{'teamId': 'role', 'teamId2': 'role2'}` + final Map? teamsRole; + + /// Map of custom user extraData + final Map extraData; + const UserEntity( + {required this.id, + this.role, + this.language, + this.createdAt, + this.updatedAt, + this.lastActive, + required this.online, + required this.banned, + this.teamsRole, + required this.extraData}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['user_id'] = Variable(userId); - map['message_id'] = Variable(messageId); - map['type'] = Variable(type); - map['created_at'] = Variable(createdAt); - map['score'] = Variable(score); - if (!nullToAbsent || extraData != null) { - map['extra_data'] = Variable( - $PinnedMessageReactionsTable.$converterextraDatan.toSql(extraData)); + map['id'] = Variable(id); + if (!nullToAbsent || role != null) { + map['role'] = Variable(role); + } + if (!nullToAbsent || language != null) { + map['language'] = Variable(language); + } + if (!nullToAbsent || createdAt != null) { + map['created_at'] = Variable(createdAt); + } + if (!nullToAbsent || updatedAt != null) { + map['updated_at'] = Variable(updatedAt); + } + if (!nullToAbsent || lastActive != null) { + map['last_active'] = Variable(lastActive); + } + map['online'] = Variable(online); + map['banned'] = Variable(banned); + if (!nullToAbsent || teamsRole != null) { + map['teams_role'] = + Variable($UsersTable.$converterteamsRolen.toSql(teamsRole)); + } + { + map['extra_data'] = + Variable($UsersTable.$converterextraData.toSql(extraData)); } return map; } - - factory PinnedMessageReactionEntity.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return PinnedMessageReactionEntity( - userId: serializer.fromJson(json['userId']), - messageId: serializer.fromJson(json['messageId']), - type: serializer.fromJson(json['type']), - createdAt: serializer.fromJson(json['createdAt']), - score: serializer.fromJson(json['score']), - extraData: serializer.fromJson?>(json['extraData']), + + factory UserEntity.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserEntity( + id: serializer.fromJson(json['id']), + role: serializer.fromJson(json['role']), + language: serializer.fromJson(json['language']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + lastActive: serializer.fromJson(json['lastActive']), + online: serializer.fromJson(json['online']), + banned: serializer.fromJson(json['banned']), + teamsRole: serializer.fromJson?>(json['teamsRole']), + extraData: serializer.fromJson>(json['extraData']), ); } @override Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'userId': serializer.toJson(userId), - 'messageId': serializer.toJson(messageId), - 'type': serializer.toJson(type), - 'createdAt': serializer.toJson(createdAt), - 'score': serializer.toJson(score), - 'extraData': serializer.toJson?>(extraData), + 'id': serializer.toJson(id), + 'role': serializer.toJson(role), + 'language': serializer.toJson(language), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'lastActive': serializer.toJson(lastActive), + 'online': serializer.toJson(online), + 'banned': serializer.toJson(banned), + 'teamsRole': serializer.toJson?>(teamsRole), + 'extraData': serializer.toJson>(extraData), }; } - PinnedMessageReactionEntity copyWith( - {String? userId, - String? messageId, - String? type, - DateTime? createdAt, - int? score, - Value?> extraData = const Value.absent()}) => - PinnedMessageReactionEntity( - userId: userId ?? this.userId, - messageId: messageId ?? this.messageId, - type: type ?? this.type, - createdAt: createdAt ?? this.createdAt, - score: score ?? this.score, - extraData: extraData.present ? extraData.value : this.extraData, + UserEntity copyWith( + {String? id, + Value role = const Value.absent(), + Value language = const Value.absent(), + Value createdAt = const Value.absent(), + Value updatedAt = const Value.absent(), + Value lastActive = const Value.absent(), + bool? online, + bool? banned, + Value?> teamsRole = const Value.absent(), + Map? extraData}) => + UserEntity( + id: id ?? this.id, + role: role.present ? role.value : this.role, + language: language.present ? language.value : this.language, + createdAt: createdAt.present ? createdAt.value : this.createdAt, + updatedAt: updatedAt.present ? updatedAt.value : this.updatedAt, + lastActive: lastActive.present ? lastActive.value : this.lastActive, + online: online ?? this.online, + banned: banned ?? this.banned, + teamsRole: teamsRole.present ? teamsRole.value : this.teamsRole, + extraData: extraData ?? this.extraData, ); - PinnedMessageReactionEntity copyWithCompanion( - PinnedMessageReactionsCompanion data) { - return PinnedMessageReactionEntity( - userId: data.userId.present ? data.userId.value : this.userId, - messageId: data.messageId.present ? data.messageId.value : this.messageId, - type: data.type.present ? data.type.value : this.type, + UserEntity copyWithCompanion(UsersCompanion data) { + return UserEntity( + id: data.id.present ? data.id.value : this.id, + role: data.role.present ? data.role.value : this.role, + language: data.language.present ? data.language.value : this.language, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, - score: data.score.present ? data.score.value : this.score, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + lastActive: + data.lastActive.present ? data.lastActive.value : this.lastActive, + online: data.online.present ? data.online.value : this.online, + banned: data.banned.present ? data.banned.value : this.banned, + teamsRole: data.teamsRole.present ? data.teamsRole.value : this.teamsRole, extraData: data.extraData.present ? data.extraData.value : this.extraData, ); } @override String toString() { - return (StringBuffer('PinnedMessageReactionEntity(') - ..write('userId: $userId, ') - ..write('messageId: $messageId, ') - ..write('type: $type, ') + return (StringBuffer('UserEntity(') + ..write('id: $id, ') + ..write('role: $role, ') + ..write('language: $language, ') ..write('createdAt: $createdAt, ') - ..write('score: $score, ') + ..write('updatedAt: $updatedAt, ') + ..write('lastActive: $lastActive, ') + ..write('online: $online, ') + ..write('banned: $banned, ') + ..write('teamsRole: $teamsRole, ') ..write('extraData: $extraData') ..write(')')) .toString(); } @override - int get hashCode => - Object.hash(userId, messageId, type, createdAt, score, extraData); + int get hashCode => Object.hash(id, role, language, createdAt, updatedAt, + lastActive, online, banned, teamsRole, extraData); @override bool operator ==(Object other) => identical(this, other) || - (other is PinnedMessageReactionEntity && - other.userId == this.userId && - other.messageId == this.messageId && - other.type == this.type && + (other is UserEntity && + other.id == this.id && + other.role == this.role && + other.language == this.language && other.createdAt == this.createdAt && - other.score == this.score && + other.updatedAt == this.updatedAt && + other.lastActive == this.lastActive && + other.online == this.online && + other.banned == this.banned && + other.teamsRole == this.teamsRole && other.extraData == this.extraData); } -class PinnedMessageReactionsCompanion - extends UpdateCompanion { - final Value userId; - final Value messageId; - final Value type; - final Value createdAt; - final Value score; - final Value?> extraData; +class UsersCompanion extends UpdateCompanion { + final Value id; + final Value role; + final Value language; + final Value createdAt; + final Value updatedAt; + final Value lastActive; + final Value online; + final Value banned; + final Value?> teamsRole; + final Value> extraData; final Value rowid; - const PinnedMessageReactionsCompanion({ - this.userId = const Value.absent(), - this.messageId = const Value.absent(), - this.type = const Value.absent(), + const UsersCompanion({ + this.id = const Value.absent(), + this.role = const Value.absent(), + this.language = const Value.absent(), this.createdAt = const Value.absent(), - this.score = const Value.absent(), + this.updatedAt = const Value.absent(), + this.lastActive = const Value.absent(), + this.online = const Value.absent(), + this.banned = const Value.absent(), + this.teamsRole = const Value.absent(), this.extraData = const Value.absent(), this.rowid = const Value.absent(), }); - PinnedMessageReactionsCompanion.insert({ - required String userId, - required String messageId, - required String type, + UsersCompanion.insert({ + required String id, + this.role = const Value.absent(), + this.language = const Value.absent(), this.createdAt = const Value.absent(), - this.score = const Value.absent(), - this.extraData = const Value.absent(), + this.updatedAt = const Value.absent(), + this.lastActive = const Value.absent(), + this.online = const Value.absent(), + this.banned = const Value.absent(), + this.teamsRole = const Value.absent(), + required Map extraData, this.rowid = const Value.absent(), - }) : userId = Value(userId), - messageId = Value(messageId), - type = Value(type); - static Insertable custom({ - Expression? userId, - Expression? messageId, - Expression? type, + }) : id = Value(id), + extraData = Value(extraData); + static Insertable custom({ + Expression? id, + Expression? role, + Expression? language, Expression? createdAt, - Expression? score, + Expression? updatedAt, + Expression? lastActive, + Expression? online, + Expression? banned, + Expression? teamsRole, Expression? extraData, Expression? rowid, }) { return RawValuesInsertable({ - if (userId != null) 'user_id': userId, - if (messageId != null) 'message_id': messageId, - if (type != null) 'type': type, + if (id != null) 'id': id, + if (role != null) 'role': role, + if (language != null) 'language': language, if (createdAt != null) 'created_at': createdAt, - if (score != null) 'score': score, + if (updatedAt != null) 'updated_at': updatedAt, + if (lastActive != null) 'last_active': lastActive, + if (online != null) 'online': online, + if (banned != null) 'banned': banned, + if (teamsRole != null) 'teams_role': teamsRole, if (extraData != null) 'extra_data': extraData, if (rowid != null) 'rowid': rowid, }); } - PinnedMessageReactionsCompanion copyWith( - {Value? userId, - Value? messageId, - Value? type, - Value? createdAt, - Value? score, - Value?>? extraData, + UsersCompanion copyWith( + {Value? id, + Value? role, + Value? language, + Value? createdAt, + Value? updatedAt, + Value? lastActive, + Value? online, + Value? banned, + Value?>? teamsRole, + Value>? extraData, Value? rowid}) { - return PinnedMessageReactionsCompanion( - userId: userId ?? this.userId, - messageId: messageId ?? this.messageId, - type: type ?? this.type, + return UsersCompanion( + id: id ?? this.id, + role: role ?? this.role, + language: language ?? this.language, createdAt: createdAt ?? this.createdAt, - score: score ?? this.score, + updatedAt: updatedAt ?? this.updatedAt, + lastActive: lastActive ?? this.lastActive, + online: online ?? this.online, + banned: banned ?? this.banned, + teamsRole: teamsRole ?? this.teamsRole, extraData: extraData ?? this.extraData, rowid: rowid ?? this.rowid, ); @@ -5731,25 +7055,37 @@ class PinnedMessageReactionsCompanion @override Map toColumns(bool nullToAbsent) { final map = {}; - if (userId.present) { - map['user_id'] = Variable(userId.value); + if (id.present) { + map['id'] = Variable(id.value); } - if (messageId.present) { - map['message_id'] = Variable(messageId.value); + if (role.present) { + map['role'] = Variable(role.value); } - if (type.present) { - map['type'] = Variable(type.value); + if (language.present) { + map['language'] = Variable(language.value); } if (createdAt.present) { map['created_at'] = Variable(createdAt.value); } - if (score.present) { - map['score'] = Variable(score.value); + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (lastActive.present) { + map['last_active'] = Variable(lastActive.value); + } + if (online.present) { + map['online'] = Variable(online.value); + } + if (banned.present) { + map['banned'] = Variable(banned.value); + } + if (teamsRole.present) { + map['teams_role'] = Variable( + $UsersTable.$converterteamsRolen.toSql(teamsRole.value)); } if (extraData.present) { - map['extra_data'] = Variable($PinnedMessageReactionsTable - .$converterextraDatan - .toSql(extraData.value)); + map['extra_data'] = Variable( + $UsersTable.$converterextraData.toSql(extraData.value)); } if (rowid.present) { map['rowid'] = Variable(rowid.value); @@ -5759,12 +7095,16 @@ class PinnedMessageReactionsCompanion @override String toString() { - return (StringBuffer('PinnedMessageReactionsCompanion(') - ..write('userId: $userId, ') - ..write('messageId: $messageId, ') - ..write('type: $type, ') + return (StringBuffer('UsersCompanion(') + ..write('id: $id, ') + ..write('role: $role, ') + ..write('language: $language, ') ..write('createdAt: $createdAt, ') - ..write('score: $score, ') + ..write('updatedAt: $updatedAt, ') + ..write('lastActive: $lastActive, ') + ..write('online: $online, ') + ..write('banned: $banned, ') + ..write('teamsRole: $teamsRole, ') ..write('extraData: $extraData, ') ..write('rowid: $rowid') ..write(')')) @@ -5772,62 +7112,145 @@ class PinnedMessageReactionsCompanion } } -class $ReactionsTable extends Reactions - with TableInfo<$ReactionsTable, ReactionEntity> { +class $MembersTable extends Members + with TableInfo<$MembersTable, MemberEntity> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $ReactionsTable(this.attachedDatabase, [this._alias]); + $MembersTable(this.attachedDatabase, [this._alias]); static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override late final GeneratedColumn userId = GeneratedColumn( 'user_id', aliasedName, false, type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _messageIdMeta = - const VerificationMeta('messageId'); + static const VerificationMeta _channelCidMeta = + const VerificationMeta('channelCid'); @override - late final GeneratedColumn messageId = GeneratedColumn( - 'message_id', aliasedName, false, + late final GeneratedColumn channelCid = GeneratedColumn( + 'channel_cid', aliasedName, false, type: DriftSqlType.string, requiredDuringInsert: true, defaultConstraints: GeneratedColumn.constraintIsAlways( - 'REFERENCES messages (id) ON DELETE CASCADE')); - static const VerificationMeta _typeMeta = const VerificationMeta('type'); + 'REFERENCES channels (cid) ON DELETE CASCADE')); + static const VerificationMeta _channelRoleMeta = + const VerificationMeta('channelRole'); @override - late final GeneratedColumn type = GeneratedColumn( - 'type', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _createdAtMeta = - const VerificationMeta('createdAt'); + late final GeneratedColumn channelRole = GeneratedColumn( + 'channel_role', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _inviteAcceptedAtMeta = + const VerificationMeta('inviteAcceptedAt'); @override - late final GeneratedColumn createdAt = GeneratedColumn( - 'created_at', aliasedName, false, + late final GeneratedColumn inviteAcceptedAt = + GeneratedColumn('invite_accepted_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _inviteRejectedAtMeta = + const VerificationMeta('inviteRejectedAt'); + @override + late final GeneratedColumn inviteRejectedAt = + GeneratedColumn('invite_rejected_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _invitedMeta = + const VerificationMeta('invited'); + @override + late final GeneratedColumn invited = GeneratedColumn( + 'invited', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("invited" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _bannedMeta = const VerificationMeta('banned'); + @override + late final GeneratedColumn banned = GeneratedColumn( + 'banned', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("banned" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _shadowBannedMeta = + const VerificationMeta('shadowBanned'); + @override + late final GeneratedColumn shadowBanned = GeneratedColumn( + 'shadow_banned', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("shadow_banned" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _pinnedAtMeta = + const VerificationMeta('pinnedAt'); + @override + late final GeneratedColumn pinnedAt = GeneratedColumn( + 'pinned_at', aliasedName, true, type: DriftSqlType.dateTime, requiredDuringInsert: false, - defaultValue: currentDateAndTime); - static const VerificationMeta _scoreMeta = const VerificationMeta('score'); + defaultValue: const Constant(null)); + static const VerificationMeta _archivedAtMeta = + const VerificationMeta('archivedAt'); @override - late final GeneratedColumn score = GeneratedColumn( - 'score', aliasedName, false, - type: DriftSqlType.int, + late final GeneratedColumn archivedAt = GeneratedColumn( + 'archived_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false, - defaultValue: const Constant(0)); + defaultValue: const Constant(null)); + static const VerificationMeta _isModeratorMeta = + const VerificationMeta('isModerator'); + @override + late final GeneratedColumn isModerator = GeneratedColumn( + 'is_moderator', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_moderator" IN (0, 1))'), + defaultValue: const Constant(false)); @override late final GeneratedColumnWithTypeConverter?, String> extraData = GeneratedColumn('extra_data', aliasedName, true, type: DriftSqlType.string, requiredDuringInsert: false) .withConverter?>( - $ReactionsTable.$converterextraDatan); + $MembersTable.$converterextraDatan); + static const VerificationMeta _createdAtMeta = + const VerificationMeta('createdAt'); @override - List get $columns => - [userId, messageId, type, createdAt, score, extraData]; + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + static const VerificationMeta _updatedAtMeta = + const VerificationMeta('updatedAt'); + @override + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + @override + List get $columns => [ + userId, + channelCid, + channelRole, + inviteAcceptedAt, + inviteRejectedAt, + invited, + banned, + shadowBanned, + pinnedAt, + archivedAt, + isModerator, + extraData, + createdAt, + updatedAt + ]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'reactions'; + static const String $name = 'members'; @override - VerificationContext validateIntegrity(Insertable instance, + VerificationContext validateIntegrity(Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); @@ -5837,54 +7260,114 @@ class $ReactionsTable extends Reactions } else if (isInserting) { context.missing(_userIdMeta); } - if (data.containsKey('message_id')) { - context.handle(_messageIdMeta, - messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta)); + if (data.containsKey('channel_cid')) { + context.handle( + _channelCidMeta, + channelCid.isAcceptableOrUnknown( + data['channel_cid']!, _channelCidMeta)); } else if (isInserting) { - context.missing(_messageIdMeta); + context.missing(_channelCidMeta); } - if (data.containsKey('type')) { + if (data.containsKey('channel_role')) { context.handle( - _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); - } else if (isInserting) { - context.missing(_typeMeta); + _channelRoleMeta, + channelRole.isAcceptableOrUnknown( + data['channel_role']!, _channelRoleMeta)); + } + if (data.containsKey('invite_accepted_at')) { + context.handle( + _inviteAcceptedAtMeta, + inviteAcceptedAt.isAcceptableOrUnknown( + data['invite_accepted_at']!, _inviteAcceptedAtMeta)); + } + if (data.containsKey('invite_rejected_at')) { + context.handle( + _inviteRejectedAtMeta, + inviteRejectedAt.isAcceptableOrUnknown( + data['invite_rejected_at']!, _inviteRejectedAtMeta)); + } + if (data.containsKey('invited')) { + context.handle(_invitedMeta, + invited.isAcceptableOrUnknown(data['invited']!, _invitedMeta)); + } + if (data.containsKey('banned')) { + context.handle(_bannedMeta, + banned.isAcceptableOrUnknown(data['banned']!, _bannedMeta)); + } + if (data.containsKey('shadow_banned')) { + context.handle( + _shadowBannedMeta, + shadowBanned.isAcceptableOrUnknown( + data['shadow_banned']!, _shadowBannedMeta)); + } + if (data.containsKey('pinned_at')) { + context.handle(_pinnedAtMeta, + pinnedAt.isAcceptableOrUnknown(data['pinned_at']!, _pinnedAtMeta)); + } + if (data.containsKey('archived_at')) { + context.handle( + _archivedAtMeta, + archivedAt.isAcceptableOrUnknown( + data['archived_at']!, _archivedAtMeta)); + } + if (data.containsKey('is_moderator')) { + context.handle( + _isModeratorMeta, + isModerator.isAcceptableOrUnknown( + data['is_moderator']!, _isModeratorMeta)); } if (data.containsKey('created_at')) { context.handle(_createdAtMeta, createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); } - if (data.containsKey('score')) { - context.handle( - _scoreMeta, score.isAcceptableOrUnknown(data['score']!, _scoreMeta)); + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); } return context; } @override - Set get $primaryKey => {messageId, type, userId}; + Set get $primaryKey => {userId, channelCid}; @override - ReactionEntity map(Map data, {String? tablePrefix}) { + MemberEntity map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return ReactionEntity( + return MemberEntity( userId: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, - messageId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}message_id'])!, - type: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}type'])!, - createdAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, - score: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}score'])!, - extraData: $ReactionsTable.$converterextraDatan.fromSql(attachedDatabase + channelCid: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}channel_cid'])!, + channelRole: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}channel_role']), + inviteAcceptedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}invite_accepted_at']), + inviteRejectedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}invite_rejected_at']), + invited: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}invited'])!, + banned: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}banned'])!, + shadowBanned: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}shadow_banned'])!, + pinnedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}pinned_at']), + archivedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}archived_at']), + isModerator: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}is_moderator'])!, + extraData: $MembersTable.$converterextraDatan.fromSql(attachedDatabase .typeMapping .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), + createdAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + updatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, ); } @override - $ReactionsTable createAlias(String alias) { - return $ReactionsTable(attachedDatabase, alias); + $MembersTable createAlias(String alias) { + return $MembersTable(attachedDatabase, alias); } static TypeConverter, String> $converterextraData = @@ -5893,56 +7376,116 @@ class $ReactionsTable extends Reactions NullAwareTypeConverter.wrap($converterextraData); } -class ReactionEntity extends DataClass implements Insertable { - /// The id of the user that sent the reaction +class MemberEntity extends DataClass implements Insertable { + /// The interested user id final String userId; - /// The messageId to which the reaction belongs - final String messageId; + /// The channel cid of which this user is part of + final String channelCid; - /// The type of the reaction - final String type; + /// The role of the user in the channel + final String? channelRole; - /// The DateTime on which the reaction is created - final DateTime createdAt; + /// The date on which the user accepted the invite to the channel + final DateTime? inviteAcceptedAt; - /// The score of the reaction (ie. number of reactions sent) - final int score; + /// The date on which the user rejected the invite to the channel + final DateTime? inviteRejectedAt; - /// Reaction custom extraData + /// True if the user has been invited to the channel + final bool invited; + + /// True if the member is banned from the channel + final bool banned; + + /// True if the member is shadow banned from the channel + final bool shadowBanned; + + /// The date at which the channel was pinned by the member + final DateTime? pinnedAt; + + /// The date at which the channel was archived by the member + final DateTime? archivedAt; + + /// True if the user is a moderator of the channel + final bool isModerator; + + /// Map of custom member extraData final Map? extraData; - const ReactionEntity( + + /// The date of creation + final DateTime createdAt; + + /// The last date of update + final DateTime updatedAt; + const MemberEntity( {required this.userId, - required this.messageId, - required this.type, + required this.channelCid, + this.channelRole, + this.inviteAcceptedAt, + this.inviteRejectedAt, + required this.invited, + required this.banned, + required this.shadowBanned, + this.pinnedAt, + this.archivedAt, + required this.isModerator, + this.extraData, required this.createdAt, - required this.score, - this.extraData}); + required this.updatedAt}); @override Map toColumns(bool nullToAbsent) { final map = {}; map['user_id'] = Variable(userId); - map['message_id'] = Variable(messageId); - map['type'] = Variable(type); - map['created_at'] = Variable(createdAt); - map['score'] = Variable(score); + map['channel_cid'] = Variable(channelCid); + if (!nullToAbsent || channelRole != null) { + map['channel_role'] = Variable(channelRole); + } + if (!nullToAbsent || inviteAcceptedAt != null) { + map['invite_accepted_at'] = Variable(inviteAcceptedAt); + } + if (!nullToAbsent || inviteRejectedAt != null) { + map['invite_rejected_at'] = Variable(inviteRejectedAt); + } + map['invited'] = Variable(invited); + map['banned'] = Variable(banned); + map['shadow_banned'] = Variable(shadowBanned); + if (!nullToAbsent || pinnedAt != null) { + map['pinned_at'] = Variable(pinnedAt); + } + if (!nullToAbsent || archivedAt != null) { + map['archived_at'] = Variable(archivedAt); + } + map['is_moderator'] = Variable(isModerator); if (!nullToAbsent || extraData != null) { - map['extra_data'] = Variable( - $ReactionsTable.$converterextraDatan.toSql(extraData)); + map['extra_data'] = + Variable($MembersTable.$converterextraDatan.toSql(extraData)); } + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); return map; } - factory ReactionEntity.fromJson(Map json, + factory MemberEntity.fromJson(Map json, {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; - return ReactionEntity( + return MemberEntity( userId: serializer.fromJson(json['userId']), - messageId: serializer.fromJson(json['messageId']), - type: serializer.fromJson(json['type']), - createdAt: serializer.fromJson(json['createdAt']), - score: serializer.fromJson(json['score']), + channelCid: serializer.fromJson(json['channelCid']), + channelRole: serializer.fromJson(json['channelRole']), + inviteAcceptedAt: + serializer.fromJson(json['inviteAcceptedAt']), + inviteRejectedAt: + serializer.fromJson(json['inviteRejectedAt']), + invited: serializer.fromJson(json['invited']), + banned: serializer.fromJson(json['banned']), + shadowBanned: serializer.fromJson(json['shadowBanned']), + pinnedAt: serializer.fromJson(json['pinnedAt']), + archivedAt: serializer.fromJson(json['archivedAt']), + isModerator: serializer.fromJson(json['isModerator']), extraData: serializer.fromJson?>(json['extraData']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), ); } @override @@ -5950,131 +7493,261 @@ class ReactionEntity extends DataClass implements Insertable { serializer ??= driftRuntimeOptions.defaultSerializer; return { 'userId': serializer.toJson(userId), - 'messageId': serializer.toJson(messageId), - 'type': serializer.toJson(type), - 'createdAt': serializer.toJson(createdAt), - 'score': serializer.toJson(score), + 'channelCid': serializer.toJson(channelCid), + 'channelRole': serializer.toJson(channelRole), + 'inviteAcceptedAt': serializer.toJson(inviteAcceptedAt), + 'inviteRejectedAt': serializer.toJson(inviteRejectedAt), + 'invited': serializer.toJson(invited), + 'banned': serializer.toJson(banned), + 'shadowBanned': serializer.toJson(shadowBanned), + 'pinnedAt': serializer.toJson(pinnedAt), + 'archivedAt': serializer.toJson(archivedAt), + 'isModerator': serializer.toJson(isModerator), 'extraData': serializer.toJson?>(extraData), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), }; } - ReactionEntity copyWith( + MemberEntity copyWith( {String? userId, - String? messageId, - String? type, + String? channelCid, + Value channelRole = const Value.absent(), + Value inviteAcceptedAt = const Value.absent(), + Value inviteRejectedAt = const Value.absent(), + bool? invited, + bool? banned, + bool? shadowBanned, + Value pinnedAt = const Value.absent(), + Value archivedAt = const Value.absent(), + bool? isModerator, + Value?> extraData = const Value.absent(), DateTime? createdAt, - int? score, - Value?> extraData = const Value.absent()}) => - ReactionEntity( + DateTime? updatedAt}) => + MemberEntity( userId: userId ?? this.userId, - messageId: messageId ?? this.messageId, - type: type ?? this.type, - createdAt: createdAt ?? this.createdAt, - score: score ?? this.score, + channelCid: channelCid ?? this.channelCid, + channelRole: channelRole.present ? channelRole.value : this.channelRole, + inviteAcceptedAt: inviteAcceptedAt.present + ? inviteAcceptedAt.value + : this.inviteAcceptedAt, + inviteRejectedAt: inviteRejectedAt.present + ? inviteRejectedAt.value + : this.inviteRejectedAt, + invited: invited ?? this.invited, + banned: banned ?? this.banned, + shadowBanned: shadowBanned ?? this.shadowBanned, + pinnedAt: pinnedAt.present ? pinnedAt.value : this.pinnedAt, + archivedAt: archivedAt.present ? archivedAt.value : this.archivedAt, + isModerator: isModerator ?? this.isModerator, extraData: extraData.present ? extraData.value : this.extraData, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, ); - ReactionEntity copyWithCompanion(ReactionsCompanion data) { - return ReactionEntity( + MemberEntity copyWithCompanion(MembersCompanion data) { + return MemberEntity( userId: data.userId.present ? data.userId.value : this.userId, - messageId: data.messageId.present ? data.messageId.value : this.messageId, - type: data.type.present ? data.type.value : this.type, - createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, - score: data.score.present ? data.score.value : this.score, + channelCid: + data.channelCid.present ? data.channelCid.value : this.channelCid, + channelRole: + data.channelRole.present ? data.channelRole.value : this.channelRole, + inviteAcceptedAt: data.inviteAcceptedAt.present + ? data.inviteAcceptedAt.value + : this.inviteAcceptedAt, + inviteRejectedAt: data.inviteRejectedAt.present + ? data.inviteRejectedAt.value + : this.inviteRejectedAt, + invited: data.invited.present ? data.invited.value : this.invited, + banned: data.banned.present ? data.banned.value : this.banned, + shadowBanned: data.shadowBanned.present + ? data.shadowBanned.value + : this.shadowBanned, + pinnedAt: data.pinnedAt.present ? data.pinnedAt.value : this.pinnedAt, + archivedAt: + data.archivedAt.present ? data.archivedAt.value : this.archivedAt, + isModerator: + data.isModerator.present ? data.isModerator.value : this.isModerator, extraData: data.extraData.present ? data.extraData.value : this.extraData, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, ); } @override String toString() { - return (StringBuffer('ReactionEntity(') + return (StringBuffer('MemberEntity(') ..write('userId: $userId, ') - ..write('messageId: $messageId, ') - ..write('type: $type, ') + ..write('channelCid: $channelCid, ') + ..write('channelRole: $channelRole, ') + ..write('inviteAcceptedAt: $inviteAcceptedAt, ') + ..write('inviteRejectedAt: $inviteRejectedAt, ') + ..write('invited: $invited, ') + ..write('banned: $banned, ') + ..write('shadowBanned: $shadowBanned, ') + ..write('pinnedAt: $pinnedAt, ') + ..write('archivedAt: $archivedAt, ') + ..write('isModerator: $isModerator, ') + ..write('extraData: $extraData, ') ..write('createdAt: $createdAt, ') - ..write('score: $score, ') - ..write('extraData: $extraData') + ..write('updatedAt: $updatedAt') ..write(')')) .toString(); } @override - int get hashCode => - Object.hash(userId, messageId, type, createdAt, score, extraData); + int get hashCode => Object.hash( + userId, + channelCid, + channelRole, + inviteAcceptedAt, + inviteRejectedAt, + invited, + banned, + shadowBanned, + pinnedAt, + archivedAt, + isModerator, + extraData, + createdAt, + updatedAt); @override bool operator ==(Object other) => identical(this, other) || - (other is ReactionEntity && + (other is MemberEntity && other.userId == this.userId && - other.messageId == this.messageId && - other.type == this.type && + other.channelCid == this.channelCid && + other.channelRole == this.channelRole && + other.inviteAcceptedAt == this.inviteAcceptedAt && + other.inviteRejectedAt == this.inviteRejectedAt && + other.invited == this.invited && + other.banned == this.banned && + other.shadowBanned == this.shadowBanned && + other.pinnedAt == this.pinnedAt && + other.archivedAt == this.archivedAt && + other.isModerator == this.isModerator && + other.extraData == this.extraData && other.createdAt == this.createdAt && - other.score == this.score && - other.extraData == this.extraData); + other.updatedAt == this.updatedAt); } -class ReactionsCompanion extends UpdateCompanion { +class MembersCompanion extends UpdateCompanion { final Value userId; - final Value messageId; - final Value type; - final Value createdAt; - final Value score; + final Value channelCid; + final Value channelRole; + final Value inviteAcceptedAt; + final Value inviteRejectedAt; + final Value invited; + final Value banned; + final Value shadowBanned; + final Value pinnedAt; + final Value archivedAt; + final Value isModerator; final Value?> extraData; + final Value createdAt; + final Value updatedAt; final Value rowid; - const ReactionsCompanion({ + const MembersCompanion({ this.userId = const Value.absent(), - this.messageId = const Value.absent(), - this.type = const Value.absent(), - this.createdAt = const Value.absent(), - this.score = const Value.absent(), + this.channelCid = const Value.absent(), + this.channelRole = const Value.absent(), + this.inviteAcceptedAt = const Value.absent(), + this.inviteRejectedAt = const Value.absent(), + this.invited = const Value.absent(), + this.banned = const Value.absent(), + this.shadowBanned = const Value.absent(), + this.pinnedAt = const Value.absent(), + this.archivedAt = const Value.absent(), + this.isModerator = const Value.absent(), this.extraData = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.rowid = const Value.absent(), }); - ReactionsCompanion.insert({ + MembersCompanion.insert({ required String userId, - required String messageId, - required String type, - this.createdAt = const Value.absent(), - this.score = const Value.absent(), + required String channelCid, + this.channelRole = const Value.absent(), + this.inviteAcceptedAt = const Value.absent(), + this.inviteRejectedAt = const Value.absent(), + this.invited = const Value.absent(), + this.banned = const Value.absent(), + this.shadowBanned = const Value.absent(), + this.pinnedAt = const Value.absent(), + this.archivedAt = const Value.absent(), + this.isModerator = const Value.absent(), this.extraData = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.rowid = const Value.absent(), }) : userId = Value(userId), - messageId = Value(messageId), - type = Value(type); - static Insertable custom({ + channelCid = Value(channelCid); + static Insertable custom({ Expression? userId, - Expression? messageId, - Expression? type, - Expression? createdAt, - Expression? score, + Expression? channelCid, + Expression? channelRole, + Expression? inviteAcceptedAt, + Expression? inviteRejectedAt, + Expression? invited, + Expression? banned, + Expression? shadowBanned, + Expression? pinnedAt, + Expression? archivedAt, + Expression? isModerator, Expression? extraData, + Expression? createdAt, + Expression? updatedAt, Expression? rowid, }) { return RawValuesInsertable({ if (userId != null) 'user_id': userId, - if (messageId != null) 'message_id': messageId, - if (type != null) 'type': type, - if (createdAt != null) 'created_at': createdAt, - if (score != null) 'score': score, + if (channelCid != null) 'channel_cid': channelCid, + if (channelRole != null) 'channel_role': channelRole, + if (inviteAcceptedAt != null) 'invite_accepted_at': inviteAcceptedAt, + if (inviteRejectedAt != null) 'invite_rejected_at': inviteRejectedAt, + if (invited != null) 'invited': invited, + if (banned != null) 'banned': banned, + if (shadowBanned != null) 'shadow_banned': shadowBanned, + if (pinnedAt != null) 'pinned_at': pinnedAt, + if (archivedAt != null) 'archived_at': archivedAt, + if (isModerator != null) 'is_moderator': isModerator, if (extraData != null) 'extra_data': extraData, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, if (rowid != null) 'rowid': rowid, }); } - ReactionsCompanion copyWith( + MembersCompanion copyWith( {Value? userId, - Value? messageId, - Value? type, - Value? createdAt, - Value? score, + Value? channelCid, + Value? channelRole, + Value? inviteAcceptedAt, + Value? inviteRejectedAt, + Value? invited, + Value? banned, + Value? shadowBanned, + Value? pinnedAt, + Value? archivedAt, + Value? isModerator, Value?>? extraData, + Value? createdAt, + Value? updatedAt, Value? rowid}) { - return ReactionsCompanion( + return MembersCompanion( userId: userId ?? this.userId, - messageId: messageId ?? this.messageId, - type: type ?? this.type, - createdAt: createdAt ?? this.createdAt, - score: score ?? this.score, + channelCid: channelCid ?? this.channelCid, + channelRole: channelRole ?? this.channelRole, + inviteAcceptedAt: inviteAcceptedAt ?? this.inviteAcceptedAt, + inviteRejectedAt: inviteRejectedAt ?? this.inviteRejectedAt, + invited: invited ?? this.invited, + banned: banned ?? this.banned, + shadowBanned: shadowBanned ?? this.shadowBanned, + pinnedAt: pinnedAt ?? this.pinnedAt, + archivedAt: archivedAt ?? this.archivedAt, + isModerator: isModerator ?? this.isModerator, extraData: extraData ?? this.extraData, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, rowid: rowid ?? this.rowid, ); } @@ -6085,21 +7758,45 @@ class ReactionsCompanion extends UpdateCompanion { if (userId.present) { map['user_id'] = Variable(userId.value); } - if (messageId.present) { - map['message_id'] = Variable(messageId.value); + if (channelCid.present) { + map['channel_cid'] = Variable(channelCid.value); } - if (type.present) { - map['type'] = Variable(type.value); + if (channelRole.present) { + map['channel_role'] = Variable(channelRole.value); } - if (createdAt.present) { - map['created_at'] = Variable(createdAt.value); + if (inviteAcceptedAt.present) { + map['invite_accepted_at'] = Variable(inviteAcceptedAt.value); } - if (score.present) { - map['score'] = Variable(score.value); + if (inviteRejectedAt.present) { + map['invite_rejected_at'] = Variable(inviteRejectedAt.value); + } + if (invited.present) { + map['invited'] = Variable(invited.value); + } + if (banned.present) { + map['banned'] = Variable(banned.value); + } + if (shadowBanned.present) { + map['shadow_banned'] = Variable(shadowBanned.value); + } + if (pinnedAt.present) { + map['pinned_at'] = Variable(pinnedAt.value); + } + if (archivedAt.present) { + map['archived_at'] = Variable(archivedAt.value); + } + if (isModerator.present) { + map['is_moderator'] = Variable(isModerator.value); } if (extraData.present) { map['extra_data'] = Variable( - $ReactionsTable.$converterextraDatan.toSql(extraData.value)); + $MembersTable.$converterextraDatan.toSql(extraData.value)); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); } if (rowid.present) { map['rowid'] = Variable(rowid.value); @@ -6109,503 +7806,330 @@ class ReactionsCompanion extends UpdateCompanion { @override String toString() { - return (StringBuffer('ReactionsCompanion(') + return (StringBuffer('MembersCompanion(') ..write('userId: $userId, ') - ..write('messageId: $messageId, ') - ..write('type: $type, ') - ..write('createdAt: $createdAt, ') - ..write('score: $score, ') + ..write('channelCid: $channelCid, ') + ..write('channelRole: $channelRole, ') + ..write('inviteAcceptedAt: $inviteAcceptedAt, ') + ..write('inviteRejectedAt: $inviteRejectedAt, ') + ..write('invited: $invited, ') + ..write('banned: $banned, ') + ..write('shadowBanned: $shadowBanned, ') + ..write('pinnedAt: $pinnedAt, ') + ..write('archivedAt: $archivedAt, ') + ..write('isModerator: $isModerator, ') ..write('extraData: $extraData, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') ..write('rowid: $rowid') ..write(')')) .toString(); } } -class $UsersTable extends Users with TableInfo<$UsersTable, UserEntity> { +class $ReadsTable extends Reads with TableInfo<$ReadsTable, ReadEntity> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $UsersTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _roleMeta = const VerificationMeta('role'); - @override - late final GeneratedColumn role = GeneratedColumn( - 'role', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _languageMeta = - const VerificationMeta('language'); - @override - late final GeneratedColumn language = GeneratedColumn( - 'language', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _createdAtMeta = - const VerificationMeta('createdAt'); - @override - late final GeneratedColumn createdAt = GeneratedColumn( - 'created_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _updatedAtMeta = - const VerificationMeta('updatedAt'); + $ReadsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _lastReadMeta = + const VerificationMeta('lastRead'); @override - late final GeneratedColumn updatedAt = GeneratedColumn( - 'updated_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _lastActiveMeta = - const VerificationMeta('lastActive'); + late final GeneratedColumn lastRead = GeneratedColumn( + 'last_read', aliasedName, false, + type: DriftSqlType.dateTime, requiredDuringInsert: true); + static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override - late final GeneratedColumn lastActive = GeneratedColumn( - 'last_active', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _onlineMeta = const VerificationMeta('online'); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _channelCidMeta = + const VerificationMeta('channelCid'); @override - late final GeneratedColumn online = GeneratedColumn( - 'online', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('CHECK ("online" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _bannedMeta = const VerificationMeta('banned'); + late final GeneratedColumn channelCid = GeneratedColumn( + 'channel_cid', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES channels (cid) ON DELETE CASCADE')); + static const VerificationMeta _unreadMessagesMeta = + const VerificationMeta('unreadMessages'); @override - late final GeneratedColumn banned = GeneratedColumn( - 'banned', aliasedName, false, - type: DriftSqlType.bool, + late final GeneratedColumn unreadMessages = GeneratedColumn( + 'unread_messages', aliasedName, false, + type: DriftSqlType.int, requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('CHECK ("banned" IN (0, 1))'), - defaultValue: const Constant(false)); - @override - late final GeneratedColumnWithTypeConverter?, String> - teamsRole = GeneratedColumn('teams_role', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $UsersTable.$converterteamsRolen); + defaultValue: const Constant(0)); + static const VerificationMeta _lastReadMessageIdMeta = + const VerificationMeta('lastReadMessageId'); @override - late final GeneratedColumnWithTypeConverter, String> - extraData = GeneratedColumn('extra_data', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true) - .withConverter>($UsersTable.$converterextraData); + late final GeneratedColumn lastReadMessageId = + GeneratedColumn('last_read_message_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); @override - List get $columns => [ - id, - role, - language, - createdAt, - updatedAt, - lastActive, - online, - banned, - teamsRole, - extraData - ]; + List get $columns => + [lastRead, userId, channelCid, unreadMessages, lastReadMessageId]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'users'; + static const String $name = 'reads'; @override - VerificationContext validateIntegrity(Insertable instance, + VerificationContext validateIntegrity(Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + if (data.containsKey('last_read')) { + context.handle(_lastReadMeta, + lastRead.isAcceptableOrUnknown(data['last_read']!, _lastReadMeta)); } else if (isInserting) { - context.missing(_idMeta); - } - if (data.containsKey('role')) { - context.handle( - _roleMeta, role.isAcceptableOrUnknown(data['role']!, _roleMeta)); - } - if (data.containsKey('language')) { - context.handle(_languageMeta, - language.isAcceptableOrUnknown(data['language']!, _languageMeta)); - } - if (data.containsKey('created_at')) { - context.handle(_createdAtMeta, - createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); + context.missing(_lastReadMeta); } - if (data.containsKey('updated_at')) { - context.handle(_updatedAtMeta, - updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + if (data.containsKey('user_id')) { + context.handle(_userIdMeta, + userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); + } else if (isInserting) { + context.missing(_userIdMeta); } - if (data.containsKey('last_active')) { + if (data.containsKey('channel_cid')) { context.handle( - _lastActiveMeta, - lastActive.isAcceptableOrUnknown( - data['last_active']!, _lastActiveMeta)); + _channelCidMeta, + channelCid.isAcceptableOrUnknown( + data['channel_cid']!, _channelCidMeta)); + } else if (isInserting) { + context.missing(_channelCidMeta); } - if (data.containsKey('online')) { - context.handle(_onlineMeta, - online.isAcceptableOrUnknown(data['online']!, _onlineMeta)); + if (data.containsKey('unread_messages')) { + context.handle( + _unreadMessagesMeta, + unreadMessages.isAcceptableOrUnknown( + data['unread_messages']!, _unreadMessagesMeta)); } - if (data.containsKey('banned')) { - context.handle(_bannedMeta, - banned.isAcceptableOrUnknown(data['banned']!, _bannedMeta)); + if (data.containsKey('last_read_message_id')) { + context.handle( + _lastReadMessageIdMeta, + lastReadMessageId.isAcceptableOrUnknown( + data['last_read_message_id']!, _lastReadMessageIdMeta)); } return context; } @override - Set get $primaryKey => {id}; + Set get $primaryKey => {userId, channelCid}; @override - UserEntity map(Map data, {String? tablePrefix}) { + ReadEntity map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return UserEntity( - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - role: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}role']), - language: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}language']), - createdAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at']), - updatedAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at']), - lastActive: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}last_active']), - online: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}online'])!, - banned: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}banned'])!, - teamsRole: $UsersTable.$converterteamsRolen.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}teams_role'])), - extraData: $UsersTable.$converterextraData.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])!), + return ReadEntity( + lastRead: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}last_read'])!, + userId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, + channelCid: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}channel_cid'])!, + unreadMessages: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}unread_messages'])!, + lastReadMessageId: attachedDatabase.typeMapping.read( + DriftSqlType.string, data['${effectivePrefix}last_read_message_id']), ); } @override - $UsersTable createAlias(String alias) { - return $UsersTable(attachedDatabase, alias); + $ReadsTable createAlias(String alias) { + return $ReadsTable(attachedDatabase, alias); } - - static TypeConverter, String> $converterteamsRole = - MapConverter(); - static TypeConverter?, String?> $converterteamsRolen = - NullAwareTypeConverter.wrap($converterteamsRole); - static TypeConverter, String> $converterextraData = - MapConverter(); } -class UserEntity extends DataClass implements Insertable { - /// User id - final String id; - - /// User role - final String? role; - - /// The language this user prefers. - final String? language; - - /// Date of user creation - final DateTime? createdAt; - - /// Date of last user update - final DateTime? updatedAt; - - /// Date of last user connection - final DateTime? lastActive; +class ReadEntity extends DataClass implements Insertable { + /// Date of the read event + final DateTime lastRead; - /// True if user is online - final bool online; + /// Id of the User who sent the event + final String userId; - /// True if user is banned from the chat - final bool banned; + /// The channel cid of which this read belongs + final String channelCid; - /// The roles for the user in the teams. - /// - /// eg: `{'teamId': 'role', 'teamId2': 'role2'}` - final Map? teamsRole; + /// Number of unread messages + final int unreadMessages; - /// Map of custom user extraData - final Map extraData; - const UserEntity( - {required this.id, - this.role, - this.language, - this.createdAt, - this.updatedAt, - this.lastActive, - required this.online, - required this.banned, - this.teamsRole, - required this.extraData}); + /// Id of the last read message + final String? lastReadMessageId; + const ReadEntity( + {required this.lastRead, + required this.userId, + required this.channelCid, + required this.unreadMessages, + this.lastReadMessageId}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id); - if (!nullToAbsent || role != null) { - map['role'] = Variable(role); - } - if (!nullToAbsent || language != null) { - map['language'] = Variable(language); - } - if (!nullToAbsent || createdAt != null) { - map['created_at'] = Variable(createdAt); - } - if (!nullToAbsent || updatedAt != null) { - map['updated_at'] = Variable(updatedAt); - } - if (!nullToAbsent || lastActive != null) { - map['last_active'] = Variable(lastActive); - } - map['online'] = Variable(online); - map['banned'] = Variable(banned); - if (!nullToAbsent || teamsRole != null) { - map['teams_role'] = - Variable($UsersTable.$converterteamsRolen.toSql(teamsRole)); - } - { - map['extra_data'] = - Variable($UsersTable.$converterextraData.toSql(extraData)); + map['last_read'] = Variable(lastRead); + map['user_id'] = Variable(userId); + map['channel_cid'] = Variable(channelCid); + map['unread_messages'] = Variable(unreadMessages); + if (!nullToAbsent || lastReadMessageId != null) { + map['last_read_message_id'] = Variable(lastReadMessageId); } return map; } - factory UserEntity.fromJson(Map json, + factory ReadEntity.fromJson(Map json, {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; - return UserEntity( - id: serializer.fromJson(json['id']), - role: serializer.fromJson(json['role']), - language: serializer.fromJson(json['language']), - createdAt: serializer.fromJson(json['createdAt']), - updatedAt: serializer.fromJson(json['updatedAt']), - lastActive: serializer.fromJson(json['lastActive']), - online: serializer.fromJson(json['online']), - banned: serializer.fromJson(json['banned']), - teamsRole: serializer.fromJson?>(json['teamsRole']), - extraData: serializer.fromJson>(json['extraData']), + return ReadEntity( + lastRead: serializer.fromJson(json['lastRead']), + userId: serializer.fromJson(json['userId']), + channelCid: serializer.fromJson(json['channelCid']), + unreadMessages: serializer.fromJson(json['unreadMessages']), + lastReadMessageId: + serializer.fromJson(json['lastReadMessageId']), ); } @override Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'id': serializer.toJson(id), - 'role': serializer.toJson(role), - 'language': serializer.toJson(language), - 'createdAt': serializer.toJson(createdAt), - 'updatedAt': serializer.toJson(updatedAt), - 'lastActive': serializer.toJson(lastActive), - 'online': serializer.toJson(online), - 'banned': serializer.toJson(banned), - 'teamsRole': serializer.toJson?>(teamsRole), - 'extraData': serializer.toJson>(extraData), + 'lastRead': serializer.toJson(lastRead), + 'userId': serializer.toJson(userId), + 'channelCid': serializer.toJson(channelCid), + 'unreadMessages': serializer.toJson(unreadMessages), + 'lastReadMessageId': serializer.toJson(lastReadMessageId), }; } - UserEntity copyWith( - {String? id, - Value role = const Value.absent(), - Value language = const Value.absent(), - Value createdAt = const Value.absent(), - Value updatedAt = const Value.absent(), - Value lastActive = const Value.absent(), - bool? online, - bool? banned, - Value?> teamsRole = const Value.absent(), - Map? extraData}) => - UserEntity( - id: id ?? this.id, - role: role.present ? role.value : this.role, - language: language.present ? language.value : this.language, - createdAt: createdAt.present ? createdAt.value : this.createdAt, - updatedAt: updatedAt.present ? updatedAt.value : this.updatedAt, - lastActive: lastActive.present ? lastActive.value : this.lastActive, - online: online ?? this.online, - banned: banned ?? this.banned, - teamsRole: teamsRole.present ? teamsRole.value : this.teamsRole, - extraData: extraData ?? this.extraData, + ReadEntity copyWith( + {DateTime? lastRead, + String? userId, + String? channelCid, + int? unreadMessages, + Value lastReadMessageId = const Value.absent()}) => + ReadEntity( + lastRead: lastRead ?? this.lastRead, + userId: userId ?? this.userId, + channelCid: channelCid ?? this.channelCid, + unreadMessages: unreadMessages ?? this.unreadMessages, + lastReadMessageId: lastReadMessageId.present + ? lastReadMessageId.value + : this.lastReadMessageId, ); - UserEntity copyWithCompanion(UsersCompanion data) { - return UserEntity( - id: data.id.present ? data.id.value : this.id, - role: data.role.present ? data.role.value : this.role, - language: data.language.present ? data.language.value : this.language, - createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, - updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, - lastActive: - data.lastActive.present ? data.lastActive.value : this.lastActive, - online: data.online.present ? data.online.value : this.online, - banned: data.banned.present ? data.banned.value : this.banned, - teamsRole: data.teamsRole.present ? data.teamsRole.value : this.teamsRole, - extraData: data.extraData.present ? data.extraData.value : this.extraData, + ReadEntity copyWithCompanion(ReadsCompanion data) { + return ReadEntity( + lastRead: data.lastRead.present ? data.lastRead.value : this.lastRead, + userId: data.userId.present ? data.userId.value : this.userId, + channelCid: + data.channelCid.present ? data.channelCid.value : this.channelCid, + unreadMessages: data.unreadMessages.present + ? data.unreadMessages.value + : this.unreadMessages, + lastReadMessageId: data.lastReadMessageId.present + ? data.lastReadMessageId.value + : this.lastReadMessageId, ); } @override String toString() { - return (StringBuffer('UserEntity(') - ..write('id: $id, ') - ..write('role: $role, ') - ..write('language: $language, ') - ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt, ') - ..write('lastActive: $lastActive, ') - ..write('online: $online, ') - ..write('banned: $banned, ') - ..write('teamsRole: $teamsRole, ') - ..write('extraData: $extraData') + return (StringBuffer('ReadEntity(') + ..write('lastRead: $lastRead, ') + ..write('userId: $userId, ') + ..write('channelCid: $channelCid, ') + ..write('unreadMessages: $unreadMessages, ') + ..write('lastReadMessageId: $lastReadMessageId') ..write(')')) .toString(); } @override - int get hashCode => Object.hash(id, role, language, createdAt, updatedAt, - lastActive, online, banned, teamsRole, extraData); + int get hashCode => Object.hash( + lastRead, userId, channelCid, unreadMessages, lastReadMessageId); @override bool operator ==(Object other) => identical(this, other) || - (other is UserEntity && - other.id == this.id && - other.role == this.role && - other.language == this.language && - other.createdAt == this.createdAt && - other.updatedAt == this.updatedAt && - other.lastActive == this.lastActive && - other.online == this.online && - other.banned == this.banned && - other.teamsRole == this.teamsRole && - other.extraData == this.extraData); + (other is ReadEntity && + other.lastRead == this.lastRead && + other.userId == this.userId && + other.channelCid == this.channelCid && + other.unreadMessages == this.unreadMessages && + other.lastReadMessageId == this.lastReadMessageId); } -class UsersCompanion extends UpdateCompanion { - final Value id; - final Value role; - final Value language; - final Value createdAt; - final Value updatedAt; - final Value lastActive; - final Value online; - final Value banned; - final Value?> teamsRole; - final Value> extraData; +class ReadsCompanion extends UpdateCompanion { + final Value lastRead; + final Value userId; + final Value channelCid; + final Value unreadMessages; + final Value lastReadMessageId; final Value rowid; - const UsersCompanion({ - this.id = const Value.absent(), - this.role = const Value.absent(), - this.language = const Value.absent(), - this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), - this.lastActive = const Value.absent(), - this.online = const Value.absent(), - this.banned = const Value.absent(), - this.teamsRole = const Value.absent(), - this.extraData = const Value.absent(), + const ReadsCompanion({ + this.lastRead = const Value.absent(), + this.userId = const Value.absent(), + this.channelCid = const Value.absent(), + this.unreadMessages = const Value.absent(), + this.lastReadMessageId = const Value.absent(), this.rowid = const Value.absent(), }); - UsersCompanion.insert({ - required String id, - this.role = const Value.absent(), - this.language = const Value.absent(), - this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), - this.lastActive = const Value.absent(), - this.online = const Value.absent(), - this.banned = const Value.absent(), - this.teamsRole = const Value.absent(), - required Map extraData, + ReadsCompanion.insert({ + required DateTime lastRead, + required String userId, + required String channelCid, + this.unreadMessages = const Value.absent(), + this.lastReadMessageId = const Value.absent(), this.rowid = const Value.absent(), - }) : id = Value(id), - extraData = Value(extraData); - static Insertable custom({ - Expression? id, - Expression? role, - Expression? language, - Expression? createdAt, - Expression? updatedAt, - Expression? lastActive, - Expression? online, - Expression? banned, - Expression? teamsRole, - Expression? extraData, + }) : lastRead = Value(lastRead), + userId = Value(userId), + channelCid = Value(channelCid); + static Insertable custom({ + Expression? lastRead, + Expression? userId, + Expression? channelCid, + Expression? unreadMessages, + Expression? lastReadMessageId, Expression? rowid, }) { return RawValuesInsertable({ - if (id != null) 'id': id, - if (role != null) 'role': role, - if (language != null) 'language': language, - if (createdAt != null) 'created_at': createdAt, - if (updatedAt != null) 'updated_at': updatedAt, - if (lastActive != null) 'last_active': lastActive, - if (online != null) 'online': online, - if (banned != null) 'banned': banned, - if (teamsRole != null) 'teams_role': teamsRole, - if (extraData != null) 'extra_data': extraData, + if (lastRead != null) 'last_read': lastRead, + if (userId != null) 'user_id': userId, + if (channelCid != null) 'channel_cid': channelCid, + if (unreadMessages != null) 'unread_messages': unreadMessages, + if (lastReadMessageId != null) 'last_read_message_id': lastReadMessageId, if (rowid != null) 'rowid': rowid, }); } - UsersCompanion copyWith( - {Value? id, - Value? role, - Value? language, - Value? createdAt, - Value? updatedAt, - Value? lastActive, - Value? online, - Value? banned, - Value?>? teamsRole, - Value>? extraData, + ReadsCompanion copyWith( + {Value? lastRead, + Value? userId, + Value? channelCid, + Value? unreadMessages, + Value? lastReadMessageId, Value? rowid}) { - return UsersCompanion( - id: id ?? this.id, - role: role ?? this.role, - language: language ?? this.language, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, - lastActive: lastActive ?? this.lastActive, - online: online ?? this.online, - banned: banned ?? this.banned, - teamsRole: teamsRole ?? this.teamsRole, - extraData: extraData ?? this.extraData, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (role.present) { - map['role'] = Variable(role.value); - } - if (language.present) { - map['language'] = Variable(language.value); - } - if (createdAt.present) { - map['created_at'] = Variable(createdAt.value); - } - if (updatedAt.present) { - map['updated_at'] = Variable(updatedAt.value); - } - if (lastActive.present) { - map['last_active'] = Variable(lastActive.value); + return ReadsCompanion( + lastRead: lastRead ?? this.lastRead, + userId: userId ?? this.userId, + channelCid: channelCid ?? this.channelCid, + unreadMessages: unreadMessages ?? this.unreadMessages, + lastReadMessageId: lastReadMessageId ?? this.lastReadMessageId, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (lastRead.present) { + map['last_read'] = Variable(lastRead.value); } - if (online.present) { - map['online'] = Variable(online.value); + if (userId.present) { + map['user_id'] = Variable(userId.value); } - if (banned.present) { - map['banned'] = Variable(banned.value); + if (channelCid.present) { + map['channel_cid'] = Variable(channelCid.value); } - if (teamsRole.present) { - map['teams_role'] = Variable( - $UsersTable.$converterteamsRolen.toSql(teamsRole.value)); + if (unreadMessages.present) { + map['unread_messages'] = Variable(unreadMessages.value); } - if (extraData.present) { - map['extra_data'] = Variable( - $UsersTable.$converterextraData.toSql(extraData.value)); + if (lastReadMessageId.present) { + map['last_read_message_id'] = Variable(lastReadMessageId.value); } if (rowid.present) { map['rowid'] = Variable(rowid.value); @@ -6615,659 +8139,183 @@ class UsersCompanion extends UpdateCompanion { @override String toString() { - return (StringBuffer('UsersCompanion(') - ..write('id: $id, ') - ..write('role: $role, ') - ..write('language: $language, ') - ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt, ') - ..write('lastActive: $lastActive, ') - ..write('online: $online, ') - ..write('banned: $banned, ') - ..write('teamsRole: $teamsRole, ') - ..write('extraData: $extraData, ') + return (StringBuffer('ReadsCompanion(') + ..write('lastRead: $lastRead, ') + ..write('userId: $userId, ') + ..write('channelCid: $channelCid, ') + ..write('unreadMessages: $unreadMessages, ') + ..write('lastReadMessageId: $lastReadMessageId, ') ..write('rowid: $rowid') ..write(')')) .toString(); } } -class $MembersTable extends Members - with TableInfo<$MembersTable, MemberEntity> { +class $ChannelQueriesTable extends ChannelQueries + with TableInfo<$ChannelQueriesTable, ChannelQueryEntity> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $MembersTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + $ChannelQueriesTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _queryHashMeta = + const VerificationMeta('queryHash'); @override - late final GeneratedColumn userId = GeneratedColumn( - 'user_id', aliasedName, false, + late final GeneratedColumn queryHash = GeneratedColumn( + 'query_hash', aliasedName, false, type: DriftSqlType.string, requiredDuringInsert: true); static const VerificationMeta _channelCidMeta = const VerificationMeta('channelCid'); @override late final GeneratedColumn channelCid = GeneratedColumn( 'channel_cid', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'REFERENCES channels (cid) ON DELETE CASCADE')); - static const VerificationMeta _channelRoleMeta = - const VerificationMeta('channelRole'); - @override - late final GeneratedColumn channelRole = GeneratedColumn( - 'channel_role', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); - static const VerificationMeta _inviteAcceptedAtMeta = - const VerificationMeta('inviteAcceptedAt'); - @override - late final GeneratedColumn inviteAcceptedAt = - GeneratedColumn('invite_accepted_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _inviteRejectedAtMeta = - const VerificationMeta('inviteRejectedAt'); - @override - late final GeneratedColumn inviteRejectedAt = - GeneratedColumn('invite_rejected_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _invitedMeta = - const VerificationMeta('invited'); - @override - late final GeneratedColumn invited = GeneratedColumn( - 'invited', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('CHECK ("invited" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _bannedMeta = const VerificationMeta('banned'); - @override - late final GeneratedColumn banned = GeneratedColumn( - 'banned', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('CHECK ("banned" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _shadowBannedMeta = - const VerificationMeta('shadowBanned'); - @override - late final GeneratedColumn shadowBanned = GeneratedColumn( - 'shadow_banned', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'CHECK ("shadow_banned" IN (0, 1))'), - defaultValue: const Constant(false)); - static const VerificationMeta _pinnedAtMeta = - const VerificationMeta('pinnedAt'); - @override - late final GeneratedColumn pinnedAt = GeneratedColumn( - 'pinned_at', aliasedName, true, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - defaultValue: const Constant(null)); - static const VerificationMeta _archivedAtMeta = - const VerificationMeta('archivedAt'); - @override - late final GeneratedColumn archivedAt = GeneratedColumn( - 'archived_at', aliasedName, true, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - defaultValue: const Constant(null)); - static const VerificationMeta _isModeratorMeta = - const VerificationMeta('isModerator'); - @override - late final GeneratedColumn isModerator = GeneratedColumn( - 'is_moderator', aliasedName, false, - type: DriftSqlType.bool, - requiredDuringInsert: false, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'CHECK ("is_moderator" IN (0, 1))'), - defaultValue: const Constant(false)); - @override - late final GeneratedColumnWithTypeConverter?, String> - extraData = GeneratedColumn('extra_data', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $MembersTable.$converterextraDatan); - static const VerificationMeta _createdAtMeta = - const VerificationMeta('createdAt'); - @override - late final GeneratedColumn createdAt = GeneratedColumn( - 'created_at', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - defaultValue: currentDateAndTime); - static const VerificationMeta _updatedAtMeta = - const VerificationMeta('updatedAt'); - @override - late final GeneratedColumn updatedAt = GeneratedColumn( - 'updated_at', aliasedName, false, - type: DriftSqlType.dateTime, - requiredDuringInsert: false, - defaultValue: currentDateAndTime); + type: DriftSqlType.string, requiredDuringInsert: true); @override - List get $columns => [ - userId, - channelCid, - channelRole, - inviteAcceptedAt, - inviteRejectedAt, - invited, - banned, - shadowBanned, - pinnedAt, - archivedAt, - isModerator, - extraData, - createdAt, - updatedAt - ]; + List get $columns => [queryHash, channelCid]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'members'; + static const String $name = 'channel_queries'; @override - VerificationContext validateIntegrity(Insertable instance, + VerificationContext validateIntegrity(Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('user_id')) { - context.handle(_userIdMeta, - userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); - } else if (isInserting) { - context.missing(_userIdMeta); - } - if (data.containsKey('channel_cid')) { - context.handle( - _channelCidMeta, - channelCid.isAcceptableOrUnknown( - data['channel_cid']!, _channelCidMeta)); + if (data.containsKey('query_hash')) { + context.handle(_queryHashMeta, + queryHash.isAcceptableOrUnknown(data['query_hash']!, _queryHashMeta)); } else if (isInserting) { - context.missing(_channelCidMeta); - } - if (data.containsKey('channel_role')) { - context.handle( - _channelRoleMeta, - channelRole.isAcceptableOrUnknown( - data['channel_role']!, _channelRoleMeta)); - } - if (data.containsKey('invite_accepted_at')) { - context.handle( - _inviteAcceptedAtMeta, - inviteAcceptedAt.isAcceptableOrUnknown( - data['invite_accepted_at']!, _inviteAcceptedAtMeta)); - } - if (data.containsKey('invite_rejected_at')) { - context.handle( - _inviteRejectedAtMeta, - inviteRejectedAt.isAcceptableOrUnknown( - data['invite_rejected_at']!, _inviteRejectedAtMeta)); - } - if (data.containsKey('invited')) { - context.handle(_invitedMeta, - invited.isAcceptableOrUnknown(data['invited']!, _invitedMeta)); - } - if (data.containsKey('banned')) { - context.handle(_bannedMeta, - banned.isAcceptableOrUnknown(data['banned']!, _bannedMeta)); - } - if (data.containsKey('shadow_banned')) { - context.handle( - _shadowBannedMeta, - shadowBanned.isAcceptableOrUnknown( - data['shadow_banned']!, _shadowBannedMeta)); - } - if (data.containsKey('pinned_at')) { - context.handle(_pinnedAtMeta, - pinnedAt.isAcceptableOrUnknown(data['pinned_at']!, _pinnedAtMeta)); - } - if (data.containsKey('archived_at')) { - context.handle( - _archivedAtMeta, - archivedAt.isAcceptableOrUnknown( - data['archived_at']!, _archivedAtMeta)); - } - if (data.containsKey('is_moderator')) { - context.handle( - _isModeratorMeta, - isModerator.isAcceptableOrUnknown( - data['is_moderator']!, _isModeratorMeta)); - } - if (data.containsKey('created_at')) { - context.handle(_createdAtMeta, - createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); - } - if (data.containsKey('updated_at')) { - context.handle(_updatedAtMeta, - updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + context.missing(_queryHashMeta); + } + if (data.containsKey('channel_cid')) { + context.handle( + _channelCidMeta, + channelCid.isAcceptableOrUnknown( + data['channel_cid']!, _channelCidMeta)); + } else if (isInserting) { + context.missing(_channelCidMeta); } return context; } @override - Set get $primaryKey => {userId, channelCid}; + Set get $primaryKey => {queryHash, channelCid}; @override - MemberEntity map(Map data, {String? tablePrefix}) { + ChannelQueryEntity map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return MemberEntity( - userId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, + return ChannelQueryEntity( + queryHash: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}query_hash'])!, channelCid: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}channel_cid'])!, - channelRole: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}channel_role']), - inviteAcceptedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}invite_accepted_at']), - inviteRejectedAt: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, data['${effectivePrefix}invite_rejected_at']), - invited: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}invited'])!, - banned: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}banned'])!, - shadowBanned: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}shadow_banned'])!, - pinnedAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}pinned_at']), - archivedAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}archived_at']), - isModerator: attachedDatabase.typeMapping - .read(DriftSqlType.bool, data['${effectivePrefix}is_moderator'])!, - extraData: $MembersTable.$converterextraDatan.fromSql(attachedDatabase - .typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}extra_data'])), - createdAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, - updatedAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, ); } @override - $MembersTable createAlias(String alias) { - return $MembersTable(attachedDatabase, alias); + $ChannelQueriesTable createAlias(String alias) { + return $ChannelQueriesTable(attachedDatabase, alias); } - - static TypeConverter, String> $converterextraData = - MapConverter(); - static TypeConverter?, String?> $converterextraDatan = - NullAwareTypeConverter.wrap($converterextraData); } -class MemberEntity extends DataClass implements Insertable { - /// The interested user id - final String userId; +class ChannelQueryEntity extends DataClass + implements Insertable { + /// The unique hash of this query + final String queryHash; - /// The channel cid of which this user is part of + /// The channel cid of this query final String channelCid; - - /// The role of the user in the channel - final String? channelRole; - - /// The date on which the user accepted the invite to the channel - final DateTime? inviteAcceptedAt; - - /// The date on which the user rejected the invite to the channel - final DateTime? inviteRejectedAt; - - /// True if the user has been invited to the channel - final bool invited; - - /// True if the member is banned from the channel - final bool banned; - - /// True if the member is shadow banned from the channel - final bool shadowBanned; - - /// The date at which the channel was pinned by the member - final DateTime? pinnedAt; - - /// The date at which the channel was archived by the member - final DateTime? archivedAt; - - /// True if the user is a moderator of the channel - final bool isModerator; - - /// Map of custom member extraData - final Map? extraData; - - /// The date of creation - final DateTime createdAt; - - /// The last date of update - final DateTime updatedAt; - const MemberEntity( - {required this.userId, - required this.channelCid, - this.channelRole, - this.inviteAcceptedAt, - this.inviteRejectedAt, - required this.invited, - required this.banned, - required this.shadowBanned, - this.pinnedAt, - this.archivedAt, - required this.isModerator, - this.extraData, - required this.createdAt, - required this.updatedAt}); + const ChannelQueryEntity({required this.queryHash, required this.channelCid}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['user_id'] = Variable(userId); + map['query_hash'] = Variable(queryHash); map['channel_cid'] = Variable(channelCid); - if (!nullToAbsent || channelRole != null) { - map['channel_role'] = Variable(channelRole); - } - if (!nullToAbsent || inviteAcceptedAt != null) { - map['invite_accepted_at'] = Variable(inviteAcceptedAt); - } - if (!nullToAbsent || inviteRejectedAt != null) { - map['invite_rejected_at'] = Variable(inviteRejectedAt); - } - map['invited'] = Variable(invited); - map['banned'] = Variable(banned); - map['shadow_banned'] = Variable(shadowBanned); - if (!nullToAbsent || pinnedAt != null) { - map['pinned_at'] = Variable(pinnedAt); - } - if (!nullToAbsent || archivedAt != null) { - map['archived_at'] = Variable(archivedAt); - } - map['is_moderator'] = Variable(isModerator); - if (!nullToAbsent || extraData != null) { - map['extra_data'] = - Variable($MembersTable.$converterextraDatan.toSql(extraData)); - } - map['created_at'] = Variable(createdAt); - map['updated_at'] = Variable(updatedAt); return map; } - factory MemberEntity.fromJson(Map json, + factory ChannelQueryEntity.fromJson(Map json, {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; - return MemberEntity( - userId: serializer.fromJson(json['userId']), + return ChannelQueryEntity( + queryHash: serializer.fromJson(json['queryHash']), channelCid: serializer.fromJson(json['channelCid']), - channelRole: serializer.fromJson(json['channelRole']), - inviteAcceptedAt: - serializer.fromJson(json['inviteAcceptedAt']), - inviteRejectedAt: - serializer.fromJson(json['inviteRejectedAt']), - invited: serializer.fromJson(json['invited']), - banned: serializer.fromJson(json['banned']), - shadowBanned: serializer.fromJson(json['shadowBanned']), - pinnedAt: serializer.fromJson(json['pinnedAt']), - archivedAt: serializer.fromJson(json['archivedAt']), - isModerator: serializer.fromJson(json['isModerator']), - extraData: serializer.fromJson?>(json['extraData']), - createdAt: serializer.fromJson(json['createdAt']), - updatedAt: serializer.fromJson(json['updatedAt']), ); } @override Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'userId': serializer.toJson(userId), + 'queryHash': serializer.toJson(queryHash), 'channelCid': serializer.toJson(channelCid), - 'channelRole': serializer.toJson(channelRole), - 'inviteAcceptedAt': serializer.toJson(inviteAcceptedAt), - 'inviteRejectedAt': serializer.toJson(inviteRejectedAt), - 'invited': serializer.toJson(invited), - 'banned': serializer.toJson(banned), - 'shadowBanned': serializer.toJson(shadowBanned), - 'pinnedAt': serializer.toJson(pinnedAt), - 'archivedAt': serializer.toJson(archivedAt), - 'isModerator': serializer.toJson(isModerator), - 'extraData': serializer.toJson?>(extraData), - 'createdAt': serializer.toJson(createdAt), - 'updatedAt': serializer.toJson(updatedAt), }; } - MemberEntity copyWith( - {String? userId, - String? channelCid, - Value channelRole = const Value.absent(), - Value inviteAcceptedAt = const Value.absent(), - Value inviteRejectedAt = const Value.absent(), - bool? invited, - bool? banned, - bool? shadowBanned, - Value pinnedAt = const Value.absent(), - Value archivedAt = const Value.absent(), - bool? isModerator, - Value?> extraData = const Value.absent(), - DateTime? createdAt, - DateTime? updatedAt}) => - MemberEntity( - userId: userId ?? this.userId, + ChannelQueryEntity copyWith({String? queryHash, String? channelCid}) => + ChannelQueryEntity( + queryHash: queryHash ?? this.queryHash, channelCid: channelCid ?? this.channelCid, - channelRole: channelRole.present ? channelRole.value : this.channelRole, - inviteAcceptedAt: inviteAcceptedAt.present - ? inviteAcceptedAt.value - : this.inviteAcceptedAt, - inviteRejectedAt: inviteRejectedAt.present - ? inviteRejectedAt.value - : this.inviteRejectedAt, - invited: invited ?? this.invited, - banned: banned ?? this.banned, - shadowBanned: shadowBanned ?? this.shadowBanned, - pinnedAt: pinnedAt.present ? pinnedAt.value : this.pinnedAt, - archivedAt: archivedAt.present ? archivedAt.value : this.archivedAt, - isModerator: isModerator ?? this.isModerator, - extraData: extraData.present ? extraData.value : this.extraData, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, ); - MemberEntity copyWithCompanion(MembersCompanion data) { - return MemberEntity( - userId: data.userId.present ? data.userId.value : this.userId, - channelCid: - data.channelCid.present ? data.channelCid.value : this.channelCid, - channelRole: - data.channelRole.present ? data.channelRole.value : this.channelRole, - inviteAcceptedAt: data.inviteAcceptedAt.present - ? data.inviteAcceptedAt.value - : this.inviteAcceptedAt, - inviteRejectedAt: data.inviteRejectedAt.present - ? data.inviteRejectedAt.value - : this.inviteRejectedAt, - invited: data.invited.present ? data.invited.value : this.invited, - banned: data.banned.present ? data.banned.value : this.banned, - shadowBanned: data.shadowBanned.present - ? data.shadowBanned.value - : this.shadowBanned, - pinnedAt: data.pinnedAt.present ? data.pinnedAt.value : this.pinnedAt, - archivedAt: - data.archivedAt.present ? data.archivedAt.value : this.archivedAt, - isModerator: - data.isModerator.present ? data.isModerator.value : this.isModerator, - extraData: data.extraData.present ? data.extraData.value : this.extraData, - createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, - updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, - ); - } - - @override - String toString() { - return (StringBuffer('MemberEntity(') - ..write('userId: $userId, ') - ..write('channelCid: $channelCid, ') - ..write('channelRole: $channelRole, ') - ..write('inviteAcceptedAt: $inviteAcceptedAt, ') - ..write('inviteRejectedAt: $inviteRejectedAt, ') - ..write('invited: $invited, ') - ..write('banned: $banned, ') - ..write('shadowBanned: $shadowBanned, ') - ..write('pinnedAt: $pinnedAt, ') - ..write('archivedAt: $archivedAt, ') - ..write('isModerator: $isModerator, ') - ..write('extraData: $extraData, ') - ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt') + ChannelQueryEntity copyWithCompanion(ChannelQueriesCompanion data) { + return ChannelQueryEntity( + queryHash: data.queryHash.present ? data.queryHash.value : this.queryHash, + channelCid: + data.channelCid.present ? data.channelCid.value : this.channelCid, + ); + } + + @override + String toString() { + return (StringBuffer('ChannelQueryEntity(') + ..write('queryHash: $queryHash, ') + ..write('channelCid: $channelCid') ..write(')')) .toString(); } @override - int get hashCode => Object.hash( - userId, - channelCid, - channelRole, - inviteAcceptedAt, - inviteRejectedAt, - invited, - banned, - shadowBanned, - pinnedAt, - archivedAt, - isModerator, - extraData, - createdAt, - updatedAt); + int get hashCode => Object.hash(queryHash, channelCid); @override bool operator ==(Object other) => identical(this, other) || - (other is MemberEntity && - other.userId == this.userId && - other.channelCid == this.channelCid && - other.channelRole == this.channelRole && - other.inviteAcceptedAt == this.inviteAcceptedAt && - other.inviteRejectedAt == this.inviteRejectedAt && - other.invited == this.invited && - other.banned == this.banned && - other.shadowBanned == this.shadowBanned && - other.pinnedAt == this.pinnedAt && - other.archivedAt == this.archivedAt && - other.isModerator == this.isModerator && - other.extraData == this.extraData && - other.createdAt == this.createdAt && - other.updatedAt == this.updatedAt); + (other is ChannelQueryEntity && + other.queryHash == this.queryHash && + other.channelCid == this.channelCid); } -class MembersCompanion extends UpdateCompanion { - final Value userId; +class ChannelQueriesCompanion extends UpdateCompanion { + final Value queryHash; final Value channelCid; - final Value channelRole; - final Value inviteAcceptedAt; - final Value inviteRejectedAt; - final Value invited; - final Value banned; - final Value shadowBanned; - final Value pinnedAt; - final Value archivedAt; - final Value isModerator; - final Value?> extraData; - final Value createdAt; - final Value updatedAt; final Value rowid; - const MembersCompanion({ - this.userId = const Value.absent(), + const ChannelQueriesCompanion({ + this.queryHash = const Value.absent(), this.channelCid = const Value.absent(), - this.channelRole = const Value.absent(), - this.inviteAcceptedAt = const Value.absent(), - this.inviteRejectedAt = const Value.absent(), - this.invited = const Value.absent(), - this.banned = const Value.absent(), - this.shadowBanned = const Value.absent(), - this.pinnedAt = const Value.absent(), - this.archivedAt = const Value.absent(), - this.isModerator = const Value.absent(), - this.extraData = const Value.absent(), - this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), this.rowid = const Value.absent(), }); - MembersCompanion.insert({ - required String userId, + ChannelQueriesCompanion.insert({ + required String queryHash, required String channelCid, - this.channelRole = const Value.absent(), - this.inviteAcceptedAt = const Value.absent(), - this.inviteRejectedAt = const Value.absent(), - this.invited = const Value.absent(), - this.banned = const Value.absent(), - this.shadowBanned = const Value.absent(), - this.pinnedAt = const Value.absent(), - this.archivedAt = const Value.absent(), - this.isModerator = const Value.absent(), - this.extraData = const Value.absent(), - this.createdAt = const Value.absent(), - this.updatedAt = const Value.absent(), this.rowid = const Value.absent(), - }) : userId = Value(userId), + }) : queryHash = Value(queryHash), channelCid = Value(channelCid); - static Insertable custom({ - Expression? userId, + static Insertable custom({ + Expression? queryHash, Expression? channelCid, - Expression? channelRole, - Expression? inviteAcceptedAt, - Expression? inviteRejectedAt, - Expression? invited, - Expression? banned, - Expression? shadowBanned, - Expression? pinnedAt, - Expression? archivedAt, - Expression? isModerator, - Expression? extraData, - Expression? createdAt, - Expression? updatedAt, Expression? rowid, }) { return RawValuesInsertable({ - if (userId != null) 'user_id': userId, + if (queryHash != null) 'query_hash': queryHash, if (channelCid != null) 'channel_cid': channelCid, - if (channelRole != null) 'channel_role': channelRole, - if (inviteAcceptedAt != null) 'invite_accepted_at': inviteAcceptedAt, - if (inviteRejectedAt != null) 'invite_rejected_at': inviteRejectedAt, - if (invited != null) 'invited': invited, - if (banned != null) 'banned': banned, - if (shadowBanned != null) 'shadow_banned': shadowBanned, - if (pinnedAt != null) 'pinned_at': pinnedAt, - if (archivedAt != null) 'archived_at': archivedAt, - if (isModerator != null) 'is_moderator': isModerator, - if (extraData != null) 'extra_data': extraData, - if (createdAt != null) 'created_at': createdAt, - if (updatedAt != null) 'updated_at': updatedAt, if (rowid != null) 'rowid': rowid, }); } - MembersCompanion copyWith( - {Value? userId, + ChannelQueriesCompanion copyWith( + {Value? queryHash, Value? channelCid, - Value? channelRole, - Value? inviteAcceptedAt, - Value? inviteRejectedAt, - Value? invited, - Value? banned, - Value? shadowBanned, - Value? pinnedAt, - Value? archivedAt, - Value? isModerator, - Value?>? extraData, - Value? createdAt, - Value? updatedAt, Value? rowid}) { - return MembersCompanion( - userId: userId ?? this.userId, + return ChannelQueriesCompanion( + queryHash: queryHash ?? this.queryHash, channelCid: channelCid ?? this.channelCid, - channelRole: channelRole ?? this.channelRole, - inviteAcceptedAt: inviteAcceptedAt ?? this.inviteAcceptedAt, - inviteRejectedAt: inviteRejectedAt ?? this.inviteRejectedAt, - invited: invited ?? this.invited, - banned: banned ?? this.banned, - shadowBanned: shadowBanned ?? this.shadowBanned, - pinnedAt: pinnedAt ?? this.pinnedAt, - archivedAt: archivedAt ?? this.archivedAt, - isModerator: isModerator ?? this.isModerator, - extraData: extraData ?? this.extraData, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, rowid: rowid ?? this.rowid, ); } @@ -7275,49 +8323,12 @@ class MembersCompanion extends UpdateCompanion { @override Map toColumns(bool nullToAbsent) { final map = {}; - if (userId.present) { - map['user_id'] = Variable(userId.value); + if (queryHash.present) { + map['query_hash'] = Variable(queryHash.value); } if (channelCid.present) { map['channel_cid'] = Variable(channelCid.value); } - if (channelRole.present) { - map['channel_role'] = Variable(channelRole.value); - } - if (inviteAcceptedAt.present) { - map['invite_accepted_at'] = Variable(inviteAcceptedAt.value); - } - if (inviteRejectedAt.present) { - map['invite_rejected_at'] = Variable(inviteRejectedAt.value); - } - if (invited.present) { - map['invited'] = Variable(invited.value); - } - if (banned.present) { - map['banned'] = Variable(banned.value); - } - if (shadowBanned.present) { - map['shadow_banned'] = Variable(shadowBanned.value); - } - if (pinnedAt.present) { - map['pinned_at'] = Variable(pinnedAt.value); - } - if (archivedAt.present) { - map['archived_at'] = Variable(archivedAt.value); - } - if (isModerator.present) { - map['is_moderator'] = Variable(isModerator.value); - } - if (extraData.present) { - map['extra_data'] = Variable( - $MembersTable.$converterextraDatan.toSql(extraData.value)); - } - if (createdAt.present) { - map['created_at'] = Variable(createdAt.value); - } - if (updatedAt.present) { - map['updated_at'] = Variable(updatedAt.value); - } if (rowid.present) { map['rowid'] = Variable(rowid.value); } @@ -7326,1207 +8337,1474 @@ class MembersCompanion extends UpdateCompanion { @override String toString() { - return (StringBuffer('MembersCompanion(') - ..write('userId: $userId, ') + return (StringBuffer('ChannelQueriesCompanion(') + ..write('queryHash: $queryHash, ') ..write('channelCid: $channelCid, ') - ..write('channelRole: $channelRole, ') - ..write('inviteAcceptedAt: $inviteAcceptedAt, ') - ..write('inviteRejectedAt: $inviteRejectedAt, ') - ..write('invited: $invited, ') - ..write('banned: $banned, ') - ..write('shadowBanned: $shadowBanned, ') - ..write('pinnedAt: $pinnedAt, ') - ..write('archivedAt: $archivedAt, ') - ..write('isModerator: $isModerator, ') - ..write('extraData: $extraData, ') - ..write('createdAt: $createdAt, ') - ..write('updatedAt: $updatedAt, ') ..write('rowid: $rowid') ..write(')')) .toString(); } } -class $ReadsTable extends Reads with TableInfo<$ReadsTable, ReadEntity> { +class $ConnectionEventsTable extends ConnectionEvents + with TableInfo<$ConnectionEventsTable, ConnectionEventEntity> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $ReadsTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _lastReadMeta = - const VerificationMeta('lastRead'); + $ConnectionEventsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); @override - late final GeneratedColumn lastRead = GeneratedColumn( - 'last_read', aliasedName, false, - type: DriftSqlType.dateTime, requiredDuringInsert: true); - static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + type: DriftSqlType.int, requiredDuringInsert: false); + static const VerificationMeta _typeMeta = const VerificationMeta('type'); @override - late final GeneratedColumn userId = GeneratedColumn( - 'user_id', aliasedName, false, + late final GeneratedColumn type = GeneratedColumn( + 'type', aliasedName, false, type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _channelCidMeta = - const VerificationMeta('channelCid'); @override - late final GeneratedColumn channelCid = GeneratedColumn( - 'channel_cid', aliasedName, false, - type: DriftSqlType.string, - requiredDuringInsert: true, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'REFERENCES channels (cid) ON DELETE CASCADE')); - static const VerificationMeta _unreadMessagesMeta = - const VerificationMeta('unreadMessages'); + late final GeneratedColumnWithTypeConverter?, String> + ownUser = GeneratedColumn('own_user', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false) + .withConverter?>( + $ConnectionEventsTable.$converterownUsern); + static const VerificationMeta _totalUnreadCountMeta = + const VerificationMeta('totalUnreadCount'); + @override + late final GeneratedColumn totalUnreadCount = GeneratedColumn( + 'total_unread_count', aliasedName, true, + type: DriftSqlType.int, requiredDuringInsert: false); + static const VerificationMeta _unreadChannelsMeta = + const VerificationMeta('unreadChannels'); @override - late final GeneratedColumn unreadMessages = GeneratedColumn( - 'unread_messages', aliasedName, false, - type: DriftSqlType.int, - requiredDuringInsert: false, - defaultValue: const Constant(0)); - static const VerificationMeta _lastReadMessageIdMeta = - const VerificationMeta('lastReadMessageId'); + late final GeneratedColumn unreadChannels = GeneratedColumn( + 'unread_channels', aliasedName, true, + type: DriftSqlType.int, requiredDuringInsert: false); + static const VerificationMeta _lastEventAtMeta = + const VerificationMeta('lastEventAt'); @override - late final GeneratedColumn lastReadMessageId = - GeneratedColumn('last_read_message_id', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false); + late final GeneratedColumn lastEventAt = GeneratedColumn( + 'last_event_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _lastSyncAtMeta = + const VerificationMeta('lastSyncAt'); @override - List get $columns => - [lastRead, userId, channelCid, unreadMessages, lastReadMessageId]; + late final GeneratedColumn lastSyncAt = GeneratedColumn( + 'last_sync_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + @override + List get $columns => [ + id, + type, + ownUser, + totalUnreadCount, + unreadChannels, + lastEventAt, + lastSyncAt + ]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'reads'; + static const String $name = 'connection_events'; @override - VerificationContext validateIntegrity(Insertable instance, + VerificationContext validateIntegrity( + Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('last_read')) { - context.handle(_lastReadMeta, - lastRead.isAcceptableOrUnknown(data['last_read']!, _lastReadMeta)); - } else if (isInserting) { - context.missing(_lastReadMeta); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); } - if (data.containsKey('user_id')) { - context.handle(_userIdMeta, - userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); + if (data.containsKey('type')) { + context.handle( + _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); } else if (isInserting) { - context.missing(_userIdMeta); + context.missing(_typeMeta); } - if (data.containsKey('channel_cid')) { + if (data.containsKey('total_unread_count')) { context.handle( - _channelCidMeta, - channelCid.isAcceptableOrUnknown( - data['channel_cid']!, _channelCidMeta)); - } else if (isInserting) { - context.missing(_channelCidMeta); + _totalUnreadCountMeta, + totalUnreadCount.isAcceptableOrUnknown( + data['total_unread_count']!, _totalUnreadCountMeta)); } - if (data.containsKey('unread_messages')) { + if (data.containsKey('unread_channels')) { context.handle( - _unreadMessagesMeta, - unreadMessages.isAcceptableOrUnknown( - data['unread_messages']!, _unreadMessagesMeta)); + _unreadChannelsMeta, + unreadChannels.isAcceptableOrUnknown( + data['unread_channels']!, _unreadChannelsMeta)); } - if (data.containsKey('last_read_message_id')) { + if (data.containsKey('last_event_at')) { context.handle( - _lastReadMessageIdMeta, - lastReadMessageId.isAcceptableOrUnknown( - data['last_read_message_id']!, _lastReadMessageIdMeta)); + _lastEventAtMeta, + lastEventAt.isAcceptableOrUnknown( + data['last_event_at']!, _lastEventAtMeta)); + } + if (data.containsKey('last_sync_at')) { + context.handle( + _lastSyncAtMeta, + lastSyncAt.isAcceptableOrUnknown( + data['last_sync_at']!, _lastSyncAtMeta)); } return context; } @override - Set get $primaryKey => {userId, channelCid}; + Set get $primaryKey => {id}; @override - ReadEntity map(Map data, {String? tablePrefix}) { + ConnectionEventEntity map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return ReadEntity( - lastRead: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}last_read'])!, - userId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, - channelCid: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}channel_cid'])!, - unreadMessages: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}unread_messages'])!, - lastReadMessageId: attachedDatabase.typeMapping.read( - DriftSqlType.string, data['${effectivePrefix}last_read_message_id']), + return ConnectionEventEntity( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + type: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}type'])!, + ownUser: $ConnectionEventsTable.$converterownUsern.fromSql( + attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}own_user'])), + totalUnreadCount: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}total_unread_count']), + unreadChannels: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}unread_channels']), + lastEventAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}last_event_at']), + lastSyncAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}last_sync_at']), ); } @override - $ReadsTable createAlias(String alias) { - return $ReadsTable(attachedDatabase, alias); + $ConnectionEventsTable createAlias(String alias) { + return $ConnectionEventsTable(attachedDatabase, alias); } + + static TypeConverter, String> $converterownUser = + MapConverter(); + static TypeConverter?, String?> $converterownUsern = + NullAwareTypeConverter.wrap($converterownUser); } -class ReadEntity extends DataClass implements Insertable { - /// Date of the read event - final DateTime lastRead; +class ConnectionEventEntity extends DataClass + implements Insertable { + /// event id + final int id; - /// Id of the User who sent the event - final String userId; + /// event type + final String type; - /// The channel cid of which this read belongs - final String channelCid; + /// User object of the current user + final Map? ownUser; - /// Number of unread messages - final int unreadMessages; + /// The number of unread messages for current user + final int? totalUnreadCount; - /// Id of the last read message - final String? lastReadMessageId; - const ReadEntity( - {required this.lastRead, - required this.userId, - required this.channelCid, - required this.unreadMessages, - this.lastReadMessageId}); + /// User total unread channels for current user + final int? unreadChannels; + + /// DateTime of the last event + final DateTime? lastEventAt; + + /// DateTime of the last sync + final DateTime? lastSyncAt; + const ConnectionEventEntity( + {required this.id, + required this.type, + this.ownUser, + this.totalUnreadCount, + this.unreadChannels, + this.lastEventAt, + this.lastSyncAt}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['last_read'] = Variable(lastRead); - map['user_id'] = Variable(userId); - map['channel_cid'] = Variable(channelCid); - map['unread_messages'] = Variable(unreadMessages); - if (!nullToAbsent || lastReadMessageId != null) { - map['last_read_message_id'] = Variable(lastReadMessageId); + map['id'] = Variable(id); + map['type'] = Variable(type); + if (!nullToAbsent || ownUser != null) { + map['own_user'] = Variable( + $ConnectionEventsTable.$converterownUsern.toSql(ownUser)); + } + if (!nullToAbsent || totalUnreadCount != null) { + map['total_unread_count'] = Variable(totalUnreadCount); + } + if (!nullToAbsent || unreadChannels != null) { + map['unread_channels'] = Variable(unreadChannels); + } + if (!nullToAbsent || lastEventAt != null) { + map['last_event_at'] = Variable(lastEventAt); + } + if (!nullToAbsent || lastSyncAt != null) { + map['last_sync_at'] = Variable(lastSyncAt); } return map; } - factory ReadEntity.fromJson(Map json, + factory ConnectionEventEntity.fromJson(Map json, {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; - return ReadEntity( - lastRead: serializer.fromJson(json['lastRead']), - userId: serializer.fromJson(json['userId']), - channelCid: serializer.fromJson(json['channelCid']), - unreadMessages: serializer.fromJson(json['unreadMessages']), - lastReadMessageId: - serializer.fromJson(json['lastReadMessageId']), + return ConnectionEventEntity( + id: serializer.fromJson(json['id']), + type: serializer.fromJson(json['type']), + ownUser: serializer.fromJson?>(json['ownUser']), + totalUnreadCount: serializer.fromJson(json['totalUnreadCount']), + unreadChannels: serializer.fromJson(json['unreadChannels']), + lastEventAt: serializer.fromJson(json['lastEventAt']), + lastSyncAt: serializer.fromJson(json['lastSyncAt']), ); } @override Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'lastRead': serializer.toJson(lastRead), - 'userId': serializer.toJson(userId), - 'channelCid': serializer.toJson(channelCid), - 'unreadMessages': serializer.toJson(unreadMessages), - 'lastReadMessageId': serializer.toJson(lastReadMessageId), + 'id': serializer.toJson(id), + 'type': serializer.toJson(type), + 'ownUser': serializer.toJson?>(ownUser), + 'totalUnreadCount': serializer.toJson(totalUnreadCount), + 'unreadChannels': serializer.toJson(unreadChannels), + 'lastEventAt': serializer.toJson(lastEventAt), + 'lastSyncAt': serializer.toJson(lastSyncAt), }; } - ReadEntity copyWith( - {DateTime? lastRead, - String? userId, - String? channelCid, - int? unreadMessages, - Value lastReadMessageId = const Value.absent()}) => - ReadEntity( - lastRead: lastRead ?? this.lastRead, - userId: userId ?? this.userId, - channelCid: channelCid ?? this.channelCid, - unreadMessages: unreadMessages ?? this.unreadMessages, - lastReadMessageId: lastReadMessageId.present - ? lastReadMessageId.value - : this.lastReadMessageId, + ConnectionEventEntity copyWith( + {int? id, + String? type, + Value?> ownUser = const Value.absent(), + Value totalUnreadCount = const Value.absent(), + Value unreadChannels = const Value.absent(), + Value lastEventAt = const Value.absent(), + Value lastSyncAt = const Value.absent()}) => + ConnectionEventEntity( + id: id ?? this.id, + type: type ?? this.type, + ownUser: ownUser.present ? ownUser.value : this.ownUser, + totalUnreadCount: totalUnreadCount.present + ? totalUnreadCount.value + : this.totalUnreadCount, + unreadChannels: + unreadChannels.present ? unreadChannels.value : this.unreadChannels, + lastEventAt: lastEventAt.present ? lastEventAt.value : this.lastEventAt, + lastSyncAt: lastSyncAt.present ? lastSyncAt.value : this.lastSyncAt, ); - ReadEntity copyWithCompanion(ReadsCompanion data) { - return ReadEntity( - lastRead: data.lastRead.present ? data.lastRead.value : this.lastRead, - userId: data.userId.present ? data.userId.value : this.userId, - channelCid: - data.channelCid.present ? data.channelCid.value : this.channelCid, - unreadMessages: data.unreadMessages.present - ? data.unreadMessages.value - : this.unreadMessages, - lastReadMessageId: data.lastReadMessageId.present - ? data.lastReadMessageId.value - : this.lastReadMessageId, + ConnectionEventEntity copyWithCompanion(ConnectionEventsCompanion data) { + return ConnectionEventEntity( + id: data.id.present ? data.id.value : this.id, + type: data.type.present ? data.type.value : this.type, + ownUser: data.ownUser.present ? data.ownUser.value : this.ownUser, + totalUnreadCount: data.totalUnreadCount.present + ? data.totalUnreadCount.value + : this.totalUnreadCount, + unreadChannels: data.unreadChannels.present + ? data.unreadChannels.value + : this.unreadChannels, + lastEventAt: + data.lastEventAt.present ? data.lastEventAt.value : this.lastEventAt, + lastSyncAt: + data.lastSyncAt.present ? data.lastSyncAt.value : this.lastSyncAt, ); } @override String toString() { - return (StringBuffer('ReadEntity(') - ..write('lastRead: $lastRead, ') - ..write('userId: $userId, ') - ..write('channelCid: $channelCid, ') - ..write('unreadMessages: $unreadMessages, ') - ..write('lastReadMessageId: $lastReadMessageId') + return (StringBuffer('ConnectionEventEntity(') + ..write('id: $id, ') + ..write('type: $type, ') + ..write('ownUser: $ownUser, ') + ..write('totalUnreadCount: $totalUnreadCount, ') + ..write('unreadChannels: $unreadChannels, ') + ..write('lastEventAt: $lastEventAt, ') + ..write('lastSyncAt: $lastSyncAt') ..write(')')) .toString(); } @override - int get hashCode => Object.hash( - lastRead, userId, channelCid, unreadMessages, lastReadMessageId); + int get hashCode => Object.hash(id, type, ownUser, totalUnreadCount, + unreadChannels, lastEventAt, lastSyncAt); @override bool operator ==(Object other) => identical(this, other) || - (other is ReadEntity && - other.lastRead == this.lastRead && - other.userId == this.userId && - other.channelCid == this.channelCid && - other.unreadMessages == this.unreadMessages && - other.lastReadMessageId == this.lastReadMessageId); + (other is ConnectionEventEntity && + other.id == this.id && + other.type == this.type && + other.ownUser == this.ownUser && + other.totalUnreadCount == this.totalUnreadCount && + other.unreadChannels == this.unreadChannels && + other.lastEventAt == this.lastEventAt && + other.lastSyncAt == this.lastSyncAt); } -class ReadsCompanion extends UpdateCompanion { - final Value lastRead; - final Value userId; - final Value channelCid; - final Value unreadMessages; - final Value lastReadMessageId; - final Value rowid; - const ReadsCompanion({ - this.lastRead = const Value.absent(), - this.userId = const Value.absent(), - this.channelCid = const Value.absent(), - this.unreadMessages = const Value.absent(), - this.lastReadMessageId = const Value.absent(), - this.rowid = const Value.absent(), +class ConnectionEventsCompanion extends UpdateCompanion { + final Value id; + final Value type; + final Value?> ownUser; + final Value totalUnreadCount; + final Value unreadChannels; + final Value lastEventAt; + final Value lastSyncAt; + const ConnectionEventsCompanion({ + this.id = const Value.absent(), + this.type = const Value.absent(), + this.ownUser = const Value.absent(), + this.totalUnreadCount = const Value.absent(), + this.unreadChannels = const Value.absent(), + this.lastEventAt = const Value.absent(), + this.lastSyncAt = const Value.absent(), }); - ReadsCompanion.insert({ - required DateTime lastRead, - required String userId, - required String channelCid, - this.unreadMessages = const Value.absent(), - this.lastReadMessageId = const Value.absent(), - this.rowid = const Value.absent(), - }) : lastRead = Value(lastRead), - userId = Value(userId), - channelCid = Value(channelCid); - static Insertable custom({ - Expression? lastRead, - Expression? userId, - Expression? channelCid, - Expression? unreadMessages, - Expression? lastReadMessageId, - Expression? rowid, + ConnectionEventsCompanion.insert({ + this.id = const Value.absent(), + required String type, + this.ownUser = const Value.absent(), + this.totalUnreadCount = const Value.absent(), + this.unreadChannels = const Value.absent(), + this.lastEventAt = const Value.absent(), + this.lastSyncAt = const Value.absent(), + }) : type = Value(type); + static Insertable custom({ + Expression? id, + Expression? type, + Expression? ownUser, + Expression? totalUnreadCount, + Expression? unreadChannels, + Expression? lastEventAt, + Expression? lastSyncAt, }) { return RawValuesInsertable({ - if (lastRead != null) 'last_read': lastRead, - if (userId != null) 'user_id': userId, - if (channelCid != null) 'channel_cid': channelCid, - if (unreadMessages != null) 'unread_messages': unreadMessages, - if (lastReadMessageId != null) 'last_read_message_id': lastReadMessageId, - if (rowid != null) 'rowid': rowid, + if (id != null) 'id': id, + if (type != null) 'type': type, + if (ownUser != null) 'own_user': ownUser, + if (totalUnreadCount != null) 'total_unread_count': totalUnreadCount, + if (unreadChannels != null) 'unread_channels': unreadChannels, + if (lastEventAt != null) 'last_event_at': lastEventAt, + if (lastSyncAt != null) 'last_sync_at': lastSyncAt, }); } - ReadsCompanion copyWith( - {Value? lastRead, - Value? userId, - Value? channelCid, - Value? unreadMessages, - Value? lastReadMessageId, - Value? rowid}) { - return ReadsCompanion( - lastRead: lastRead ?? this.lastRead, - userId: userId ?? this.userId, - channelCid: channelCid ?? this.channelCid, - unreadMessages: unreadMessages ?? this.unreadMessages, - lastReadMessageId: lastReadMessageId ?? this.lastReadMessageId, - rowid: rowid ?? this.rowid, + ConnectionEventsCompanion copyWith( + {Value? id, + Value? type, + Value?>? ownUser, + Value? totalUnreadCount, + Value? unreadChannels, + Value? lastEventAt, + Value? lastSyncAt}) { + return ConnectionEventsCompanion( + id: id ?? this.id, + type: type ?? this.type, + ownUser: ownUser ?? this.ownUser, + totalUnreadCount: totalUnreadCount ?? this.totalUnreadCount, + unreadChannels: unreadChannels ?? this.unreadChannels, + lastEventAt: lastEventAt ?? this.lastEventAt, + lastSyncAt: lastSyncAt ?? this.lastSyncAt, ); } @override Map toColumns(bool nullToAbsent) { final map = {}; - if (lastRead.present) { - map['last_read'] = Variable(lastRead.value); + if (id.present) { + map['id'] = Variable(id.value); } - if (userId.present) { - map['user_id'] = Variable(userId.value); + if (type.present) { + map['type'] = Variable(type.value); } - if (channelCid.present) { - map['channel_cid'] = Variable(channelCid.value); + if (ownUser.present) { + map['own_user'] = Variable( + $ConnectionEventsTable.$converterownUsern.toSql(ownUser.value)); } - if (unreadMessages.present) { - map['unread_messages'] = Variable(unreadMessages.value); + if (totalUnreadCount.present) { + map['total_unread_count'] = Variable(totalUnreadCount.value); } - if (lastReadMessageId.present) { - map['last_read_message_id'] = Variable(lastReadMessageId.value); + if (unreadChannels.present) { + map['unread_channels'] = Variable(unreadChannels.value); } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); + if (lastEventAt.present) { + map['last_event_at'] = Variable(lastEventAt.value); + } + if (lastSyncAt.present) { + map['last_sync_at'] = Variable(lastSyncAt.value); } return map; } @override String toString() { - return (StringBuffer('ReadsCompanion(') - ..write('lastRead: $lastRead, ') - ..write('userId: $userId, ') - ..write('channelCid: $channelCid, ') - ..write('unreadMessages: $unreadMessages, ') - ..write('lastReadMessageId: $lastReadMessageId, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -class $ChannelQueriesTable extends ChannelQueries - with TableInfo<$ChannelQueriesTable, ChannelQueryEntity> { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - $ChannelQueriesTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _queryHashMeta = - const VerificationMeta('queryHash'); - @override - late final GeneratedColumn queryHash = GeneratedColumn( - 'query_hash', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _channelCidMeta = - const VerificationMeta('channelCid'); - @override - late final GeneratedColumn channelCid = GeneratedColumn( - 'channel_cid', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - @override - List get $columns => [queryHash, channelCid]; - @override - String get aliasedName => _alias ?? actualTableName; - @override - String get actualTableName => $name; - static const String $name = 'channel_queries'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('query_hash')) { - context.handle(_queryHashMeta, - queryHash.isAcceptableOrUnknown(data['query_hash']!, _queryHashMeta)); - } else if (isInserting) { - context.missing(_queryHashMeta); - } - if (data.containsKey('channel_cid')) { - context.handle( - _channelCidMeta, - channelCid.isAcceptableOrUnknown( - data['channel_cid']!, _channelCidMeta)); - } else if (isInserting) { - context.missing(_channelCidMeta); - } - return context; + return (StringBuffer('ConnectionEventsCompanion(') + ..write('id: $id, ') + ..write('type: $type, ') + ..write('ownUser: $ownUser, ') + ..write('totalUnreadCount: $totalUnreadCount, ') + ..write('unreadChannels: $unreadChannels, ') + ..write('lastEventAt: $lastEventAt, ') + ..write('lastSyncAt: $lastSyncAt') + ..write(')')) + .toString(); } +} +abstract class _$DriftChatDatabase extends GeneratedDatabase { + _$DriftChatDatabase(QueryExecutor e) : super(e); + $DriftChatDatabaseManager get managers => $DriftChatDatabaseManager(this); + late final $ChannelsTable channels = $ChannelsTable(this); + late final $MessagesTable messages = $MessagesTable(this); + late final $DraftMessagesTable draftMessages = $DraftMessagesTable(this); + late final $LocationsTable locations = $LocationsTable(this); + late final $PinnedMessagesTable pinnedMessages = $PinnedMessagesTable(this); + late final $PollsTable polls = $PollsTable(this); + late final $PollVotesTable pollVotes = $PollVotesTable(this); + late final $PinnedMessageReactionsTable pinnedMessageReactions = + $PinnedMessageReactionsTable(this); + late final $ReactionsTable reactions = $ReactionsTable(this); + late final $UsersTable users = $UsersTable(this); + late final $MembersTable members = $MembersTable(this); + late final $ReadsTable reads = $ReadsTable(this); + late final $ChannelQueriesTable channelQueries = $ChannelQueriesTable(this); + late final $ConnectionEventsTable connectionEvents = + $ConnectionEventsTable(this); + late final UserDao userDao = UserDao(this as DriftChatDatabase); + late final ChannelDao channelDao = ChannelDao(this as DriftChatDatabase); + late final MessageDao messageDao = MessageDao(this as DriftChatDatabase); + late final DraftMessageDao draftMessageDao = + DraftMessageDao(this as DriftChatDatabase); + late final LocationDao locationDao = LocationDao(this as DriftChatDatabase); + late final PinnedMessageDao pinnedMessageDao = + PinnedMessageDao(this as DriftChatDatabase); + late final PinnedMessageReactionDao pinnedMessageReactionDao = + PinnedMessageReactionDao(this as DriftChatDatabase); + late final MemberDao memberDao = MemberDao(this as DriftChatDatabase); + late final PollDao pollDao = PollDao(this as DriftChatDatabase); + late final PollVoteDao pollVoteDao = PollVoteDao(this as DriftChatDatabase); + late final ReactionDao reactionDao = ReactionDao(this as DriftChatDatabase); + late final ReadDao readDao = ReadDao(this as DriftChatDatabase); + late final ChannelQueryDao channelQueryDao = + ChannelQueryDao(this as DriftChatDatabase); + late final ConnectionEventDao connectionEventDao = + ConnectionEventDao(this as DriftChatDatabase); @override - Set get $primaryKey => {queryHash, channelCid}; + Iterable> get allTables => + allSchemaEntities.whereType>(); @override - ChannelQueryEntity map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return ChannelQueryEntity( - queryHash: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}query_hash'])!, - channelCid: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}channel_cid'])!, - ); - } - + List get allSchemaEntities => [ + channels, + messages, + draftMessages, + locations, + pinnedMessages, + polls, + pollVotes, + pinnedMessageReactions, + reactions, + users, + members, + reads, + channelQueries, + connectionEvents + ]; @override - $ChannelQueriesTable createAlias(String alias) { - return $ChannelQueriesTable(attachedDatabase, alias); - } + StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules( + [ + WritePropagation( + on: TableUpdateQuery.onTableName('channels', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('messages', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('messages', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('draft_messages', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('channels', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('draft_messages', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('channels', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('locations', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('messages', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('locations', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('polls', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('poll_votes', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('pinned_messages', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('pinned_message_reactions', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('messages', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('reactions', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('channels', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('members', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName('channels', + limitUpdateKind: UpdateKind.delete), + result: [ + TableUpdate('reads', kind: UpdateKind.delete), + ], + ), + ], + ); } -class ChannelQueryEntity extends DataClass - implements Insertable { - /// The unique hash of this query - final String queryHash; +typedef $$ChannelsTableCreateCompanionBuilder = ChannelsCompanion Function({ + required String id, + required String type, + required String cid, + Value?> ownCapabilities, + required Map config, + Value frozen, + Value lastMessageAt, + Value createdAt, + Value updatedAt, + Value deletedAt, + Value memberCount, + Value createdById, + Value?> extraData, + Value rowid, +}); +typedef $$ChannelsTableUpdateCompanionBuilder = ChannelsCompanion Function({ + Value id, + Value type, + Value cid, + Value?> ownCapabilities, + Value> config, + Value frozen, + Value lastMessageAt, + Value createdAt, + Value updatedAt, + Value deletedAt, + Value memberCount, + Value createdById, + Value?> extraData, + Value rowid, +}); - /// The channel cid of this query - final String channelCid; - const ChannelQueryEntity({required this.queryHash, required this.channelCid}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['query_hash'] = Variable(queryHash); - map['channel_cid'] = Variable(channelCid); - return map; - } +final class $$ChannelsTableReferences + extends BaseReferences<_$DriftChatDatabase, $ChannelsTable, ChannelEntity> { + $$ChannelsTableReferences(super.$_db, super.$_table, super.$_typedResult); - factory ChannelQueryEntity.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return ChannelQueryEntity( - queryHash: serializer.fromJson(json['queryHash']), - channelCid: serializer.fromJson(json['channelCid']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'queryHash': serializer.toJson(queryHash), - 'channelCid': serializer.toJson(channelCid), - }; - } + static MultiTypedResultKey<$MessagesTable, List> + _messagesRefsTable(_$DriftChatDatabase db) => + MultiTypedResultKey.fromTable(db.messages, + aliasName: $_aliasNameGenerator( + db.channels.cid, db.messages.channelCid)); - ChannelQueryEntity copyWith({String? queryHash, String? channelCid}) => - ChannelQueryEntity( - queryHash: queryHash ?? this.queryHash, - channelCid: channelCid ?? this.channelCid, - ); - ChannelQueryEntity copyWithCompanion(ChannelQueriesCompanion data) { - return ChannelQueryEntity( - queryHash: data.queryHash.present ? data.queryHash.value : this.queryHash, - channelCid: - data.channelCid.present ? data.channelCid.value : this.channelCid, - ); + $$MessagesTableProcessedTableManager get messagesRefs { + final manager = $$MessagesTableTableManager($_db, $_db.messages).filter( + (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + + final cache = $_typedResult.readTableOrNull(_messagesRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); } - @override - String toString() { - return (StringBuffer('ChannelQueryEntity(') - ..write('queryHash: $queryHash, ') - ..write('channelCid: $channelCid') - ..write(')')) - .toString(); + static MultiTypedResultKey<$DraftMessagesTable, List> + _draftMessagesRefsTable(_$DriftChatDatabase db) => + MultiTypedResultKey.fromTable(db.draftMessages, + aliasName: $_aliasNameGenerator( + db.channels.cid, db.draftMessages.channelCid)); + + $$DraftMessagesTableProcessedTableManager get draftMessagesRefs { + final manager = $$DraftMessagesTableTableManager($_db, $_db.draftMessages) + .filter( + (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + + final cache = $_typedResult.readTableOrNull(_draftMessagesRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); } - @override - int get hashCode => Object.hash(queryHash, channelCid); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is ChannelQueryEntity && - other.queryHash == this.queryHash && - other.channelCid == this.channelCid); -} + static MultiTypedResultKey<$LocationsTable, List> + _locationsRefsTable(_$DriftChatDatabase db) => + MultiTypedResultKey.fromTable(db.locations, + aliasName: $_aliasNameGenerator( + db.channels.cid, db.locations.channelCid)); -class ChannelQueriesCompanion extends UpdateCompanion { - final Value queryHash; - final Value channelCid; - final Value rowid; - const ChannelQueriesCompanion({ - this.queryHash = const Value.absent(), - this.channelCid = const Value.absent(), - this.rowid = const Value.absent(), - }); - ChannelQueriesCompanion.insert({ - required String queryHash, - required String channelCid, - this.rowid = const Value.absent(), - }) : queryHash = Value(queryHash), - channelCid = Value(channelCid); - static Insertable custom({ - Expression? queryHash, - Expression? channelCid, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (queryHash != null) 'query_hash': queryHash, - if (channelCid != null) 'channel_cid': channelCid, - if (rowid != null) 'rowid': rowid, - }); - } + $$LocationsTableProcessedTableManager get locationsRefs { + final manager = $$LocationsTableTableManager($_db, $_db.locations).filter( + (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); - ChannelQueriesCompanion copyWith( - {Value? queryHash, - Value? channelCid, - Value? rowid}) { - return ChannelQueriesCompanion( - queryHash: queryHash ?? this.queryHash, - channelCid: channelCid ?? this.channelCid, - rowid: rowid ?? this.rowid, - ); + final cache = $_typedResult.readTableOrNull(_locationsRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); } - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (queryHash.present) { - map['query_hash'] = Variable(queryHash.value); - } - if (channelCid.present) { - map['channel_cid'] = Variable(channelCid.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; + static MultiTypedResultKey<$MembersTable, List> + _membersRefsTable(_$DriftChatDatabase db) => + MultiTypedResultKey.fromTable(db.members, + aliasName: + $_aliasNameGenerator(db.channels.cid, db.members.channelCid)); + + $$MembersTableProcessedTableManager get membersRefs { + final manager = $$MembersTableTableManager($_db, $_db.members).filter( + (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + + final cache = $_typedResult.readTableOrNull(_membersRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); } - @override - String toString() { - return (StringBuffer('ChannelQueriesCompanion(') - ..write('queryHash: $queryHash, ') - ..write('channelCid: $channelCid, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); + static MultiTypedResultKey<$ReadsTable, List> _readsRefsTable( + _$DriftChatDatabase db) => + MultiTypedResultKey.fromTable(db.reads, + aliasName: + $_aliasNameGenerator(db.channels.cid, db.reads.channelCid)); + + $$ReadsTableProcessedTableManager get readsRefs { + final manager = $$ReadsTableTableManager($_db, $_db.reads).filter( + (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + + final cache = $_typedResult.readTableOrNull(_readsRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); } } -class $ConnectionEventsTable extends ConnectionEvents - with TableInfo<$ConnectionEventsTable, ConnectionEventEntity> { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - $ConnectionEventsTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.int, requiredDuringInsert: false); - static const VerificationMeta _typeMeta = const VerificationMeta('type'); - @override - late final GeneratedColumn type = GeneratedColumn( - 'type', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - @override - late final GeneratedColumnWithTypeConverter?, String> - ownUser = GeneratedColumn('own_user', aliasedName, true, - type: DriftSqlType.string, requiredDuringInsert: false) - .withConverter?>( - $ConnectionEventsTable.$converterownUsern); - static const VerificationMeta _totalUnreadCountMeta = - const VerificationMeta('totalUnreadCount'); - @override - late final GeneratedColumn totalUnreadCount = GeneratedColumn( - 'total_unread_count', aliasedName, true, - type: DriftSqlType.int, requiredDuringInsert: false); - static const VerificationMeta _unreadChannelsMeta = - const VerificationMeta('unreadChannels'); - @override - late final GeneratedColumn unreadChannels = GeneratedColumn( - 'unread_channels', aliasedName, true, - type: DriftSqlType.int, requiredDuringInsert: false); - static const VerificationMeta _lastEventAtMeta = - const VerificationMeta('lastEventAt'); - @override - late final GeneratedColumn lastEventAt = GeneratedColumn( - 'last_event_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _lastSyncAtMeta = - const VerificationMeta('lastSyncAt'); - @override - late final GeneratedColumn lastSyncAt = GeneratedColumn( - 'last_sync_at', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); - @override - List get $columns => [ - id, - type, - ownUser, - totalUnreadCount, - unreadChannels, - lastEventAt, - lastSyncAt - ]; - @override - String get aliasedName => _alias ?? actualTableName; - @override - String get actualTableName => $name; - static const String $name = 'connection_events'; - @override - VerificationContext validateIntegrity( - Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - if (data.containsKey('type')) { - context.handle( - _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); - } else if (isInserting) { - context.missing(_typeMeta); - } - if (data.containsKey('total_unread_count')) { - context.handle( - _totalUnreadCountMeta, - totalUnreadCount.isAcceptableOrUnknown( - data['total_unread_count']!, _totalUnreadCountMeta)); - } - if (data.containsKey('unread_channels')) { - context.handle( - _unreadChannelsMeta, - unreadChannels.isAcceptableOrUnknown( - data['unread_channels']!, _unreadChannelsMeta)); - } - if (data.containsKey('last_event_at')) { - context.handle( - _lastEventAtMeta, - lastEventAt.isAcceptableOrUnknown( - data['last_event_at']!, _lastEventAtMeta)); - } - if (data.containsKey('last_sync_at')) { - context.handle( - _lastSyncAtMeta, - lastSyncAt.isAcceptableOrUnknown( - data['last_sync_at']!, _lastSyncAtMeta)); - } - return context; +class $$ChannelsTableFilterComposer + extends Composer<_$DriftChatDatabase, $ChannelsTable> { + $$ChannelsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnFilters get type => $composableBuilder( + column: $table.type, builder: (column) => ColumnFilters(column)); + + ColumnFilters get cid => $composableBuilder( + column: $table.cid, builder: (column) => ColumnFilters(column)); + + ColumnWithTypeConverterFilters?, List, String> + get ownCapabilities => $composableBuilder( + column: $table.ownCapabilities, + builder: (column) => ColumnWithTypeConverterFilters(column)); + + ColumnWithTypeConverterFilters, Map, + String> + get config => $composableBuilder( + column: $table.config, + builder: (column) => ColumnWithTypeConverterFilters(column)); + + ColumnFilters get frozen => $composableBuilder( + column: $table.frozen, builder: (column) => ColumnFilters(column)); + + ColumnFilters get lastMessageAt => $composableBuilder( + column: $table.lastMessageAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get deletedAt => $composableBuilder( + column: $table.deletedAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get memberCount => $composableBuilder( + column: $table.memberCount, builder: (column) => ColumnFilters(column)); + + ColumnFilters get createdById => $composableBuilder( + column: $table.createdById, builder: (column) => ColumnFilters(column)); + + ColumnWithTypeConverterFilters?, Map, + String> + get extraData => $composableBuilder( + column: $table.extraData, + builder: (column) => ColumnWithTypeConverterFilters(column)); + + Expression messagesRefs( + Expression Function($$MessagesTableFilterComposer f) f) { + final $$MessagesTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MessagesTableFilterComposer( + $db: $db, + $table: $db.messages, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); } - @override - Set get $primaryKey => {id}; - @override - ConnectionEventEntity map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return ConnectionEventEntity( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, - type: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}type'])!, - ownUser: $ConnectionEventsTable.$converterownUsern.fromSql( - attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}own_user'])), - totalUnreadCount: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}total_unread_count']), - unreadChannels: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}unread_channels']), - lastEventAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}last_event_at']), - lastSyncAt: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}last_sync_at']), - ); + Expression draftMessagesRefs( + Expression Function($$DraftMessagesTableFilterComposer f) f) { + final $$DraftMessagesTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.draftMessages, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$DraftMessagesTableFilterComposer( + $db: $db, + $table: $db.draftMessages, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); } - @override - $ConnectionEventsTable createAlias(String alias) { - return $ConnectionEventsTable(attachedDatabase, alias); + Expression locationsRefs( + Expression Function($$LocationsTableFilterComposer f) f) { + final $$LocationsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.locations, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$LocationsTableFilterComposer( + $db: $db, + $table: $db.locations, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); } - static TypeConverter, String> $converterownUser = - MapConverter(); - static TypeConverter?, String?> $converterownUsern = - NullAwareTypeConverter.wrap($converterownUser); + Expression membersRefs( + Expression Function($$MembersTableFilterComposer f) f) { + final $$MembersTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.members, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MembersTableFilterComposer( + $db: $db, + $table: $db.members, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression readsRefs( + Expression Function($$ReadsTableFilterComposer f) f) { + final $$ReadsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.reads, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$ReadsTableFilterComposer( + $db: $db, + $table: $db.reads, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } } -class ConnectionEventEntity extends DataClass - implements Insertable { - /// event id - final int id; +class $$ChannelsTableOrderingComposer + extends Composer<_$DriftChatDatabase, $ChannelsTable> { + $$ChannelsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnOrderings(column)); - /// event type - final String type; + ColumnOrderings get type => $composableBuilder( + column: $table.type, builder: (column) => ColumnOrderings(column)); - /// User object of the current user - final Map? ownUser; + ColumnOrderings get cid => $composableBuilder( + column: $table.cid, builder: (column) => ColumnOrderings(column)); - /// The number of unread messages for current user - final int? totalUnreadCount; + ColumnOrderings get ownCapabilities => $composableBuilder( + column: $table.ownCapabilities, + builder: (column) => ColumnOrderings(column)); - /// User total unread channels for current user - final int? unreadChannels; + ColumnOrderings get config => $composableBuilder( + column: $table.config, builder: (column) => ColumnOrderings(column)); - /// DateTime of the last event - final DateTime? lastEventAt; + ColumnOrderings get frozen => $composableBuilder( + column: $table.frozen, builder: (column) => ColumnOrderings(column)); - /// DateTime of the last sync - final DateTime? lastSyncAt; - const ConnectionEventEntity( - {required this.id, - required this.type, - this.ownUser, - this.totalUnreadCount, - this.unreadChannels, - this.lastEventAt, - this.lastSyncAt}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['id'] = Variable(id); - map['type'] = Variable(type); - if (!nullToAbsent || ownUser != null) { - map['own_user'] = Variable( - $ConnectionEventsTable.$converterownUsern.toSql(ownUser)); - } - if (!nullToAbsent || totalUnreadCount != null) { - map['total_unread_count'] = Variable(totalUnreadCount); - } - if (!nullToAbsent || unreadChannels != null) { - map['unread_channels'] = Variable(unreadChannels); - } - if (!nullToAbsent || lastEventAt != null) { - map['last_event_at'] = Variable(lastEventAt); - } - if (!nullToAbsent || lastSyncAt != null) { - map['last_sync_at'] = Variable(lastSyncAt); - } - return map; - } + ColumnOrderings get lastMessageAt => $composableBuilder( + column: $table.lastMessageAt, + builder: (column) => ColumnOrderings(column)); - factory ConnectionEventEntity.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return ConnectionEventEntity( - id: serializer.fromJson(json['id']), - type: serializer.fromJson(json['type']), - ownUser: serializer.fromJson?>(json['ownUser']), - totalUnreadCount: serializer.fromJson(json['totalUnreadCount']), - unreadChannels: serializer.fromJson(json['unreadChannels']), - lastEventAt: serializer.fromJson(json['lastEventAt']), - lastSyncAt: serializer.fromJson(json['lastSyncAt']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'id': serializer.toJson(id), - 'type': serializer.toJson(type), - 'ownUser': serializer.toJson?>(ownUser), - 'totalUnreadCount': serializer.toJson(totalUnreadCount), - 'unreadChannels': serializer.toJson(unreadChannels), - 'lastEventAt': serializer.toJson(lastEventAt), - 'lastSyncAt': serializer.toJson(lastSyncAt), - }; - } + ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnOrderings(column)); - ConnectionEventEntity copyWith( - {int? id, - String? type, - Value?> ownUser = const Value.absent(), - Value totalUnreadCount = const Value.absent(), - Value unreadChannels = const Value.absent(), - Value lastEventAt = const Value.absent(), - Value lastSyncAt = const Value.absent()}) => - ConnectionEventEntity( - id: id ?? this.id, - type: type ?? this.type, - ownUser: ownUser.present ? ownUser.value : this.ownUser, - totalUnreadCount: totalUnreadCount.present - ? totalUnreadCount.value - : this.totalUnreadCount, - unreadChannels: - unreadChannels.present ? unreadChannels.value : this.unreadChannels, - lastEventAt: lastEventAt.present ? lastEventAt.value : this.lastEventAt, - lastSyncAt: lastSyncAt.present ? lastSyncAt.value : this.lastSyncAt, - ); - ConnectionEventEntity copyWithCompanion(ConnectionEventsCompanion data) { - return ConnectionEventEntity( - id: data.id.present ? data.id.value : this.id, - type: data.type.present ? data.type.value : this.type, - ownUser: data.ownUser.present ? data.ownUser.value : this.ownUser, - totalUnreadCount: data.totalUnreadCount.present - ? data.totalUnreadCount.value - : this.totalUnreadCount, - unreadChannels: data.unreadChannels.present - ? data.unreadChannels.value - : this.unreadChannels, - lastEventAt: - data.lastEventAt.present ? data.lastEventAt.value : this.lastEventAt, - lastSyncAt: - data.lastSyncAt.present ? data.lastSyncAt.value : this.lastSyncAt, - ); - } + ColumnOrderings get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnOrderings(column)); - @override - String toString() { - return (StringBuffer('ConnectionEventEntity(') - ..write('id: $id, ') - ..write('type: $type, ') - ..write('ownUser: $ownUser, ') - ..write('totalUnreadCount: $totalUnreadCount, ') - ..write('unreadChannels: $unreadChannels, ') - ..write('lastEventAt: $lastEventAt, ') - ..write('lastSyncAt: $lastSyncAt') - ..write(')')) - .toString(); - } + ColumnOrderings get deletedAt => $composableBuilder( + column: $table.deletedAt, builder: (column) => ColumnOrderings(column)); - @override - int get hashCode => Object.hash(id, type, ownUser, totalUnreadCount, - unreadChannels, lastEventAt, lastSyncAt); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is ConnectionEventEntity && - other.id == this.id && - other.type == this.type && - other.ownUser == this.ownUser && - other.totalUnreadCount == this.totalUnreadCount && - other.unreadChannels == this.unreadChannels && - other.lastEventAt == this.lastEventAt && - other.lastSyncAt == this.lastSyncAt); + ColumnOrderings get memberCount => $composableBuilder( + column: $table.memberCount, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get createdById => $composableBuilder( + column: $table.createdById, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get extraData => $composableBuilder( + column: $table.extraData, builder: (column) => ColumnOrderings(column)); } -class ConnectionEventsCompanion extends UpdateCompanion { - final Value id; - final Value type; - final Value?> ownUser; - final Value totalUnreadCount; - final Value unreadChannels; - final Value lastEventAt; - final Value lastSyncAt; - const ConnectionEventsCompanion({ - this.id = const Value.absent(), - this.type = const Value.absent(), - this.ownUser = const Value.absent(), - this.totalUnreadCount = const Value.absent(), - this.unreadChannels = const Value.absent(), - this.lastEventAt = const Value.absent(), - this.lastSyncAt = const Value.absent(), +class $$ChannelsTableAnnotationComposer + extends Composer<_$DriftChatDatabase, $ChannelsTable> { + $$ChannelsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, }); - ConnectionEventsCompanion.insert({ - this.id = const Value.absent(), - required String type, - this.ownUser = const Value.absent(), - this.totalUnreadCount = const Value.absent(), - this.unreadChannels = const Value.absent(), - this.lastEventAt = const Value.absent(), - this.lastSyncAt = const Value.absent(), - }) : type = Value(type); - static Insertable custom({ - Expression? id, - Expression? type, - Expression? ownUser, - Expression? totalUnreadCount, - Expression? unreadChannels, - Expression? lastEventAt, - Expression? lastSyncAt, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (type != null) 'type': type, - if (ownUser != null) 'own_user': ownUser, - if (totalUnreadCount != null) 'total_unread_count': totalUnreadCount, - if (unreadChannels != null) 'unread_channels': unreadChannels, - if (lastEventAt != null) 'last_event_at': lastEventAt, - if (lastSyncAt != null) 'last_sync_at': lastSyncAt, - }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get type => + $composableBuilder(column: $table.type, builder: (column) => column); + + GeneratedColumn get cid => + $composableBuilder(column: $table.cid, builder: (column) => column); + + GeneratedColumnWithTypeConverter?, String> get ownCapabilities => + $composableBuilder( + column: $table.ownCapabilities, builder: (column) => column); + + GeneratedColumnWithTypeConverter, String> get config => + $composableBuilder(column: $table.config, builder: (column) => column); + + GeneratedColumn get frozen => + $composableBuilder(column: $table.frozen, builder: (column) => column); + + GeneratedColumn get lastMessageAt => $composableBuilder( + column: $table.lastMessageAt, builder: (column) => column); + + GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); + + GeneratedColumn get updatedAt => + $composableBuilder(column: $table.updatedAt, builder: (column) => column); + + GeneratedColumn get deletedAt => + $composableBuilder(column: $table.deletedAt, builder: (column) => column); + + GeneratedColumn get memberCount => $composableBuilder( + column: $table.memberCount, builder: (column) => column); + + GeneratedColumn get createdById => $composableBuilder( + column: $table.createdById, builder: (column) => column); + + GeneratedColumnWithTypeConverter?, String> + get extraData => $composableBuilder( + column: $table.extraData, builder: (column) => column); + + Expression messagesRefs( + Expression Function($$MessagesTableAnnotationComposer a) f) { + final $$MessagesTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MessagesTableAnnotationComposer( + $db: $db, + $table: $db.messages, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); } - ConnectionEventsCompanion copyWith( - {Value? id, - Value? type, - Value?>? ownUser, - Value? totalUnreadCount, - Value? unreadChannels, - Value? lastEventAt, - Value? lastSyncAt}) { - return ConnectionEventsCompanion( - id: id ?? this.id, - type: type ?? this.type, - ownUser: ownUser ?? this.ownUser, - totalUnreadCount: totalUnreadCount ?? this.totalUnreadCount, - unreadChannels: unreadChannels ?? this.unreadChannels, - lastEventAt: lastEventAt ?? this.lastEventAt, - lastSyncAt: lastSyncAt ?? this.lastSyncAt, - ); + Expression draftMessagesRefs( + Expression Function($$DraftMessagesTableAnnotationComposer a) f) { + final $$DraftMessagesTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.draftMessages, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$DraftMessagesTableAnnotationComposer( + $db: $db, + $table: $db.draftMessages, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); } - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (type.present) { - map['type'] = Variable(type.value); - } - if (ownUser.present) { - map['own_user'] = Variable( - $ConnectionEventsTable.$converterownUsern.toSql(ownUser.value)); - } - if (totalUnreadCount.present) { - map['total_unread_count'] = Variable(totalUnreadCount.value); - } - if (unreadChannels.present) { - map['unread_channels'] = Variable(unreadChannels.value); - } - if (lastEventAt.present) { - map['last_event_at'] = Variable(lastEventAt.value); - } - if (lastSyncAt.present) { - map['last_sync_at'] = Variable(lastSyncAt.value); - } - return map; + Expression locationsRefs( + Expression Function($$LocationsTableAnnotationComposer a) f) { + final $$LocationsTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.locations, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$LocationsTableAnnotationComposer( + $db: $db, + $table: $db.locations, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); } - @override - String toString() { - return (StringBuffer('ConnectionEventsCompanion(') - ..write('id: $id, ') - ..write('type: $type, ') - ..write('ownUser: $ownUser, ') - ..write('totalUnreadCount: $totalUnreadCount, ') - ..write('unreadChannels: $unreadChannels, ') - ..write('lastEventAt: $lastEventAt, ') - ..write('lastSyncAt: $lastSyncAt') - ..write(')')) - .toString(); + Expression membersRefs( + Expression Function($$MembersTableAnnotationComposer a) f) { + final $$MembersTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.members, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MembersTableAnnotationComposer( + $db: $db, + $table: $db.members, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression readsRefs( + Expression Function($$ReadsTableAnnotationComposer a) f) { + final $$ReadsTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.cid, + referencedTable: $db.reads, + getReferencedColumn: (t) => t.channelCid, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$ReadsTableAnnotationComposer( + $db: $db, + $table: $db.reads, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); } } -abstract class _$DriftChatDatabase extends GeneratedDatabase { - _$DriftChatDatabase(QueryExecutor e) : super(e); - $DriftChatDatabaseManager get managers => $DriftChatDatabaseManager(this); - late final $ChannelsTable channels = $ChannelsTable(this); - late final $MessagesTable messages = $MessagesTable(this); - late final $DraftMessagesTable draftMessages = $DraftMessagesTable(this); - late final $PinnedMessagesTable pinnedMessages = $PinnedMessagesTable(this); - late final $PollsTable polls = $PollsTable(this); - late final $PollVotesTable pollVotes = $PollVotesTable(this); - late final $PinnedMessageReactionsTable pinnedMessageReactions = - $PinnedMessageReactionsTable(this); - late final $ReactionsTable reactions = $ReactionsTable(this); - late final $UsersTable users = $UsersTable(this); - late final $MembersTable members = $MembersTable(this); - late final $ReadsTable reads = $ReadsTable(this); - late final $ChannelQueriesTable channelQueries = $ChannelQueriesTable(this); - late final $ConnectionEventsTable connectionEvents = - $ConnectionEventsTable(this); - late final UserDao userDao = UserDao(this as DriftChatDatabase); - late final ChannelDao channelDao = ChannelDao(this as DriftChatDatabase); - late final MessageDao messageDao = MessageDao(this as DriftChatDatabase); - late final DraftMessageDao draftMessageDao = - DraftMessageDao(this as DriftChatDatabase); - late final PinnedMessageDao pinnedMessageDao = - PinnedMessageDao(this as DriftChatDatabase); - late final PinnedMessageReactionDao pinnedMessageReactionDao = - PinnedMessageReactionDao(this as DriftChatDatabase); - late final MemberDao memberDao = MemberDao(this as DriftChatDatabase); - late final PollDao pollDao = PollDao(this as DriftChatDatabase); - late final PollVoteDao pollVoteDao = PollVoteDao(this as DriftChatDatabase); - late final ReactionDao reactionDao = ReactionDao(this as DriftChatDatabase); - late final ReadDao readDao = ReadDao(this as DriftChatDatabase); - late final ChannelQueryDao channelQueryDao = - ChannelQueryDao(this as DriftChatDatabase); - late final ConnectionEventDao connectionEventDao = - ConnectionEventDao(this as DriftChatDatabase); - @override - Iterable> get allTables => - allSchemaEntities.whereType>(); - @override - List get allSchemaEntities => [ - channels, - messages, - draftMessages, - pinnedMessages, - polls, - pollVotes, - pinnedMessageReactions, - reactions, - users, - members, - reads, - channelQueries, - connectionEvents - ]; - @override - StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules( - [ - WritePropagation( - on: TableUpdateQuery.onTableName('channels', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('messages', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('messages', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('draft_messages', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('channels', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('draft_messages', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('polls', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('poll_votes', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('pinned_messages', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('pinned_message_reactions', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('messages', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('reactions', kind: UpdateKind.delete), - ], - ), - WritePropagation( - on: TableUpdateQuery.onTableName('channels', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('members', kind: UpdateKind.delete), - ], +class $$ChannelsTableTableManager extends RootTableManager< + _$DriftChatDatabase, + $ChannelsTable, + ChannelEntity, + $$ChannelsTableFilterComposer, + $$ChannelsTableOrderingComposer, + $$ChannelsTableAnnotationComposer, + $$ChannelsTableCreateCompanionBuilder, + $$ChannelsTableUpdateCompanionBuilder, + (ChannelEntity, $$ChannelsTableReferences), + ChannelEntity, + PrefetchHooks Function( + {bool messagesRefs, + bool draftMessagesRefs, + bool locationsRefs, + bool membersRefs, + bool readsRefs})> { + $$ChannelsTableTableManager(_$DriftChatDatabase db, $ChannelsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$ChannelsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$ChannelsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$ChannelsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value type = const Value.absent(), + Value cid = const Value.absent(), + Value?> ownCapabilities = const Value.absent(), + Value> config = const Value.absent(), + Value frozen = const Value.absent(), + Value lastMessageAt = const Value.absent(), + Value createdAt = const Value.absent(), + Value updatedAt = const Value.absent(), + Value deletedAt = const Value.absent(), + Value memberCount = const Value.absent(), + Value createdById = const Value.absent(), + Value?> extraData = const Value.absent(), + Value rowid = const Value.absent(), + }) => + ChannelsCompanion( + id: id, + type: type, + cid: cid, + ownCapabilities: ownCapabilities, + config: config, + frozen: frozen, + lastMessageAt: lastMessageAt, + createdAt: createdAt, + updatedAt: updatedAt, + deletedAt: deletedAt, + memberCount: memberCount, + createdById: createdById, + extraData: extraData, + rowid: rowid, ), - WritePropagation( - on: TableUpdateQuery.onTableName('channels', - limitUpdateKind: UpdateKind.delete), - result: [ - TableUpdate('reads', kind: UpdateKind.delete), - ], + createCompanionCallback: ({ + required String id, + required String type, + required String cid, + Value?> ownCapabilities = const Value.absent(), + required Map config, + Value frozen = const Value.absent(), + Value lastMessageAt = const Value.absent(), + Value createdAt = const Value.absent(), + Value updatedAt = const Value.absent(), + Value deletedAt = const Value.absent(), + Value memberCount = const Value.absent(), + Value createdById = const Value.absent(), + Value?> extraData = const Value.absent(), + Value rowid = const Value.absent(), + }) => + ChannelsCompanion.insert( + id: id, + type: type, + cid: cid, + ownCapabilities: ownCapabilities, + config: config, + frozen: frozen, + lastMessageAt: lastMessageAt, + createdAt: createdAt, + updatedAt: updatedAt, + deletedAt: deletedAt, + memberCount: memberCount, + createdById: createdById, + extraData: extraData, + rowid: rowid, ), - ], - ); + withReferenceMapper: (p0) => p0 + .map((e) => + (e.readTable(table), $$ChannelsTableReferences(db, table, e))) + .toList(), + prefetchHooksCallback: ( + {messagesRefs = false, + draftMessagesRefs = false, + locationsRefs = false, + membersRefs = false, + readsRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [ + if (messagesRefs) db.messages, + if (draftMessagesRefs) db.draftMessages, + if (locationsRefs) db.locations, + if (membersRefs) db.members, + if (readsRefs) db.reads + ], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (messagesRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$ChannelsTableReferences._messagesRefsTable(db), + managerFromTypedResult: (p0) => + $$ChannelsTableReferences(db, table, p0) + .messagesRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => referencedItems + .where((e) => e.channelCid == item.cid), + typedResults: items), + if (draftMessagesRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: $$ChannelsTableReferences + ._draftMessagesRefsTable(db), + managerFromTypedResult: (p0) => + $$ChannelsTableReferences(db, table, p0) + .draftMessagesRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => referencedItems + .where((e) => e.channelCid == item.cid), + typedResults: items), + if (locationsRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$ChannelsTableReferences._locationsRefsTable(db), + managerFromTypedResult: (p0) => + $$ChannelsTableReferences(db, table, p0) + .locationsRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => referencedItems + .where((e) => e.channelCid == item.cid), + typedResults: items), + if (membersRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$ChannelsTableReferences._membersRefsTable(db), + managerFromTypedResult: (p0) => + $$ChannelsTableReferences(db, table, p0) + .membersRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => referencedItems + .where((e) => e.channelCid == item.cid), + typedResults: items), + if (readsRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$ChannelsTableReferences._readsRefsTable(db), + managerFromTypedResult: (p0) => + $$ChannelsTableReferences(db, table, p0).readsRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => referencedItems + .where((e) => e.channelCid == item.cid), + typedResults: items) + ]; + }, + ); + }, + )); } -typedef $$ChannelsTableCreateCompanionBuilder = ChannelsCompanion Function({ +typedef $$ChannelsTableProcessedTableManager = ProcessedTableManager< + _$DriftChatDatabase, + $ChannelsTable, + ChannelEntity, + $$ChannelsTableFilterComposer, + $$ChannelsTableOrderingComposer, + $$ChannelsTableAnnotationComposer, + $$ChannelsTableCreateCompanionBuilder, + $$ChannelsTableUpdateCompanionBuilder, + (ChannelEntity, $$ChannelsTableReferences), + ChannelEntity, + PrefetchHooks Function( + {bool messagesRefs, + bool draftMessagesRefs, + bool locationsRefs, + bool membersRefs, + bool readsRefs})>; +typedef $$MessagesTableCreateCompanionBuilder = MessagesCompanion Function({ required String id, - required String type, - required String cid, - Value?> ownCapabilities, - required Map config, - Value frozen, - Value lastMessageAt, - Value createdAt, - Value updatedAt, - Value deletedAt, - Value memberCount, - Value createdById, + Value messageText, + required List attachments, + required String state, + Value type, + required List mentionedUsers, + Value?> reactionGroups, + Value parentId, + Value quotedMessageId, + Value pollId, + Value replyCount, + Value showInChannel, + Value shadowed, + Value command, + Value localCreatedAt, + Value remoteCreatedAt, + Value localUpdatedAt, + Value remoteUpdatedAt, + Value localDeletedAt, + Value remoteDeletedAt, + Value messageTextUpdatedAt, + Value userId, + Value pinned, + Value pinnedAt, + Value pinExpires, + Value pinnedByUserId, + required String channelCid, + Value?> i18n, + Value?> restrictedVisibility, Value?> extraData, Value rowid, }); -typedef $$ChannelsTableUpdateCompanionBuilder = ChannelsCompanion Function({ +typedef $$MessagesTableUpdateCompanionBuilder = MessagesCompanion Function({ Value id, + Value messageText, + Value> attachments, + Value state, Value type, - Value cid, - Value?> ownCapabilities, - Value> config, - Value frozen, - Value lastMessageAt, - Value createdAt, - Value updatedAt, - Value deletedAt, - Value memberCount, - Value createdById, + Value> mentionedUsers, + Value?> reactionGroups, + Value parentId, + Value quotedMessageId, + Value pollId, + Value replyCount, + Value showInChannel, + Value shadowed, + Value command, + Value localCreatedAt, + Value remoteCreatedAt, + Value localUpdatedAt, + Value remoteUpdatedAt, + Value localDeletedAt, + Value remoteDeletedAt, + Value messageTextUpdatedAt, + Value userId, + Value pinned, + Value pinnedAt, + Value pinExpires, + Value pinnedByUserId, + Value channelCid, + Value?> i18n, + Value?> restrictedVisibility, Value?> extraData, Value rowid, }); -final class $$ChannelsTableReferences - extends BaseReferences<_$DriftChatDatabase, $ChannelsTable, ChannelEntity> { - $$ChannelsTableReferences(super.$_db, super.$_table, super.$_typedResult); +final class $$MessagesTableReferences + extends BaseReferences<_$DriftChatDatabase, $MessagesTable, MessageEntity> { + $$MessagesTableReferences(super.$_db, super.$_table, super.$_typedResult); - static MultiTypedResultKey<$MessagesTable, List> - _messagesRefsTable(_$DriftChatDatabase db) => - MultiTypedResultKey.fromTable(db.messages, - aliasName: $_aliasNameGenerator( - db.channels.cid, db.messages.channelCid)); + static $ChannelsTable _channelCidTable(_$DriftChatDatabase db) => + db.channels.createAlias( + $_aliasNameGenerator(db.messages.channelCid, db.channels.cid)); - $$MessagesTableProcessedTableManager get messagesRefs { - final manager = $$MessagesTableTableManager($_db, $_db.messages).filter( - (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + $$ChannelsTableProcessedTableManager get channelCid { + final $_column = $_itemColumn('channel_cid')!; - final cache = $_typedResult.readTableOrNull(_messagesRefsTable($_db)); + final manager = $$ChannelsTableTableManager($_db, $_db.channels) + .filter((f) => f.cid.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_channelCidTable($_db)); + if (item == null) return manager; return ProcessedTableManager( - manager.$state.copyWith(prefetchedData: cache)); + manager.$state.copyWith(prefetchedData: [item])); } static MultiTypedResultKey<$DraftMessagesTable, List> _draftMessagesRefsTable(_$DriftChatDatabase db) => MultiTypedResultKey.fromTable(db.draftMessages, aliasName: $_aliasNameGenerator( - db.channels.cid, db.draftMessages.channelCid)); + db.messages.id, db.draftMessages.parentId)); $$DraftMessagesTableProcessedTableManager get draftMessagesRefs { final manager = $$DraftMessagesTableTableManager($_db, $_db.draftMessages) - .filter( - (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + .filter((f) => f.parentId.id.sqlEquals($_itemColumn('id')!)); final cache = $_typedResult.readTableOrNull(_draftMessagesRefsTable($_db)); return ProcessedTableManager( manager.$state.copyWith(prefetchedData: cache)); } - static MultiTypedResultKey<$MembersTable, List> - _membersRefsTable(_$DriftChatDatabase db) => - MultiTypedResultKey.fromTable(db.members, + static MultiTypedResultKey<$LocationsTable, List> + _locationsRefsTable(_$DriftChatDatabase db) => + MultiTypedResultKey.fromTable(db.locations, aliasName: - $_aliasNameGenerator(db.channels.cid, db.members.channelCid)); + $_aliasNameGenerator(db.messages.id, db.locations.messageId)); - $$MembersTableProcessedTableManager get membersRefs { - final manager = $$MembersTableTableManager($_db, $_db.members).filter( - (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + $$LocationsTableProcessedTableManager get locationsRefs { + final manager = $$LocationsTableTableManager($_db, $_db.locations) + .filter((f) => f.messageId.id.sqlEquals($_itemColumn('id')!)); - final cache = $_typedResult.readTableOrNull(_membersRefsTable($_db)); + final cache = $_typedResult.readTableOrNull(_locationsRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } + + static MultiTypedResultKey<$ReactionsTable, List> + _reactionsRefsTable(_$DriftChatDatabase db) => + MultiTypedResultKey.fromTable(db.reactions, + aliasName: + $_aliasNameGenerator(db.messages.id, db.reactions.messageId)); + + $$ReactionsTableProcessedTableManager get reactionsRefs { + final manager = $$ReactionsTableTableManager($_db, $_db.reactions) + .filter((f) => f.messageId.id.sqlEquals($_itemColumn('id')!)); + + final cache = $_typedResult.readTableOrNull(_reactionsRefsTable($_db)); return ProcessedTableManager( manager.$state.copyWith(prefetchedData: cache)); } +} + +class $$MessagesTableFilterComposer + extends Composer<_$DriftChatDatabase, $MessagesTable> { + $$MessagesTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnFilters get messageText => $composableBuilder( + column: $table.messageText, builder: (column) => ColumnFilters(column)); + + ColumnWithTypeConverterFilters, List, String> + get attachments => $composableBuilder( + column: $table.attachments, + builder: (column) => ColumnWithTypeConverterFilters(column)); + + ColumnFilters get state => $composableBuilder( + column: $table.state, builder: (column) => ColumnFilters(column)); + + ColumnFilters get type => $composableBuilder( + column: $table.type, builder: (column) => ColumnFilters(column)); + + ColumnWithTypeConverterFilters, List, String> + get mentionedUsers => $composableBuilder( + column: $table.mentionedUsers, + builder: (column) => ColumnWithTypeConverterFilters(column)); + + ColumnWithTypeConverterFilters?, + Map, String> + get reactionGroups => $composableBuilder( + column: $table.reactionGroups, + builder: (column) => ColumnWithTypeConverterFilters(column)); + + ColumnFilters get parentId => $composableBuilder( + column: $table.parentId, builder: (column) => ColumnFilters(column)); + + ColumnFilters get quotedMessageId => $composableBuilder( + column: $table.quotedMessageId, + builder: (column) => ColumnFilters(column)); + + ColumnFilters get pollId => $composableBuilder( + column: $table.pollId, builder: (column) => ColumnFilters(column)); + + ColumnFilters get replyCount => $composableBuilder( + column: $table.replyCount, builder: (column) => ColumnFilters(column)); + + ColumnFilters get showInChannel => $composableBuilder( + column: $table.showInChannel, builder: (column) => ColumnFilters(column)); + + ColumnFilters get shadowed => $composableBuilder( + column: $table.shadowed, builder: (column) => ColumnFilters(column)); - static MultiTypedResultKey<$ReadsTable, List> _readsRefsTable( - _$DriftChatDatabase db) => - MultiTypedResultKey.fromTable(db.reads, - aliasName: - $_aliasNameGenerator(db.channels.cid, db.reads.channelCid)); + ColumnFilters get command => $composableBuilder( + column: $table.command, builder: (column) => ColumnFilters(column)); - $$ReadsTableProcessedTableManager get readsRefs { - final manager = $$ReadsTableTableManager($_db, $_db.reads).filter( - (f) => f.channelCid.cid.sqlEquals($_itemColumn('cid')!)); + ColumnFilters get localCreatedAt => $composableBuilder( + column: $table.localCreatedAt, + builder: (column) => ColumnFilters(column)); - final cache = $_typedResult.readTableOrNull(_readsRefsTable($_db)); - return ProcessedTableManager( - manager.$state.copyWith(prefetchedData: cache)); - } -} + ColumnFilters get remoteCreatedAt => $composableBuilder( + column: $table.remoteCreatedAt, + builder: (column) => ColumnFilters(column)); -class $$ChannelsTableFilterComposer - extends Composer<_$DriftChatDatabase, $ChannelsTable> { - $$ChannelsTableFilterComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - ColumnFilters get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnFilters(column)); + ColumnFilters get localUpdatedAt => $composableBuilder( + column: $table.localUpdatedAt, + builder: (column) => ColumnFilters(column)); - ColumnFilters get type => $composableBuilder( - column: $table.type, builder: (column) => ColumnFilters(column)); + ColumnFilters get remoteUpdatedAt => $composableBuilder( + column: $table.remoteUpdatedAt, + builder: (column) => ColumnFilters(column)); - ColumnFilters get cid => $composableBuilder( - column: $table.cid, builder: (column) => ColumnFilters(column)); + ColumnFilters get localDeletedAt => $composableBuilder( + column: $table.localDeletedAt, + builder: (column) => ColumnFilters(column)); - ColumnWithTypeConverterFilters?, List, String> - get ownCapabilities => $composableBuilder( - column: $table.ownCapabilities, - builder: (column) => ColumnWithTypeConverterFilters(column)); + ColumnFilters get remoteDeletedAt => $composableBuilder( + column: $table.remoteDeletedAt, + builder: (column) => ColumnFilters(column)); - ColumnWithTypeConverterFilters, Map, - String> - get config => $composableBuilder( - column: $table.config, - builder: (column) => ColumnWithTypeConverterFilters(column)); + ColumnFilters get messageTextUpdatedAt => $composableBuilder( + column: $table.messageTextUpdatedAt, + builder: (column) => ColumnFilters(column)); - ColumnFilters get frozen => $composableBuilder( - column: $table.frozen, builder: (column) => ColumnFilters(column)); + ColumnFilters get userId => $composableBuilder( + column: $table.userId, builder: (column) => ColumnFilters(column)); - ColumnFilters get lastMessageAt => $composableBuilder( - column: $table.lastMessageAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get pinned => $composableBuilder( + column: $table.pinned, builder: (column) => ColumnFilters(column)); - ColumnFilters get createdAt => $composableBuilder( - column: $table.createdAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get pinnedAt => $composableBuilder( + column: $table.pinnedAt, builder: (column) => ColumnFilters(column)); - ColumnFilters get updatedAt => $composableBuilder( - column: $table.updatedAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get pinExpires => $composableBuilder( + column: $table.pinExpires, builder: (column) => ColumnFilters(column)); - ColumnFilters get deletedAt => $composableBuilder( - column: $table.deletedAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get pinnedByUserId => $composableBuilder( + column: $table.pinnedByUserId, + builder: (column) => ColumnFilters(column)); - ColumnFilters get memberCount => $composableBuilder( - column: $table.memberCount, builder: (column) => ColumnFilters(column)); + ColumnWithTypeConverterFilters?, Map, + String> + get i18n => $composableBuilder( + column: $table.i18n, + builder: (column) => ColumnWithTypeConverterFilters(column)); - ColumnFilters get createdById => $composableBuilder( - column: $table.createdById, builder: (column) => ColumnFilters(column)); + ColumnWithTypeConverterFilters?, List, String> + get restrictedVisibility => $composableBuilder( + column: $table.restrictedVisibility, + builder: (column) => ColumnWithTypeConverterFilters(column)); ColumnWithTypeConverterFilters?, Map, String> @@ -8534,34 +9812,33 @@ class $$ChannelsTableFilterComposer column: $table.extraData, builder: (column) => ColumnWithTypeConverterFilters(column)); - Expression messagesRefs( - Expression Function($$MessagesTableFilterComposer f) f) { - final $$MessagesTableFilterComposer composer = $composerBuilder( + $$ChannelsTableFilterComposer get channelCid { + final $$ChannelsTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.cid, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.channelCid, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$MessagesTableFilterComposer( + $$ChannelsTableFilterComposer( $db: $db, - $table: $db.messages, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: $removeJoinBuilderFromRootComposer, )); - return f(composer); + return composer; } Expression draftMessagesRefs( Expression Function($$DraftMessagesTableFilterComposer f) f) { final $$DraftMessagesTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.cid, + getCurrentColumn: (t) => t.id, referencedTable: $db.draftMessages, - getReferencedColumn: (t) => t.channelCid, + getReferencedColumn: (t) => t.parentId, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => @@ -8576,178 +9853,307 @@ class $$ChannelsTableFilterComposer return f(composer); } - Expression membersRefs( - Expression Function($$MembersTableFilterComposer f) f) { - final $$MembersTableFilterComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.cid, - referencedTable: $db.members, - getReferencedColumn: (t) => t.channelCid, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$MembersTableFilterComposer( - $db: $db, - $table: $db.members, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return f(composer); - } + Expression locationsRefs( + Expression Function($$LocationsTableFilterComposer f) f) { + final $$LocationsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.locations, + getReferencedColumn: (t) => t.messageId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$LocationsTableFilterComposer( + $db: $db, + $table: $db.locations, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression reactionsRefs( + Expression Function($$ReactionsTableFilterComposer f) f) { + final $$ReactionsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.reactions, + getReferencedColumn: (t) => t.messageId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$ReactionsTableFilterComposer( + $db: $db, + $table: $db.reactions, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$MessagesTableOrderingComposer + extends Composer<_$DriftChatDatabase, $MessagesTable> { + $$MessagesTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get messageText => $composableBuilder( + column: $table.messageText, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get attachments => $composableBuilder( + column: $table.attachments, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get state => $composableBuilder( + column: $table.state, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get type => $composableBuilder( + column: $table.type, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get mentionedUsers => $composableBuilder( + column: $table.mentionedUsers, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get reactionGroups => $composableBuilder( + column: $table.reactionGroups, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get parentId => $composableBuilder( + column: $table.parentId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get quotedMessageId => $composableBuilder( + column: $table.quotedMessageId, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get pollId => $composableBuilder( + column: $table.pollId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get replyCount => $composableBuilder( + column: $table.replyCount, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get showInChannel => $composableBuilder( + column: $table.showInChannel, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get shadowed => $composableBuilder( + column: $table.shadowed, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get command => $composableBuilder( + column: $table.command, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get localCreatedAt => $composableBuilder( + column: $table.localCreatedAt, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get remoteCreatedAt => $composableBuilder( + column: $table.remoteCreatedAt, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get localUpdatedAt => $composableBuilder( + column: $table.localUpdatedAt, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get remoteUpdatedAt => $composableBuilder( + column: $table.remoteUpdatedAt, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get localDeletedAt => $composableBuilder( + column: $table.localDeletedAt, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get remoteDeletedAt => $composableBuilder( + column: $table.remoteDeletedAt, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get messageTextUpdatedAt => $composableBuilder( + column: $table.messageTextUpdatedAt, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get userId => $composableBuilder( + column: $table.userId, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get pinned => $composableBuilder( + column: $table.pinned, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get pinnedAt => $composableBuilder( + column: $table.pinnedAt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get pinExpires => $composableBuilder( + column: $table.pinExpires, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get pinnedByUserId => $composableBuilder( + column: $table.pinnedByUserId, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get i18n => $composableBuilder( + column: $table.i18n, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get restrictedVisibility => $composableBuilder( + column: $table.restrictedVisibility, + builder: (column) => ColumnOrderings(column)); - Expression readsRefs( - Expression Function($$ReadsTableFilterComposer f) f) { - final $$ReadsTableFilterComposer composer = $composerBuilder( + ColumnOrderings get extraData => $composableBuilder( + column: $table.extraData, builder: (column) => ColumnOrderings(column)); + + $$ChannelsTableOrderingComposer get channelCid { + final $$ChannelsTableOrderingComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.cid, - referencedTable: $db.reads, - getReferencedColumn: (t) => t.channelCid, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ReadsTableFilterComposer( + $$ChannelsTableOrderingComposer( $db: $db, - $table: $db.reads, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: $removeJoinBuilderFromRootComposer, )); - return f(composer); + return composer; } } -class $$ChannelsTableOrderingComposer - extends Composer<_$DriftChatDatabase, $ChannelsTable> { - $$ChannelsTableOrderingComposer({ +class $$MessagesTableAnnotationComposer + extends Composer<_$DriftChatDatabase, $MessagesTable> { + $$MessagesTableAnnotationComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnOrderings get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); - ColumnOrderings get type => $composableBuilder( - column: $table.type, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get messageText => $composableBuilder( + column: $table.messageText, builder: (column) => column); - ColumnOrderings get cid => $composableBuilder( - column: $table.cid, builder: (column) => ColumnOrderings(column)); + GeneratedColumnWithTypeConverter, String> get attachments => + $composableBuilder( + column: $table.attachments, builder: (column) => column); - ColumnOrderings get ownCapabilities => $composableBuilder( - column: $table.ownCapabilities, - builder: (column) => ColumnOrderings(column)); + GeneratedColumn get state => + $composableBuilder(column: $table.state, builder: (column) => column); - ColumnOrderings get config => $composableBuilder( - column: $table.config, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get type => + $composableBuilder(column: $table.type, builder: (column) => column); - ColumnOrderings get frozen => $composableBuilder( - column: $table.frozen, builder: (column) => ColumnOrderings(column)); + GeneratedColumnWithTypeConverter, String> get mentionedUsers => + $composableBuilder( + column: $table.mentionedUsers, builder: (column) => column); - ColumnOrderings get lastMessageAt => $composableBuilder( - column: $table.lastMessageAt, - builder: (column) => ColumnOrderings(column)); + GeneratedColumnWithTypeConverter?, String> + get reactionGroups => $composableBuilder( + column: $table.reactionGroups, builder: (column) => column); - ColumnOrderings get createdAt => $composableBuilder( - column: $table.createdAt, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get parentId => + $composableBuilder(column: $table.parentId, builder: (column) => column); - ColumnOrderings get updatedAt => $composableBuilder( - column: $table.updatedAt, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get quotedMessageId => $composableBuilder( + column: $table.quotedMessageId, builder: (column) => column); - ColumnOrderings get deletedAt => $composableBuilder( - column: $table.deletedAt, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get pollId => + $composableBuilder(column: $table.pollId, builder: (column) => column); - ColumnOrderings get memberCount => $composableBuilder( - column: $table.memberCount, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get replyCount => $composableBuilder( + column: $table.replyCount, builder: (column) => column); - ColumnOrderings get createdById => $composableBuilder( - column: $table.createdById, builder: (column) => ColumnOrderings(column)); + GeneratedColumn get showInChannel => $composableBuilder( + column: $table.showInChannel, builder: (column) => column); - ColumnOrderings get extraData => $composableBuilder( - column: $table.extraData, builder: (column) => ColumnOrderings(column)); -} + GeneratedColumn get shadowed => + $composableBuilder(column: $table.shadowed, builder: (column) => column); -class $$ChannelsTableAnnotationComposer - extends Composer<_$DriftChatDatabase, $ChannelsTable> { - $$ChannelsTableAnnotationComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - GeneratedColumn get id => - $composableBuilder(column: $table.id, builder: (column) => column); + GeneratedColumn get command => + $composableBuilder(column: $table.command, builder: (column) => column); - GeneratedColumn get type => - $composableBuilder(column: $table.type, builder: (column) => column); + GeneratedColumn get localCreatedAt => $composableBuilder( + column: $table.localCreatedAt, builder: (column) => column); - GeneratedColumn get cid => - $composableBuilder(column: $table.cid, builder: (column) => column); + GeneratedColumn get remoteCreatedAt => $composableBuilder( + column: $table.remoteCreatedAt, builder: (column) => column); - GeneratedColumnWithTypeConverter?, String> get ownCapabilities => - $composableBuilder( - column: $table.ownCapabilities, builder: (column) => column); + GeneratedColumn get localUpdatedAt => $composableBuilder( + column: $table.localUpdatedAt, builder: (column) => column); - GeneratedColumnWithTypeConverter, String> get config => - $composableBuilder(column: $table.config, builder: (column) => column); + GeneratedColumn get remoteUpdatedAt => $composableBuilder( + column: $table.remoteUpdatedAt, builder: (column) => column); - GeneratedColumn get frozen => - $composableBuilder(column: $table.frozen, builder: (column) => column); + GeneratedColumn get localDeletedAt => $composableBuilder( + column: $table.localDeletedAt, builder: (column) => column); - GeneratedColumn get lastMessageAt => $composableBuilder( - column: $table.lastMessageAt, builder: (column) => column); + GeneratedColumn get remoteDeletedAt => $composableBuilder( + column: $table.remoteDeletedAt, builder: (column) => column); - GeneratedColumn get createdAt => - $composableBuilder(column: $table.createdAt, builder: (column) => column); + GeneratedColumn get messageTextUpdatedAt => $composableBuilder( + column: $table.messageTextUpdatedAt, builder: (column) => column); - GeneratedColumn get updatedAt => - $composableBuilder(column: $table.updatedAt, builder: (column) => column); + GeneratedColumn get userId => + $composableBuilder(column: $table.userId, builder: (column) => column); - GeneratedColumn get deletedAt => - $composableBuilder(column: $table.deletedAt, builder: (column) => column); + GeneratedColumn get pinned => + $composableBuilder(column: $table.pinned, builder: (column) => column); - GeneratedColumn get memberCount => $composableBuilder( - column: $table.memberCount, builder: (column) => column); + GeneratedColumn get pinnedAt => + $composableBuilder(column: $table.pinnedAt, builder: (column) => column); - GeneratedColumn get createdById => $composableBuilder( - column: $table.createdById, builder: (column) => column); + GeneratedColumn get pinExpires => $composableBuilder( + column: $table.pinExpires, builder: (column) => column); + + GeneratedColumn get pinnedByUserId => $composableBuilder( + column: $table.pinnedByUserId, builder: (column) => column); + + GeneratedColumnWithTypeConverter?, String> get i18n => + $composableBuilder(column: $table.i18n, builder: (column) => column); + + GeneratedColumnWithTypeConverter?, String> + get restrictedVisibility => $composableBuilder( + column: $table.restrictedVisibility, builder: (column) => column); GeneratedColumnWithTypeConverter?, String> get extraData => $composableBuilder( column: $table.extraData, builder: (column) => column); - Expression messagesRefs( - Expression Function($$MessagesTableAnnotationComposer a) f) { - final $$MessagesTableAnnotationComposer composer = $composerBuilder( + $$ChannelsTableAnnotationComposer get channelCid { + final $$ChannelsTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.cid, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.channelCid, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$MessagesTableAnnotationComposer( + $$ChannelsTableAnnotationComposer( $db: $db, - $table: $db.messages, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: $removeJoinBuilderFromRootComposer, )); - return f(composer); + return composer; } Expression draftMessagesRefs( Expression Function($$DraftMessagesTableAnnotationComposer a) f) { final $$DraftMessagesTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.cid, + getCurrentColumn: (t) => t.id, referencedTable: $db.draftMessages, - getReferencedColumn: (t) => t.channelCid, + getReferencedColumn: (t) => t.parentId, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => @@ -8762,19 +10168,19 @@ class $$ChannelsTableAnnotationComposer return f(composer); } - Expression membersRefs( - Expression Function($$MembersTableAnnotationComposer a) f) { - final $$MembersTableAnnotationComposer composer = $composerBuilder( + Expression locationsRefs( + Expression Function($$LocationsTableAnnotationComposer a) f) { + final $$LocationsTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.cid, - referencedTable: $db.members, - getReferencedColumn: (t) => t.channelCid, + getCurrentColumn: (t) => t.id, + referencedTable: $db.locations, + getReferencedColumn: (t) => t.messageId, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$MembersTableAnnotationComposer( + $$LocationsTableAnnotationComposer( $db: $db, - $table: $db.members, + $table: $db.locations, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -8783,19 +10189,19 @@ class $$ChannelsTableAnnotationComposer return f(composer); } - Expression readsRefs( - Expression Function($$ReadsTableAnnotationComposer a) f) { - final $$ReadsTableAnnotationComposer composer = $composerBuilder( + Expression reactionsRefs( + Expression Function($$ReactionsTableAnnotationComposer a) f) { + final $$ReactionsTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.cid, - referencedTable: $db.reads, - getReferencedColumn: (t) => t.channelCid, + getCurrentColumn: (t) => t.id, + referencedTable: $db.reactions, + getReferencedColumn: (t) => t.messageId, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ReadsTableAnnotationComposer( + $$ReactionsTableAnnotationComposer( $db: $db, - $table: $db.reads, + $table: $db.reactions, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -8805,166 +10211,248 @@ class $$ChannelsTableAnnotationComposer } } -class $$ChannelsTableTableManager extends RootTableManager< +class $$MessagesTableTableManager extends RootTableManager< _$DriftChatDatabase, - $ChannelsTable, - ChannelEntity, - $$ChannelsTableFilterComposer, - $$ChannelsTableOrderingComposer, - $$ChannelsTableAnnotationComposer, - $$ChannelsTableCreateCompanionBuilder, - $$ChannelsTableUpdateCompanionBuilder, - (ChannelEntity, $$ChannelsTableReferences), - ChannelEntity, + $MessagesTable, + MessageEntity, + $$MessagesTableFilterComposer, + $$MessagesTableOrderingComposer, + $$MessagesTableAnnotationComposer, + $$MessagesTableCreateCompanionBuilder, + $$MessagesTableUpdateCompanionBuilder, + (MessageEntity, $$MessagesTableReferences), + MessageEntity, PrefetchHooks Function( - {bool messagesRefs, + {bool channelCid, bool draftMessagesRefs, - bool membersRefs, - bool readsRefs})> { - $$ChannelsTableTableManager(_$DriftChatDatabase db, $ChannelsTable table) + bool locationsRefs, + bool reactionsRefs})> { + $$MessagesTableTableManager(_$DriftChatDatabase db, $MessagesTable table) : super(TableManagerState( db: db, table: table, createFilteringComposer: () => - $$ChannelsTableFilterComposer($db: db, $table: table), + $$MessagesTableFilterComposer($db: db, $table: table), createOrderingComposer: () => - $$ChannelsTableOrderingComposer($db: db, $table: table), + $$MessagesTableOrderingComposer($db: db, $table: table), createComputedFieldComposer: () => - $$ChannelsTableAnnotationComposer($db: db, $table: table), + $$MessagesTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ Value id = const Value.absent(), + Value messageText = const Value.absent(), + Value> attachments = const Value.absent(), + Value state = const Value.absent(), Value type = const Value.absent(), - Value cid = const Value.absent(), - Value?> ownCapabilities = const Value.absent(), - Value> config = const Value.absent(), - Value frozen = const Value.absent(), - Value lastMessageAt = const Value.absent(), - Value createdAt = const Value.absent(), - Value updatedAt = const Value.absent(), - Value deletedAt = const Value.absent(), - Value memberCount = const Value.absent(), - Value createdById = const Value.absent(), + Value> mentionedUsers = const Value.absent(), + Value?> reactionGroups = + const Value.absent(), + Value parentId = const Value.absent(), + Value quotedMessageId = const Value.absent(), + Value pollId = const Value.absent(), + Value replyCount = const Value.absent(), + Value showInChannel = const Value.absent(), + Value shadowed = const Value.absent(), + Value command = const Value.absent(), + Value localCreatedAt = const Value.absent(), + Value remoteCreatedAt = const Value.absent(), + Value localUpdatedAt = const Value.absent(), + Value remoteUpdatedAt = const Value.absent(), + Value localDeletedAt = const Value.absent(), + Value remoteDeletedAt = const Value.absent(), + Value messageTextUpdatedAt = const Value.absent(), + Value userId = const Value.absent(), + Value pinned = const Value.absent(), + Value pinnedAt = const Value.absent(), + Value pinExpires = const Value.absent(), + Value pinnedByUserId = const Value.absent(), + Value channelCid = const Value.absent(), + Value?> i18n = const Value.absent(), + Value?> restrictedVisibility = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), }) => - ChannelsCompanion( + MessagesCompanion( id: id, + messageText: messageText, + attachments: attachments, + state: state, type: type, - cid: cid, - ownCapabilities: ownCapabilities, - config: config, - frozen: frozen, - lastMessageAt: lastMessageAt, - createdAt: createdAt, - updatedAt: updatedAt, - deletedAt: deletedAt, - memberCount: memberCount, - createdById: createdById, + mentionedUsers: mentionedUsers, + reactionGroups: reactionGroups, + parentId: parentId, + quotedMessageId: quotedMessageId, + pollId: pollId, + replyCount: replyCount, + showInChannel: showInChannel, + shadowed: shadowed, + command: command, + localCreatedAt: localCreatedAt, + remoteCreatedAt: remoteCreatedAt, + localUpdatedAt: localUpdatedAt, + remoteUpdatedAt: remoteUpdatedAt, + localDeletedAt: localDeletedAt, + remoteDeletedAt: remoteDeletedAt, + messageTextUpdatedAt: messageTextUpdatedAt, + userId: userId, + pinned: pinned, + pinnedAt: pinnedAt, + pinExpires: pinExpires, + pinnedByUserId: pinnedByUserId, + channelCid: channelCid, + i18n: i18n, + restrictedVisibility: restrictedVisibility, extraData: extraData, rowid: rowid, ), createCompanionCallback: ({ required String id, - required String type, - required String cid, - Value?> ownCapabilities = const Value.absent(), - required Map config, - Value frozen = const Value.absent(), - Value lastMessageAt = const Value.absent(), - Value createdAt = const Value.absent(), - Value updatedAt = const Value.absent(), - Value deletedAt = const Value.absent(), - Value memberCount = const Value.absent(), - Value createdById = const Value.absent(), + Value messageText = const Value.absent(), + required List attachments, + required String state, + Value type = const Value.absent(), + required List mentionedUsers, + Value?> reactionGroups = + const Value.absent(), + Value parentId = const Value.absent(), + Value quotedMessageId = const Value.absent(), + Value pollId = const Value.absent(), + Value replyCount = const Value.absent(), + Value showInChannel = const Value.absent(), + Value shadowed = const Value.absent(), + Value command = const Value.absent(), + Value localCreatedAt = const Value.absent(), + Value remoteCreatedAt = const Value.absent(), + Value localUpdatedAt = const Value.absent(), + Value remoteUpdatedAt = const Value.absent(), + Value localDeletedAt = const Value.absent(), + Value remoteDeletedAt = const Value.absent(), + Value messageTextUpdatedAt = const Value.absent(), + Value userId = const Value.absent(), + Value pinned = const Value.absent(), + Value pinnedAt = const Value.absent(), + Value pinExpires = const Value.absent(), + Value pinnedByUserId = const Value.absent(), + required String channelCid, + Value?> i18n = const Value.absent(), + Value?> restrictedVisibility = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), }) => - ChannelsCompanion.insert( + MessagesCompanion.insert( id: id, + messageText: messageText, + attachments: attachments, + state: state, type: type, - cid: cid, - ownCapabilities: ownCapabilities, - config: config, - frozen: frozen, - lastMessageAt: lastMessageAt, - createdAt: createdAt, - updatedAt: updatedAt, - deletedAt: deletedAt, - memberCount: memberCount, - createdById: createdById, + mentionedUsers: mentionedUsers, + reactionGroups: reactionGroups, + parentId: parentId, + quotedMessageId: quotedMessageId, + pollId: pollId, + replyCount: replyCount, + showInChannel: showInChannel, + shadowed: shadowed, + command: command, + localCreatedAt: localCreatedAt, + remoteCreatedAt: remoteCreatedAt, + localUpdatedAt: localUpdatedAt, + remoteUpdatedAt: remoteUpdatedAt, + localDeletedAt: localDeletedAt, + remoteDeletedAt: remoteDeletedAt, + messageTextUpdatedAt: messageTextUpdatedAt, + userId: userId, + pinned: pinned, + pinnedAt: pinnedAt, + pinExpires: pinExpires, + pinnedByUserId: pinnedByUserId, + channelCid: channelCid, + i18n: i18n, + restrictedVisibility: restrictedVisibility, extraData: extraData, rowid: rowid, ), withReferenceMapper: (p0) => p0 .map((e) => - (e.readTable(table), $$ChannelsTableReferences(db, table, e))) + (e.readTable(table), $$MessagesTableReferences(db, table, e))) .toList(), prefetchHooksCallback: ( - {messagesRefs = false, + {channelCid = false, draftMessagesRefs = false, - membersRefs = false, - readsRefs = false}) { + locationsRefs = false, + reactionsRefs = false}) { return PrefetchHooks( db: db, explicitlyWatchedTables: [ - if (messagesRefs) db.messages, if (draftMessagesRefs) db.draftMessages, - if (membersRefs) db.members, - if (readsRefs) db.reads + if (locationsRefs) db.locations, + if (reactionsRefs) db.reactions ], - addJoins: null, + addJoins: < + T extends TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (channelCid) { + state = state.withJoin( + currentTable: table, + currentColumn: table.channelCid, + referencedTable: + $$MessagesTableReferences._channelCidTable(db), + referencedColumn: + $$MessagesTableReferences._channelCidTable(db).cid, + ) as T; + } + + return state; + }, getPrefetchedDataCallback: (items) async { return [ - if (messagesRefs) - await $_getPrefetchedData( - currentTable: table, - referencedTable: - $$ChannelsTableReferences._messagesRefsTable(db), - managerFromTypedResult: (p0) => - $$ChannelsTableReferences(db, table, p0) - .messagesRefs, - referencedItemsForCurrentItem: - (item, referencedItems) => referencedItems - .where((e) => e.channelCid == item.cid), - typedResults: items), if (draftMessagesRefs) - await $_getPrefetchedData( currentTable: table, - referencedTable: $$ChannelsTableReferences + referencedTable: $$MessagesTableReferences ._draftMessagesRefsTable(db), managerFromTypedResult: (p0) => - $$ChannelsTableReferences(db, table, p0) + $$MessagesTableReferences(db, table, p0) .draftMessagesRefs, - referencedItemsForCurrentItem: - (item, referencedItems) => referencedItems - .where((e) => e.channelCid == item.cid), + referencedItemsForCurrentItem: (item, + referencedItems) => + referencedItems.where((e) => e.parentId == item.id), typedResults: items), - if (membersRefs) - await $_getPrefetchedData( + if (locationsRefs) + await $_getPrefetchedData( currentTable: table, referencedTable: - $$ChannelsTableReferences._membersRefsTable(db), + $$MessagesTableReferences._locationsRefsTable(db), managerFromTypedResult: (p0) => - $$ChannelsTableReferences(db, table, p0) - .membersRefs, + $$MessagesTableReferences(db, table, p0) + .locationsRefs, referencedItemsForCurrentItem: (item, referencedItems) => referencedItems - .where((e) => e.channelCid == item.cid), + .where((e) => e.messageId == item.id), typedResults: items), - if (readsRefs) - await $_getPrefetchedData( + if (reactionsRefs) + await $_getPrefetchedData( currentTable: table, referencedTable: - $$ChannelsTableReferences._readsRefsTable(db), + $$MessagesTableReferences._reactionsRefsTable(db), managerFromTypedResult: (p0) => - $$ChannelsTableReferences(db, table, p0).readsRefs, + $$MessagesTableReferences(db, table, p0) + .reactionsRefs, referencedItemsForCurrentItem: (item, referencedItems) => referencedItems - .where((e) => e.channelCid == item.cid), + .where((e) => e.messageId == item.id), typedResults: items) ]; }, @@ -8973,96 +10461,82 @@ class $$ChannelsTableTableManager extends RootTableManager< )); } -typedef $$ChannelsTableProcessedTableManager = ProcessedTableManager< +typedef $$MessagesTableProcessedTableManager = ProcessedTableManager< _$DriftChatDatabase, - $ChannelsTable, - ChannelEntity, - $$ChannelsTableFilterComposer, - $$ChannelsTableOrderingComposer, - $$ChannelsTableAnnotationComposer, - $$ChannelsTableCreateCompanionBuilder, - $$ChannelsTableUpdateCompanionBuilder, - (ChannelEntity, $$ChannelsTableReferences), - ChannelEntity, + $MessagesTable, + MessageEntity, + $$MessagesTableFilterComposer, + $$MessagesTableOrderingComposer, + $$MessagesTableAnnotationComposer, + $$MessagesTableCreateCompanionBuilder, + $$MessagesTableUpdateCompanionBuilder, + (MessageEntity, $$MessagesTableReferences), + MessageEntity, PrefetchHooks Function( - {bool messagesRefs, + {bool channelCid, bool draftMessagesRefs, - bool membersRefs, - bool readsRefs})>; -typedef $$MessagesTableCreateCompanionBuilder = MessagesCompanion Function({ + bool locationsRefs, + bool reactionsRefs})>; +typedef $$DraftMessagesTableCreateCompanionBuilder = DraftMessagesCompanion + Function({ required String id, Value messageText, required List attachments, - required String state, Value type, required List mentionedUsers, - Value?> reactionGroups, Value parentId, Value quotedMessageId, Value pollId, - Value replyCount, Value showInChannel, - Value shadowed, Value command, - Value localCreatedAt, - Value remoteCreatedAt, - Value localUpdatedAt, - Value remoteUpdatedAt, - Value localDeletedAt, - Value remoteDeletedAt, - Value messageTextUpdatedAt, - Value userId, - Value pinned, - Value pinnedAt, - Value pinExpires, - Value pinnedByUserId, + Value silent, + Value createdAt, required String channelCid, - Value?> i18n, - Value?> restrictedVisibility, Value?> extraData, Value rowid, }); -typedef $$MessagesTableUpdateCompanionBuilder = MessagesCompanion Function({ +typedef $$DraftMessagesTableUpdateCompanionBuilder = DraftMessagesCompanion + Function({ Value id, Value messageText, Value> attachments, - Value state, Value type, Value> mentionedUsers, - Value?> reactionGroups, Value parentId, Value quotedMessageId, Value pollId, - Value replyCount, Value showInChannel, - Value shadowed, Value command, - Value localCreatedAt, - Value remoteCreatedAt, - Value localUpdatedAt, - Value remoteUpdatedAt, - Value localDeletedAt, - Value remoteDeletedAt, - Value messageTextUpdatedAt, - Value userId, - Value pinned, - Value pinnedAt, - Value pinExpires, - Value pinnedByUserId, + Value silent, + Value createdAt, Value channelCid, - Value?> i18n, - Value?> restrictedVisibility, Value?> extraData, Value rowid, }); -final class $$MessagesTableReferences - extends BaseReferences<_$DriftChatDatabase, $MessagesTable, MessageEntity> { - $$MessagesTableReferences(super.$_db, super.$_table, super.$_typedResult); +final class $$DraftMessagesTableReferences extends BaseReferences< + _$DriftChatDatabase, $DraftMessagesTable, DraftMessageEntity> { + $$DraftMessagesTableReferences( + super.$_db, super.$_table, super.$_typedResult); + + static $MessagesTable _parentIdTable(_$DriftChatDatabase db) => + db.messages.createAlias( + $_aliasNameGenerator(db.draftMessages.parentId, db.messages.id)); + + $$MessagesTableProcessedTableManager? get parentId { + final $_column = $_itemColumn('parent_id'); + if ($_column == null) return null; + final manager = $$MessagesTableTableManager($_db, $_db.messages) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_parentIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } static $ChannelsTable _channelCidTable(_$DriftChatDatabase db) => db.channels.createAlias( - $_aliasNameGenerator(db.messages.channelCid, db.channels.cid)); + $_aliasNameGenerator(db.draftMessages.channelCid, db.channels.cid)); $$ChannelsTableProcessedTableManager get channelCid { final $_column = $_itemColumn('channel_cid')!; @@ -9074,41 +10548,11 @@ final class $$MessagesTableReferences return ProcessedTableManager( manager.$state.copyWith(prefetchedData: [item])); } - - static MultiTypedResultKey<$DraftMessagesTable, List> - _draftMessagesRefsTable(_$DriftChatDatabase db) => - MultiTypedResultKey.fromTable(db.draftMessages, - aliasName: $_aliasNameGenerator( - db.messages.id, db.draftMessages.parentId)); - - $$DraftMessagesTableProcessedTableManager get draftMessagesRefs { - final manager = $$DraftMessagesTableTableManager($_db, $_db.draftMessages) - .filter((f) => f.parentId.id.sqlEquals($_itemColumn('id')!)); - - final cache = $_typedResult.readTableOrNull(_draftMessagesRefsTable($_db)); - return ProcessedTableManager( - manager.$state.copyWith(prefetchedData: cache)); - } - - static MultiTypedResultKey<$ReactionsTable, List> - _reactionsRefsTable(_$DriftChatDatabase db) => - MultiTypedResultKey.fromTable(db.reactions, - aliasName: - $_aliasNameGenerator(db.messages.id, db.reactions.messageId)); - - $$ReactionsTableProcessedTableManager get reactionsRefs { - final manager = $$ReactionsTableTableManager($_db, $_db.reactions) - .filter((f) => f.messageId.id.sqlEquals($_itemColumn('id')!)); - - final cache = $_typedResult.readTableOrNull(_reactionsRefsTable($_db)); - return ProcessedTableManager( - manager.$state.copyWith(prefetchedData: cache)); - } } -class $$MessagesTableFilterComposer - extends Composer<_$DriftChatDatabase, $MessagesTable> { - $$MessagesTableFilterComposer({ +class $$DraftMessagesTableFilterComposer + extends Composer<_$DriftChatDatabase, $DraftMessagesTable> { + $$DraftMessagesTableFilterComposer({ required super.$db, required super.$table, super.joinBuilder, @@ -9126,9 +10570,6 @@ class $$MessagesTableFilterComposer column: $table.attachments, builder: (column) => ColumnWithTypeConverterFilters(column)); - ColumnFilters get state => $composableBuilder( - column: $table.state, builder: (column) => ColumnFilters(column)); - ColumnFilters get type => $composableBuilder( column: $table.type, builder: (column) => ColumnFilters(column)); @@ -9137,15 +10578,6 @@ class $$MessagesTableFilterComposer column: $table.mentionedUsers, builder: (column) => ColumnWithTypeConverterFilters(column)); - ColumnWithTypeConverterFilters?, - Map, String> - get reactionGroups => $composableBuilder( - column: $table.reactionGroups, - builder: (column) => ColumnWithTypeConverterFilters(column)); - - ColumnFilters get parentId => $composableBuilder( - column: $table.parentId, builder: (column) => ColumnFilters(column)); - ColumnFilters get quotedMessageId => $composableBuilder( column: $table.quotedMessageId, builder: (column) => ColumnFilters(column)); @@ -9153,72 +10585,17 @@ class $$MessagesTableFilterComposer ColumnFilters get pollId => $composableBuilder( column: $table.pollId, builder: (column) => ColumnFilters(column)); - ColumnFilters get replyCount => $composableBuilder( - column: $table.replyCount, builder: (column) => ColumnFilters(column)); - ColumnFilters get showInChannel => $composableBuilder( column: $table.showInChannel, builder: (column) => ColumnFilters(column)); - ColumnFilters get shadowed => $composableBuilder( - column: $table.shadowed, builder: (column) => ColumnFilters(column)); - ColumnFilters get command => $composableBuilder( column: $table.command, builder: (column) => ColumnFilters(column)); - ColumnFilters get localCreatedAt => $composableBuilder( - column: $table.localCreatedAt, - builder: (column) => ColumnFilters(column)); - - ColumnFilters get remoteCreatedAt => $composableBuilder( - column: $table.remoteCreatedAt, - builder: (column) => ColumnFilters(column)); - - ColumnFilters get localUpdatedAt => $composableBuilder( - column: $table.localUpdatedAt, - builder: (column) => ColumnFilters(column)); - - ColumnFilters get remoteUpdatedAt => $composableBuilder( - column: $table.remoteUpdatedAt, - builder: (column) => ColumnFilters(column)); - - ColumnFilters get localDeletedAt => $composableBuilder( - column: $table.localDeletedAt, - builder: (column) => ColumnFilters(column)); - - ColumnFilters get remoteDeletedAt => $composableBuilder( - column: $table.remoteDeletedAt, - builder: (column) => ColumnFilters(column)); - - ColumnFilters get messageTextUpdatedAt => $composableBuilder( - column: $table.messageTextUpdatedAt, - builder: (column) => ColumnFilters(column)); - - ColumnFilters get userId => $composableBuilder( - column: $table.userId, builder: (column) => ColumnFilters(column)); - - ColumnFilters get pinned => $composableBuilder( - column: $table.pinned, builder: (column) => ColumnFilters(column)); - - ColumnFilters get pinnedAt => $composableBuilder( - column: $table.pinnedAt, builder: (column) => ColumnFilters(column)); - - ColumnFilters get pinExpires => $composableBuilder( - column: $table.pinExpires, builder: (column) => ColumnFilters(column)); - - ColumnFilters get pinnedByUserId => $composableBuilder( - column: $table.pinnedByUserId, - builder: (column) => ColumnFilters(column)); - - ColumnWithTypeConverterFilters?, Map, - String> - get i18n => $composableBuilder( - column: $table.i18n, - builder: (column) => ColumnWithTypeConverterFilters(column)); + ColumnFilters get silent => $composableBuilder( + column: $table.silent, builder: (column) => ColumnFilters(column)); - ColumnWithTypeConverterFilters?, List, String> - get restrictedVisibility => $composableBuilder( - column: $table.restrictedVisibility, - builder: (column) => ColumnWithTypeConverterFilters(column)); + ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnFilters(column)); ColumnWithTypeConverterFilters?, Map, String> @@ -9226,18 +10603,18 @@ class $$MessagesTableFilterComposer column: $table.extraData, builder: (column) => ColumnWithTypeConverterFilters(column)); - $$ChannelsTableFilterComposer get channelCid { - final $$ChannelsTableFilterComposer composer = $composerBuilder( + $$MessagesTableFilterComposer get parentId { + final $$MessagesTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.channelCid, - referencedTable: $db.channels, - getReferencedColumn: (t) => t.cid, + getCurrentColumn: (t) => t.parentId, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ChannelsTableFilterComposer( + $$MessagesTableFilterComposer( $db: $db, - $table: $db.channels, + $table: $db.messages, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -9246,52 +10623,30 @@ class $$MessagesTableFilterComposer return composer; } - Expression draftMessagesRefs( - Expression Function($$DraftMessagesTableFilterComposer f) f) { - final $$DraftMessagesTableFilterComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.id, - referencedTable: $db.draftMessages, - getReferencedColumn: (t) => t.parentId, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$DraftMessagesTableFilterComposer( - $db: $db, - $table: $db.draftMessages, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return f(composer); - } - - Expression reactionsRefs( - Expression Function($$ReactionsTableFilterComposer f) f) { - final $$ReactionsTableFilterComposer composer = $composerBuilder( + $$ChannelsTableFilterComposer get channelCid { + final $$ChannelsTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.id, - referencedTable: $db.reactions, - getReferencedColumn: (t) => t.messageId, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ReactionsTableFilterComposer( + $$ChannelsTableFilterComposer( $db: $db, - $table: $db.reactions, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: $removeJoinBuilderFromRootComposer, )); - return f(composer); + return composer; } } -class $$MessagesTableOrderingComposer - extends Composer<_$DriftChatDatabase, $MessagesTable> { - $$MessagesTableOrderingComposer({ +class $$DraftMessagesTableOrderingComposer + extends Composer<_$DriftChatDatabase, $DraftMessagesTable> { + $$DraftMessagesTableOrderingComposer({ required super.$db, required super.$table, super.joinBuilder, @@ -9307,22 +10662,12 @@ class $$MessagesTableOrderingComposer ColumnOrderings get attachments => $composableBuilder( column: $table.attachments, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get state => $composableBuilder( - column: $table.state, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get type => $composableBuilder( column: $table.type, builder: (column) => ColumnOrderings(column)); ColumnOrderings get mentionedUsers => $composableBuilder( column: $table.mentionedUsers, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get reactionGroups => $composableBuilder( - column: $table.reactionGroups, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get parentId => $composableBuilder( - column: $table.parentId, builder: (column) => ColumnOrderings(column)); + builder: (column) => ColumnOrderings(column)); ColumnOrderings get quotedMessageId => $composableBuilder( column: $table.quotedMessageId, @@ -9331,73 +10676,42 @@ class $$MessagesTableOrderingComposer ColumnOrderings get pollId => $composableBuilder( column: $table.pollId, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get replyCount => $composableBuilder( - column: $table.replyCount, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get showInChannel => $composableBuilder( column: $table.showInChannel, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get shadowed => $composableBuilder( - column: $table.shadowed, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get command => $composableBuilder( column: $table.command, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get localCreatedAt => $composableBuilder( - column: $table.localCreatedAt, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get remoteCreatedAt => $composableBuilder( - column: $table.remoteCreatedAt, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get localUpdatedAt => $composableBuilder( - column: $table.localUpdatedAt, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get remoteUpdatedAt => $composableBuilder( - column: $table.remoteUpdatedAt, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get localDeletedAt => $composableBuilder( - column: $table.localDeletedAt, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get remoteDeletedAt => $composableBuilder( - column: $table.remoteDeletedAt, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get messageTextUpdatedAt => $composableBuilder( - column: $table.messageTextUpdatedAt, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get userId => $composableBuilder( - column: $table.userId, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get pinned => $composableBuilder( - column: $table.pinned, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get pinnedAt => $composableBuilder( - column: $table.pinnedAt, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get pinExpires => $composableBuilder( - column: $table.pinExpires, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get pinnedByUserId => $composableBuilder( - column: $table.pinnedByUserId, - builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get i18n => $composableBuilder( - column: $table.i18n, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get silent => $composableBuilder( + column: $table.silent, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get restrictedVisibility => $composableBuilder( - column: $table.restrictedVisibility, - builder: (column) => ColumnOrderings(column)); + ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnOrderings(column)); ColumnOrderings get extraData => $composableBuilder( column: $table.extraData, builder: (column) => ColumnOrderings(column)); + $$MessagesTableOrderingComposer get parentId { + final $$MessagesTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.parentId, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MessagesTableOrderingComposer( + $db: $db, + $table: $db.messages, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + $$ChannelsTableOrderingComposer get channelCid { final $$ChannelsTableOrderingComposer composer = $composerBuilder( composer: this, @@ -9419,9 +10733,9 @@ class $$MessagesTableOrderingComposer } } -class $$MessagesTableAnnotationComposer - extends Composer<_$DriftChatDatabase, $MessagesTable> { - $$MessagesTableAnnotationComposer({ +class $$DraftMessagesTableAnnotationComposer + extends Composer<_$DriftChatDatabase, $DraftMessagesTable> { + $$DraftMessagesTableAnnotationComposer({ required super.$db, required super.$table, super.joinBuilder, @@ -9438,9 +10752,6 @@ class $$MessagesTableAnnotationComposer $composableBuilder( column: $table.attachments, builder: (column) => column); - GeneratedColumn get state => - $composableBuilder(column: $table.state, builder: (column) => column); - GeneratedColumn get type => $composableBuilder(column: $table.type, builder: (column) => column); @@ -9448,90 +10759,40 @@ class $$MessagesTableAnnotationComposer $composableBuilder( column: $table.mentionedUsers, builder: (column) => column); - GeneratedColumnWithTypeConverter?, String> - get reactionGroups => $composableBuilder( - column: $table.reactionGroups, builder: (column) => column); - - GeneratedColumn get parentId => - $composableBuilder(column: $table.parentId, builder: (column) => column); - GeneratedColumn get quotedMessageId => $composableBuilder( column: $table.quotedMessageId, builder: (column) => column); GeneratedColumn get pollId => $composableBuilder(column: $table.pollId, builder: (column) => column); - GeneratedColumn get replyCount => $composableBuilder( - column: $table.replyCount, builder: (column) => column); - GeneratedColumn get showInChannel => $composableBuilder( column: $table.showInChannel, builder: (column) => column); - GeneratedColumn get shadowed => - $composableBuilder(column: $table.shadowed, builder: (column) => column); - GeneratedColumn get command => $composableBuilder(column: $table.command, builder: (column) => column); - GeneratedColumn get localCreatedAt => $composableBuilder( - column: $table.localCreatedAt, builder: (column) => column); - - GeneratedColumn get remoteCreatedAt => $composableBuilder( - column: $table.remoteCreatedAt, builder: (column) => column); - - GeneratedColumn get localUpdatedAt => $composableBuilder( - column: $table.localUpdatedAt, builder: (column) => column); - - GeneratedColumn get remoteUpdatedAt => $composableBuilder( - column: $table.remoteUpdatedAt, builder: (column) => column); - - GeneratedColumn get localDeletedAt => $composableBuilder( - column: $table.localDeletedAt, builder: (column) => column); - - GeneratedColumn get remoteDeletedAt => $composableBuilder( - column: $table.remoteDeletedAt, builder: (column) => column); - - GeneratedColumn get messageTextUpdatedAt => $composableBuilder( - column: $table.messageTextUpdatedAt, builder: (column) => column); - - GeneratedColumn get userId => - $composableBuilder(column: $table.userId, builder: (column) => column); - - GeneratedColumn get pinned => - $composableBuilder(column: $table.pinned, builder: (column) => column); - - GeneratedColumn get pinnedAt => - $composableBuilder(column: $table.pinnedAt, builder: (column) => column); - - GeneratedColumn get pinExpires => $composableBuilder( - column: $table.pinExpires, builder: (column) => column); - - GeneratedColumn get pinnedByUserId => $composableBuilder( - column: $table.pinnedByUserId, builder: (column) => column); - - GeneratedColumnWithTypeConverter?, String> get i18n => - $composableBuilder(column: $table.i18n, builder: (column) => column); + GeneratedColumn get silent => + $composableBuilder(column: $table.silent, builder: (column) => column); - GeneratedColumnWithTypeConverter?, String> - get restrictedVisibility => $composableBuilder( - column: $table.restrictedVisibility, builder: (column) => column); + GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); GeneratedColumnWithTypeConverter?, String> get extraData => $composableBuilder( column: $table.extraData, builder: (column) => column); - $$ChannelsTableAnnotationComposer get channelCid { - final $$ChannelsTableAnnotationComposer composer = $composerBuilder( + $$MessagesTableAnnotationComposer get parentId { + final $$MessagesTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.channelCid, - referencedTable: $db.channels, - getReferencedColumn: (t) => t.cid, + getCurrentColumn: (t) => t.parentId, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ChannelsTableAnnotationComposer( + $$MessagesTableAnnotationComposer( $db: $db, - $table: $db.channels, + $table: $db.messages, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -9540,136 +10801,81 @@ class $$MessagesTableAnnotationComposer return composer; } - Expression draftMessagesRefs( - Expression Function($$DraftMessagesTableAnnotationComposer a) f) { - final $$DraftMessagesTableAnnotationComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.id, - referencedTable: $db.draftMessages, - getReferencedColumn: (t) => t.parentId, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$DraftMessagesTableAnnotationComposer( - $db: $db, - $table: $db.draftMessages, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return f(composer); - } - - Expression reactionsRefs( - Expression Function($$ReactionsTableAnnotationComposer a) f) { - final $$ReactionsTableAnnotationComposer composer = $composerBuilder( + $$ChannelsTableAnnotationComposer get channelCid { + final $$ChannelsTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.id, - referencedTable: $db.reactions, - getReferencedColumn: (t) => t.messageId, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ReactionsTableAnnotationComposer( + $$ChannelsTableAnnotationComposer( $db: $db, - $table: $db.reactions, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: $removeJoinBuilderFromRootComposer, )); - return f(composer); + return composer; } } -class $$MessagesTableTableManager extends RootTableManager< +class $$DraftMessagesTableTableManager extends RootTableManager< _$DriftChatDatabase, - $MessagesTable, - MessageEntity, - $$MessagesTableFilterComposer, - $$MessagesTableOrderingComposer, - $$MessagesTableAnnotationComposer, - $$MessagesTableCreateCompanionBuilder, - $$MessagesTableUpdateCompanionBuilder, - (MessageEntity, $$MessagesTableReferences), - MessageEntity, - PrefetchHooks Function( - {bool channelCid, bool draftMessagesRefs, bool reactionsRefs})> { - $$MessagesTableTableManager(_$DriftChatDatabase db, $MessagesTable table) + $DraftMessagesTable, + DraftMessageEntity, + $$DraftMessagesTableFilterComposer, + $$DraftMessagesTableOrderingComposer, + $$DraftMessagesTableAnnotationComposer, + $$DraftMessagesTableCreateCompanionBuilder, + $$DraftMessagesTableUpdateCompanionBuilder, + (DraftMessageEntity, $$DraftMessagesTableReferences), + DraftMessageEntity, + PrefetchHooks Function({bool parentId, bool channelCid})> { + $$DraftMessagesTableTableManager( + _$DriftChatDatabase db, $DraftMessagesTable table) : super(TableManagerState( db: db, table: table, createFilteringComposer: () => - $$MessagesTableFilterComposer($db: db, $table: table), + $$DraftMessagesTableFilterComposer($db: db, $table: table), createOrderingComposer: () => - $$MessagesTableOrderingComposer($db: db, $table: table), + $$DraftMessagesTableOrderingComposer($db: db, $table: table), createComputedFieldComposer: () => - $$MessagesTableAnnotationComposer($db: db, $table: table), + $$DraftMessagesTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ Value id = const Value.absent(), Value messageText = const Value.absent(), Value> attachments = const Value.absent(), - Value state = const Value.absent(), Value type = const Value.absent(), Value> mentionedUsers = const Value.absent(), - Value?> reactionGroups = - const Value.absent(), Value parentId = const Value.absent(), Value quotedMessageId = const Value.absent(), Value pollId = const Value.absent(), - Value replyCount = const Value.absent(), Value showInChannel = const Value.absent(), - Value shadowed = const Value.absent(), Value command = const Value.absent(), - Value localCreatedAt = const Value.absent(), - Value remoteCreatedAt = const Value.absent(), - Value localUpdatedAt = const Value.absent(), - Value remoteUpdatedAt = const Value.absent(), - Value localDeletedAt = const Value.absent(), - Value remoteDeletedAt = const Value.absent(), - Value messageTextUpdatedAt = const Value.absent(), - Value userId = const Value.absent(), - Value pinned = const Value.absent(), - Value pinnedAt = const Value.absent(), - Value pinExpires = const Value.absent(), - Value pinnedByUserId = const Value.absent(), + Value silent = const Value.absent(), + Value createdAt = const Value.absent(), Value channelCid = const Value.absent(), - Value?> i18n = const Value.absent(), - Value?> restrictedVisibility = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), }) => - MessagesCompanion( + DraftMessagesCompanion( id: id, messageText: messageText, attachments: attachments, - state: state, type: type, mentionedUsers: mentionedUsers, - reactionGroups: reactionGroups, parentId: parentId, quotedMessageId: quotedMessageId, pollId: pollId, - replyCount: replyCount, showInChannel: showInChannel, - shadowed: shadowed, command: command, - localCreatedAt: localCreatedAt, - remoteCreatedAt: remoteCreatedAt, - localUpdatedAt: localUpdatedAt, - remoteUpdatedAt: remoteUpdatedAt, - localDeletedAt: localDeletedAt, - remoteDeletedAt: remoteDeletedAt, - messageTextUpdatedAt: messageTextUpdatedAt, - userId: userId, - pinned: pinned, - pinnedAt: pinnedAt, - pinExpires: pinExpires, - pinnedByUserId: pinnedByUserId, + silent: silent, + createdAt: createdAt, channelCid: channelCid, - i18n: i18n, - restrictedVisibility: restrictedVisibility, extraData: extraData, rowid: rowid, ), @@ -9677,83 +10883,46 @@ class $$MessagesTableTableManager extends RootTableManager< required String id, Value messageText = const Value.absent(), required List attachments, - required String state, Value type = const Value.absent(), required List mentionedUsers, - Value?> reactionGroups = - const Value.absent(), Value parentId = const Value.absent(), Value quotedMessageId = const Value.absent(), Value pollId = const Value.absent(), - Value replyCount = const Value.absent(), Value showInChannel = const Value.absent(), - Value shadowed = const Value.absent(), Value command = const Value.absent(), - Value localCreatedAt = const Value.absent(), - Value remoteCreatedAt = const Value.absent(), - Value localUpdatedAt = const Value.absent(), - Value remoteUpdatedAt = const Value.absent(), - Value localDeletedAt = const Value.absent(), - Value remoteDeletedAt = const Value.absent(), - Value messageTextUpdatedAt = const Value.absent(), - Value userId = const Value.absent(), - Value pinned = const Value.absent(), - Value pinnedAt = const Value.absent(), - Value pinExpires = const Value.absent(), - Value pinnedByUserId = const Value.absent(), + Value silent = const Value.absent(), + Value createdAt = const Value.absent(), required String channelCid, - Value?> i18n = const Value.absent(), - Value?> restrictedVisibility = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), }) => - MessagesCompanion.insert( + DraftMessagesCompanion.insert( id: id, messageText: messageText, attachments: attachments, - state: state, type: type, mentionedUsers: mentionedUsers, - reactionGroups: reactionGroups, parentId: parentId, quotedMessageId: quotedMessageId, pollId: pollId, - replyCount: replyCount, showInChannel: showInChannel, - shadowed: shadowed, command: command, - localCreatedAt: localCreatedAt, - remoteCreatedAt: remoteCreatedAt, - localUpdatedAt: localUpdatedAt, - remoteUpdatedAt: remoteUpdatedAt, - localDeletedAt: localDeletedAt, - remoteDeletedAt: remoteDeletedAt, - messageTextUpdatedAt: messageTextUpdatedAt, - userId: userId, - pinned: pinned, - pinnedAt: pinnedAt, - pinExpires: pinExpires, - pinnedByUserId: pinnedByUserId, + silent: silent, + createdAt: createdAt, channelCid: channelCid, - i18n: i18n, - restrictedVisibility: restrictedVisibility, extraData: extraData, rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => - (e.readTable(table), $$MessagesTableReferences(db, table, e))) + .map((e) => ( + e.readTable(table), + $$DraftMessagesTableReferences(db, table, e) + )) .toList(), - prefetchHooksCallback: ( - {channelCid = false, - draftMessagesRefs = false, - reactionsRefs = false}) { + prefetchHooksCallback: ({parentId = false, channelCid = false}) { return PrefetchHooks( db: db, - explicitlyWatchedTables: [ - if (draftMessagesRefs) db.draftMessages, - if (reactionsRefs) db.reactions - ], + explicitlyWatchedTables: [], addJoins: < T extends TableManagerState< dynamic, @@ -9767,205 +10936,152 @@ class $$MessagesTableTableManager extends RootTableManager< dynamic, dynamic, dynamic>>(state) { + if (parentId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.parentId, + referencedTable: + $$DraftMessagesTableReferences._parentIdTable(db), + referencedColumn: + $$DraftMessagesTableReferences._parentIdTable(db).id, + ) as T; + } if (channelCid) { state = state.withJoin( currentTable: table, currentColumn: table.channelCid, referencedTable: - $$MessagesTableReferences._channelCidTable(db), + $$DraftMessagesTableReferences._channelCidTable(db), referencedColumn: - $$MessagesTableReferences._channelCidTable(db).cid, + $$DraftMessagesTableReferences._channelCidTable(db).cid, ) as T; } return state; }, getPrefetchedDataCallback: (items) async { - return [ - if (draftMessagesRefs) - await $_getPrefetchedData( - currentTable: table, - referencedTable: $$MessagesTableReferences - ._draftMessagesRefsTable(db), - managerFromTypedResult: (p0) => - $$MessagesTableReferences(db, table, p0) - .draftMessagesRefs, - referencedItemsForCurrentItem: (item, - referencedItems) => - referencedItems.where((e) => e.parentId == item.id), - typedResults: items), - if (reactionsRefs) - await $_getPrefetchedData( - currentTable: table, - referencedTable: - $$MessagesTableReferences._reactionsRefsTable(db), - managerFromTypedResult: (p0) => - $$MessagesTableReferences(db, table, p0) - .reactionsRefs, - referencedItemsForCurrentItem: - (item, referencedItems) => referencedItems - .where((e) => e.messageId == item.id), - typedResults: items) - ]; + return []; }, ); }, )); } -typedef $$MessagesTableProcessedTableManager = ProcessedTableManager< +typedef $$DraftMessagesTableProcessedTableManager = ProcessedTableManager< _$DriftChatDatabase, - $MessagesTable, - MessageEntity, - $$MessagesTableFilterComposer, - $$MessagesTableOrderingComposer, - $$MessagesTableAnnotationComposer, - $$MessagesTableCreateCompanionBuilder, - $$MessagesTableUpdateCompanionBuilder, - (MessageEntity, $$MessagesTableReferences), - MessageEntity, - PrefetchHooks Function( - {bool channelCid, bool draftMessagesRefs, bool reactionsRefs})>; -typedef $$DraftMessagesTableCreateCompanionBuilder = DraftMessagesCompanion - Function({ - required String id, - Value messageText, - required List attachments, - Value type, - required List mentionedUsers, - Value parentId, - Value quotedMessageId, - Value pollId, - Value showInChannel, - Value command, - Value silent, + $DraftMessagesTable, + DraftMessageEntity, + $$DraftMessagesTableFilterComposer, + $$DraftMessagesTableOrderingComposer, + $$DraftMessagesTableAnnotationComposer, + $$DraftMessagesTableCreateCompanionBuilder, + $$DraftMessagesTableUpdateCompanionBuilder, + (DraftMessageEntity, $$DraftMessagesTableReferences), + DraftMessageEntity, + PrefetchHooks Function({bool parentId, bool channelCid})>; +typedef $$LocationsTableCreateCompanionBuilder = LocationsCompanion Function({ + Value channelCid, + Value messageId, + Value userId, + required double latitude, + required double longitude, + Value createdByDeviceId, + Value endAt, Value createdAt, - required String channelCid, - Value?> extraData, + Value updatedAt, Value rowid, }); -typedef $$DraftMessagesTableUpdateCompanionBuilder = DraftMessagesCompanion - Function({ - Value id, - Value messageText, - Value> attachments, - Value type, - Value> mentionedUsers, - Value parentId, - Value quotedMessageId, - Value pollId, - Value showInChannel, - Value command, - Value silent, +typedef $$LocationsTableUpdateCompanionBuilder = LocationsCompanion Function({ + Value channelCid, + Value messageId, + Value userId, + Value latitude, + Value longitude, + Value createdByDeviceId, + Value endAt, Value createdAt, - Value channelCid, - Value?> extraData, + Value updatedAt, Value rowid, }); -final class $$DraftMessagesTableReferences extends BaseReferences< - _$DriftChatDatabase, $DraftMessagesTable, DraftMessageEntity> { - $$DraftMessagesTableReferences( - super.$_db, super.$_table, super.$_typedResult); +final class $$LocationsTableReferences extends BaseReferences< + _$DriftChatDatabase, $LocationsTable, LocationEntity> { + $$LocationsTableReferences(super.$_db, super.$_table, super.$_typedResult); - static $MessagesTable _parentIdTable(_$DriftChatDatabase db) => - db.messages.createAlias( - $_aliasNameGenerator(db.draftMessages.parentId, db.messages.id)); + static $ChannelsTable _channelCidTable(_$DriftChatDatabase db) => + db.channels.createAlias( + $_aliasNameGenerator(db.locations.channelCid, db.channels.cid)); - $$MessagesTableProcessedTableManager? get parentId { - final $_column = $_itemColumn('parent_id'); + $$ChannelsTableProcessedTableManager? get channelCid { + final $_column = $_itemColumn('channel_cid'); if ($_column == null) return null; - final manager = $$MessagesTableTableManager($_db, $_db.messages) - .filter((f) => f.id.sqlEquals($_column)); - final item = $_typedResult.readTableOrNull(_parentIdTable($_db)); + final manager = $$ChannelsTableTableManager($_db, $_db.channels) + .filter((f) => f.cid.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_channelCidTable($_db)); if (item == null) return manager; return ProcessedTableManager( manager.$state.copyWith(prefetchedData: [item])); } - static $ChannelsTable _channelCidTable(_$DriftChatDatabase db) => - db.channels.createAlias( - $_aliasNameGenerator(db.draftMessages.channelCid, db.channels.cid)); - - $$ChannelsTableProcessedTableManager get channelCid { - final $_column = $_itemColumn('channel_cid')!; + static $MessagesTable _messageIdTable(_$DriftChatDatabase db) => + db.messages.createAlias( + $_aliasNameGenerator(db.locations.messageId, db.messages.id)); - final manager = $$ChannelsTableTableManager($_db, $_db.channels) - .filter((f) => f.cid.sqlEquals($_column)); - final item = $_typedResult.readTableOrNull(_channelCidTable($_db)); + $$MessagesTableProcessedTableManager? get messageId { + final $_column = $_itemColumn('message_id'); + if ($_column == null) return null; + final manager = $$MessagesTableTableManager($_db, $_db.messages) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_messageIdTable($_db)); if (item == null) return manager; return ProcessedTableManager( manager.$state.copyWith(prefetchedData: [item])); } } -class $$DraftMessagesTableFilterComposer - extends Composer<_$DriftChatDatabase, $DraftMessagesTable> { - $$DraftMessagesTableFilterComposer({ +class $$LocationsTableFilterComposer + extends Composer<_$DriftChatDatabase, $LocationsTable> { + $$LocationsTableFilterComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnFilters get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnFilters(column)); - - ColumnFilters get messageText => $composableBuilder( - column: $table.messageText, builder: (column) => ColumnFilters(column)); - - ColumnWithTypeConverterFilters, List, String> - get attachments => $composableBuilder( - column: $table.attachments, - builder: (column) => ColumnWithTypeConverterFilters(column)); + ColumnFilters get userId => $composableBuilder( + column: $table.userId, builder: (column) => ColumnFilters(column)); - ColumnFilters get type => $composableBuilder( - column: $table.type, builder: (column) => ColumnFilters(column)); + ColumnFilters get latitude => $composableBuilder( + column: $table.latitude, builder: (column) => ColumnFilters(column)); - ColumnWithTypeConverterFilters, List, String> - get mentionedUsers => $composableBuilder( - column: $table.mentionedUsers, - builder: (column) => ColumnWithTypeConverterFilters(column)); + ColumnFilters get longitude => $composableBuilder( + column: $table.longitude, builder: (column) => ColumnFilters(column)); - ColumnFilters get quotedMessageId => $composableBuilder( - column: $table.quotedMessageId, + ColumnFilters get createdByDeviceId => $composableBuilder( + column: $table.createdByDeviceId, builder: (column) => ColumnFilters(column)); - ColumnFilters get pollId => $composableBuilder( - column: $table.pollId, builder: (column) => ColumnFilters(column)); - - ColumnFilters get showInChannel => $composableBuilder( - column: $table.showInChannel, builder: (column) => ColumnFilters(column)); - - ColumnFilters get command => $composableBuilder( - column: $table.command, builder: (column) => ColumnFilters(column)); - - ColumnFilters get silent => $composableBuilder( - column: $table.silent, builder: (column) => ColumnFilters(column)); + ColumnFilters get endAt => $composableBuilder( + column: $table.endAt, builder: (column) => ColumnFilters(column)); ColumnFilters get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnFilters(column)); - ColumnWithTypeConverterFilters?, Map, - String> - get extraData => $composableBuilder( - column: $table.extraData, - builder: (column) => ColumnWithTypeConverterFilters(column)); + ColumnFilters get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnFilters(column)); - $$MessagesTableFilterComposer get parentId { - final $$MessagesTableFilterComposer composer = $composerBuilder( + $$ChannelsTableFilterComposer get channelCid { + final $$ChannelsTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.parentId, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.id, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$MessagesTableFilterComposer( + $$ChannelsTableFilterComposer( $db: $db, - $table: $db.messages, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -9974,18 +11090,18 @@ class $$DraftMessagesTableFilterComposer return composer; } - $$ChannelsTableFilterComposer get channelCid { - final $$ChannelsTableFilterComposer composer = $composerBuilder( + $$MessagesTableFilterComposer get messageId { + final $$MessagesTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.channelCid, - referencedTable: $db.channels, - getReferencedColumn: (t) => t.cid, + getCurrentColumn: (t) => t.messageId, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ChannelsTableFilterComposer( + $$MessagesTableFilterComposer( $db: $db, - $table: $db.channels, + $table: $db.messages, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -9995,66 +11111,49 @@ class $$DraftMessagesTableFilterComposer } } -class $$DraftMessagesTableOrderingComposer - extends Composer<_$DriftChatDatabase, $DraftMessagesTable> { - $$DraftMessagesTableOrderingComposer({ +class $$LocationsTableOrderingComposer + extends Composer<_$DriftChatDatabase, $LocationsTable> { + $$LocationsTableOrderingComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnOrderings get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get messageText => $composableBuilder( - column: $table.messageText, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get attachments => $composableBuilder( - column: $table.attachments, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get type => $composableBuilder( - column: $table.type, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get mentionedUsers => $composableBuilder( - column: $table.mentionedUsers, - builder: (column) => ColumnOrderings(column)); + ColumnOrderings get userId => $composableBuilder( + column: $table.userId, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get quotedMessageId => $composableBuilder( - column: $table.quotedMessageId, - builder: (column) => ColumnOrderings(column)); + ColumnOrderings get latitude => $composableBuilder( + column: $table.latitude, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get pollId => $composableBuilder( - column: $table.pollId, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get longitude => $composableBuilder( + column: $table.longitude, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get showInChannel => $composableBuilder( - column: $table.showInChannel, + ColumnOrderings get createdByDeviceId => $composableBuilder( + column: $table.createdByDeviceId, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get command => $composableBuilder( - column: $table.command, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get silent => $composableBuilder( - column: $table.silent, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get endAt => $composableBuilder( + column: $table.endAt, builder: (column) => ColumnOrderings(column)); ColumnOrderings get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get extraData => $composableBuilder( - column: $table.extraData, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnOrderings(column)); - $$MessagesTableOrderingComposer get parentId { - final $$MessagesTableOrderingComposer composer = $composerBuilder( + $$ChannelsTableOrderingComposer get channelCid { + final $$ChannelsTableOrderingComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.parentId, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.id, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$MessagesTableOrderingComposer( + $$ChannelsTableOrderingComposer( $db: $db, - $table: $db.messages, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -10063,18 +11162,18 @@ class $$DraftMessagesTableOrderingComposer return composer; } - $$ChannelsTableOrderingComposer get channelCid { - final $$ChannelsTableOrderingComposer composer = $composerBuilder( + $$MessagesTableOrderingComposer get messageId { + final $$MessagesTableOrderingComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.channelCid, - referencedTable: $db.channels, - getReferencedColumn: (t) => t.cid, + getCurrentColumn: (t) => t.messageId, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ChannelsTableOrderingComposer( + $$MessagesTableOrderingComposer( $db: $db, - $table: $db.channels, + $table: $db.messages, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -10084,66 +11183,48 @@ class $$DraftMessagesTableOrderingComposer } } -class $$DraftMessagesTableAnnotationComposer - extends Composer<_$DriftChatDatabase, $DraftMessagesTable> { - $$DraftMessagesTableAnnotationComposer({ +class $$LocationsTableAnnotationComposer + extends Composer<_$DriftChatDatabase, $LocationsTable> { + $$LocationsTableAnnotationComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - GeneratedColumn get id => - $composableBuilder(column: $table.id, builder: (column) => column); - - GeneratedColumn get messageText => $composableBuilder( - column: $table.messageText, builder: (column) => column); - - GeneratedColumnWithTypeConverter, String> get attachments => - $composableBuilder( - column: $table.attachments, builder: (column) => column); - - GeneratedColumn get type => - $composableBuilder(column: $table.type, builder: (column) => column); - - GeneratedColumnWithTypeConverter, String> get mentionedUsers => - $composableBuilder( - column: $table.mentionedUsers, builder: (column) => column); - - GeneratedColumn get quotedMessageId => $composableBuilder( - column: $table.quotedMessageId, builder: (column) => column); + GeneratedColumn get userId => + $composableBuilder(column: $table.userId, builder: (column) => column); - GeneratedColumn get pollId => - $composableBuilder(column: $table.pollId, builder: (column) => column); + GeneratedColumn get latitude => + $composableBuilder(column: $table.latitude, builder: (column) => column); - GeneratedColumn get showInChannel => $composableBuilder( - column: $table.showInChannel, builder: (column) => column); + GeneratedColumn get longitude => + $composableBuilder(column: $table.longitude, builder: (column) => column); - GeneratedColumn get command => - $composableBuilder(column: $table.command, builder: (column) => column); + GeneratedColumn get createdByDeviceId => $composableBuilder( + column: $table.createdByDeviceId, builder: (column) => column); - GeneratedColumn get silent => - $composableBuilder(column: $table.silent, builder: (column) => column); + GeneratedColumn get endAt => + $composableBuilder(column: $table.endAt, builder: (column) => column); GeneratedColumn get createdAt => $composableBuilder(column: $table.createdAt, builder: (column) => column); - GeneratedColumnWithTypeConverter?, String> - get extraData => $composableBuilder( - column: $table.extraData, builder: (column) => column); + GeneratedColumn get updatedAt => + $composableBuilder(column: $table.updatedAt, builder: (column) => column); - $$MessagesTableAnnotationComposer get parentId { - final $$MessagesTableAnnotationComposer composer = $composerBuilder( + $$ChannelsTableAnnotationComposer get channelCid { + final $$ChannelsTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.parentId, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.id, + getCurrentColumn: (t) => t.channelCid, + referencedTable: $db.channels, + getReferencedColumn: (t) => t.cid, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$MessagesTableAnnotationComposer( + $$ChannelsTableAnnotationComposer( $db: $db, - $table: $db.messages, + $table: $db.channels, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -10152,18 +11233,18 @@ class $$DraftMessagesTableAnnotationComposer return composer; } - $$ChannelsTableAnnotationComposer get channelCid { - final $$ChannelsTableAnnotationComposer composer = $composerBuilder( + $$MessagesTableAnnotationComposer get messageId { + final $$MessagesTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.channelCid, - referencedTable: $db.channels, - getReferencedColumn: (t) => t.cid, + getCurrentColumn: (t) => t.messageId, + referencedTable: $db.messages, + getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$ChannelsTableAnnotationComposer( + $$MessagesTableAnnotationComposer( $db: $db, - $table: $db.channels, + $table: $db.messages, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -10173,104 +11254,83 @@ class $$DraftMessagesTableAnnotationComposer } } -class $$DraftMessagesTableTableManager extends RootTableManager< +class $$LocationsTableTableManager extends RootTableManager< _$DriftChatDatabase, - $DraftMessagesTable, - DraftMessageEntity, - $$DraftMessagesTableFilterComposer, - $$DraftMessagesTableOrderingComposer, - $$DraftMessagesTableAnnotationComposer, - $$DraftMessagesTableCreateCompanionBuilder, - $$DraftMessagesTableUpdateCompanionBuilder, - (DraftMessageEntity, $$DraftMessagesTableReferences), - DraftMessageEntity, - PrefetchHooks Function({bool parentId, bool channelCid})> { - $$DraftMessagesTableTableManager( - _$DriftChatDatabase db, $DraftMessagesTable table) + $LocationsTable, + LocationEntity, + $$LocationsTableFilterComposer, + $$LocationsTableOrderingComposer, + $$LocationsTableAnnotationComposer, + $$LocationsTableCreateCompanionBuilder, + $$LocationsTableUpdateCompanionBuilder, + (LocationEntity, $$LocationsTableReferences), + LocationEntity, + PrefetchHooks Function({bool channelCid, bool messageId})> { + $$LocationsTableTableManager(_$DriftChatDatabase db, $LocationsTable table) : super(TableManagerState( db: db, table: table, createFilteringComposer: () => - $$DraftMessagesTableFilterComposer($db: db, $table: table), + $$LocationsTableFilterComposer($db: db, $table: table), createOrderingComposer: () => - $$DraftMessagesTableOrderingComposer($db: db, $table: table), + $$LocationsTableOrderingComposer($db: db, $table: table), createComputedFieldComposer: () => - $$DraftMessagesTableAnnotationComposer($db: db, $table: table), + $$LocationsTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ - Value id = const Value.absent(), - Value messageText = const Value.absent(), - Value> attachments = const Value.absent(), - Value type = const Value.absent(), - Value> mentionedUsers = const Value.absent(), - Value parentId = const Value.absent(), - Value quotedMessageId = const Value.absent(), - Value pollId = const Value.absent(), - Value showInChannel = const Value.absent(), - Value command = const Value.absent(), - Value silent = const Value.absent(), + Value channelCid = const Value.absent(), + Value messageId = const Value.absent(), + Value userId = const Value.absent(), + Value latitude = const Value.absent(), + Value longitude = const Value.absent(), + Value createdByDeviceId = const Value.absent(), + Value endAt = const Value.absent(), Value createdAt = const Value.absent(), - Value channelCid = const Value.absent(), - Value?> extraData = const Value.absent(), + Value updatedAt = const Value.absent(), Value rowid = const Value.absent(), }) => - DraftMessagesCompanion( - id: id, - messageText: messageText, - attachments: attachments, - type: type, - mentionedUsers: mentionedUsers, - parentId: parentId, - quotedMessageId: quotedMessageId, - pollId: pollId, - showInChannel: showInChannel, - command: command, - silent: silent, - createdAt: createdAt, + LocationsCompanion( channelCid: channelCid, - extraData: extraData, + messageId: messageId, + userId: userId, + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, rowid: rowid, ), createCompanionCallback: ({ - required String id, - Value messageText = const Value.absent(), - required List attachments, - Value type = const Value.absent(), - required List mentionedUsers, - Value parentId = const Value.absent(), - Value quotedMessageId = const Value.absent(), - Value pollId = const Value.absent(), - Value showInChannel = const Value.absent(), - Value command = const Value.absent(), - Value silent = const Value.absent(), + Value channelCid = const Value.absent(), + Value messageId = const Value.absent(), + Value userId = const Value.absent(), + required double latitude, + required double longitude, + Value createdByDeviceId = const Value.absent(), + Value endAt = const Value.absent(), Value createdAt = const Value.absent(), - required String channelCid, - Value?> extraData = const Value.absent(), + Value updatedAt = const Value.absent(), Value rowid = const Value.absent(), }) => - DraftMessagesCompanion.insert( - id: id, - messageText: messageText, - attachments: attachments, - type: type, - mentionedUsers: mentionedUsers, - parentId: parentId, - quotedMessageId: quotedMessageId, - pollId: pollId, - showInChannel: showInChannel, - command: command, - silent: silent, - createdAt: createdAt, + LocationsCompanion.insert( channelCid: channelCid, - extraData: extraData, + messageId: messageId, + userId: userId, + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, rowid: rowid, ), withReferenceMapper: (p0) => p0 .map((e) => ( e.readTable(table), - $$DraftMessagesTableReferences(db, table, e) + $$LocationsTableReferences(db, table, e) )) .toList(), - prefetchHooksCallback: ({parentId = false, channelCid = false}) { + prefetchHooksCallback: ({channelCid = false, messageId = false}) { return PrefetchHooks( db: db, explicitlyWatchedTables: [], @@ -10287,24 +11347,24 @@ class $$DraftMessagesTableTableManager extends RootTableManager< dynamic, dynamic, dynamic>>(state) { - if (parentId) { + if (channelCid) { state = state.withJoin( currentTable: table, - currentColumn: table.parentId, + currentColumn: table.channelCid, referencedTable: - $$DraftMessagesTableReferences._parentIdTable(db), + $$LocationsTableReferences._channelCidTable(db), referencedColumn: - $$DraftMessagesTableReferences._parentIdTable(db).id, + $$LocationsTableReferences._channelCidTable(db).cid, ) as T; } - if (channelCid) { + if (messageId) { state = state.withJoin( currentTable: table, - currentColumn: table.channelCid, + currentColumn: table.messageId, referencedTable: - $$DraftMessagesTableReferences._channelCidTable(db), + $$LocationsTableReferences._messageIdTable(db), referencedColumn: - $$DraftMessagesTableReferences._channelCidTable(db).cid, + $$LocationsTableReferences._messageIdTable(db).id, ) as T; } @@ -10318,18 +11378,18 @@ class $$DraftMessagesTableTableManager extends RootTableManager< )); } -typedef $$DraftMessagesTableProcessedTableManager = ProcessedTableManager< +typedef $$LocationsTableProcessedTableManager = ProcessedTableManager< _$DriftChatDatabase, - $DraftMessagesTable, - DraftMessageEntity, - $$DraftMessagesTableFilterComposer, - $$DraftMessagesTableOrderingComposer, - $$DraftMessagesTableAnnotationComposer, - $$DraftMessagesTableCreateCompanionBuilder, - $$DraftMessagesTableUpdateCompanionBuilder, - (DraftMessageEntity, $$DraftMessagesTableReferences), - DraftMessageEntity, - PrefetchHooks Function({bool parentId, bool channelCid})>; + $LocationsTable, + LocationEntity, + $$LocationsTableFilterComposer, + $$LocationsTableOrderingComposer, + $$LocationsTableAnnotationComposer, + $$LocationsTableCreateCompanionBuilder, + $$LocationsTableUpdateCompanionBuilder, + (LocationEntity, $$LocationsTableReferences), + LocationEntity, + PrefetchHooks Function({bool channelCid, bool messageId})>; typedef $$PinnedMessagesTableCreateCompanionBuilder = PinnedMessagesCompanion Function({ required String id, @@ -13650,6 +14710,8 @@ class $DriftChatDatabaseManager { $$MessagesTableTableManager(_db, _db.messages); $$DraftMessagesTableTableManager get draftMessages => $$DraftMessagesTableTableManager(_db, _db.draftMessages); + $$LocationsTableTableManager get locations => + $$LocationsTableTableManager(_db, _db.locations); $$PinnedMessagesTableTableManager get pinnedMessages => $$PinnedMessagesTableTableManager(_db, _db.pinnedMessages); $$PollsTableTableManager get polls => diff --git a/packages/stream_chat_persistence/lib/src/entity/entity.dart b/packages/stream_chat_persistence/lib/src/entity/entity.dart index 2ef87c5cb6..58fb6a164d 100644 --- a/packages/stream_chat_persistence/lib/src/entity/entity.dart +++ b/packages/stream_chat_persistence/lib/src/entity/entity.dart @@ -2,6 +2,7 @@ export 'channel_queries.dart'; export 'channels.dart'; export 'connection_events.dart'; export 'draft_messages.dart'; +export 'locations.dart'; export 'members.dart'; export 'messages.dart'; export 'pinned_message_reactions.dart'; diff --git a/packages/stream_chat_persistence/lib/src/entity/locations.dart b/packages/stream_chat_persistence/lib/src/entity/locations.dart new file mode 100644 index 0000000000..b12f448b8b --- /dev/null +++ b/packages/stream_chat_persistence/lib/src/entity/locations.dart @@ -0,0 +1,43 @@ +// coverage:ignore-file +import 'package:drift/drift.dart'; +import 'package:stream_chat_persistence/src/entity/channels.dart'; +import 'package:stream_chat_persistence/src/entity/messages.dart'; + +/// Represents a [Locations] table in [DriftChatDatabase]. +@DataClassName('LocationEntity') +class Locations extends Table { + /// The channel CID where the location is shared + TextColumn get channelCid => text() + .nullable() + .references(Channels, #cid, onDelete: KeyAction.cascade)(); + + /// The ID of the message that contains this shared location + TextColumn get messageId => text() + .nullable() + .references(Messages, #id, onDelete: KeyAction.cascade)(); + + /// The ID of the user who shared the location + TextColumn get userId => text().nullable()(); + + /// The latitude of the shared location + RealColumn get latitude => real()(); + + /// The longitude of the shared location + RealColumn get longitude => real()(); + + /// The ID of the device that created the location + TextColumn get createdByDeviceId => text().nullable()(); + + /// The date at which the shared location will end (for live locations) + /// If null, this is a static location + DateTimeColumn get endAt => dateTime().nullable()(); + + /// The date at which the location was created + DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); + + /// The date at which the location was last updated + DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)(); + + @override + Set get primaryKey => {messageId}; +} diff --git a/packages/stream_chat_persistence/lib/src/mapper/location_mapper.dart b/packages/stream_chat_persistence/lib/src/mapper/location_mapper.dart new file mode 100644 index 0000000000..bcbc18be1b --- /dev/null +++ b/packages/stream_chat_persistence/lib/src/mapper/location_mapper.dart @@ -0,0 +1,40 @@ +import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; + +/// Useful mapping functions for [LocationEntity] +extension LocationEntityX on LocationEntity { + /// Maps a [LocationEntity] into [Location] + Location toLocation({ + ChannelModel? channel, + Message? message, + }) => + Location( + channelCid: channelCid, + channel: channel, + messageId: messageId, + message: message, + userId: userId, + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, + ); +} + +/// Useful mapping functions for [Location] +extension LocationX on Location { + /// Maps a [Location] into [LocationEntity] + LocationEntity toEntity() => LocationEntity( + channelCid: channelCid, + messageId: messageId, + userId: userId, + latitude: latitude, + longitude: longitude, + createdByDeviceId: createdByDeviceId, + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, + ); +} diff --git a/packages/stream_chat_persistence/lib/src/mapper/mapper.dart b/packages/stream_chat_persistence/lib/src/mapper/mapper.dart index 742776f504..45b35dba81 100644 --- a/packages/stream_chat_persistence/lib/src/mapper/mapper.dart +++ b/packages/stream_chat_persistence/lib/src/mapper/mapper.dart @@ -1,6 +1,7 @@ export 'channel_mapper.dart'; export 'draft_message_mapper.dart'; export 'event_mapper.dart'; +export 'location_mapper.dart'; export 'member_mapper.dart'; export 'message_mapper.dart'; export 'pinned_message_mapper.dart'; diff --git a/packages/stream_chat_persistence/lib/src/mapper/message_mapper.dart b/packages/stream_chat_persistence/lib/src/mapper/message_mapper.dart index 3235925165..4640c0f325 100644 --- a/packages/stream_chat_persistence/lib/src/mapper/message_mapper.dart +++ b/packages/stream_chat_persistence/lib/src/mapper/message_mapper.dart @@ -14,6 +14,7 @@ extension MessageEntityX on MessageEntity { Message? quotedMessage, Poll? poll, Draft? draft, + Location? sharedLocation, }) => Message( shadowed: shadowed, @@ -54,6 +55,7 @@ extension MessageEntityX on MessageEntity { i18n: i18n, restrictedVisibility: restrictedVisibility, draft: draft, + sharedLocation: sharedLocation, ); } diff --git a/packages/stream_chat_persistence/lib/src/mapper/pinned_message_mapper.dart b/packages/stream_chat_persistence/lib/src/mapper/pinned_message_mapper.dart index c6cbf19414..fbd168c717 100644 --- a/packages/stream_chat_persistence/lib/src/mapper/pinned_message_mapper.dart +++ b/packages/stream_chat_persistence/lib/src/mapper/pinned_message_mapper.dart @@ -14,6 +14,7 @@ extension PinnedMessageEntityX on PinnedMessageEntity { Message? quotedMessage, Poll? poll, Draft? draft, + Location? sharedLocation, }) => Message( shadowed: shadowed, @@ -54,6 +55,7 @@ extension PinnedMessageEntityX on PinnedMessageEntity { i18n: i18n, restrictedVisibility: restrictedVisibility, draft: draft, + sharedLocation: sharedLocation, ); } diff --git a/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart b/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart index f136a9fe50..93ff648f1a 100644 --- a/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart +++ b/packages/stream_chat_persistence/lib/src/stream_chat_persistence_client.dart @@ -224,6 +224,20 @@ class StreamChatPersistenceClient extends ChatPersistenceClient { ); } + @override + Future> getLocationsByCid(String cid) async { + assert(_debugIsConnected, ''); + _logger.info('getLocationsByCid'); + return db!.locationDao.getLocationsByCid(cid); + } + + @override + Future getLocationByMessageId(String messageId) async { + assert(_debugIsConnected, ''); + _logger.info('getLocationByMessageId'); + return db!.locationDao.getLocationByMessageId(messageId); + } + @override Future> getReadsByCid(String cid) async { assert(_debugIsConnected, ''); @@ -394,6 +408,13 @@ class StreamChatPersistenceClient extends ChatPersistenceClient { return db!.userDao.updateUsers(users); } + @override + Future updateLocations(List locations) async { + assert(_debugIsConnected, ''); + _logger.info('updateLocations'); + return db!.locationDao.updateLocations(locations); + } + @override Future deletePinnedMessageReactionsByMessageId( List messageIds, @@ -444,6 +465,20 @@ class StreamChatPersistenceClient extends ChatPersistenceClient { ); } + @override + Future deleteLocationsByCid(String cid) { + assert(_debugIsConnected, ''); + _logger.info('deleteLocationsByCid'); + return db!.locationDao.deleteLocationsByCid(cid); + } + + @override + Future deleteLocationsByMessageIds(List messageIds) { + assert(_debugIsConnected, ''); + _logger.info('deleteLocationsByMessageIds'); + return db!.locationDao.deleteLocationsByMessageIds(messageIds); + } + @override Future updateChannelThreads( String cid, diff --git a/packages/stream_chat_persistence/test/mock_chat_database.dart b/packages/stream_chat_persistence/test/mock_chat_database.dart index 6f1f61af0d..cb0f06a541 100644 --- a/packages/stream_chat_persistence/test/mock_chat_database.dart +++ b/packages/stream_chat_persistence/test/mock_chat_database.dart @@ -63,6 +63,10 @@ class MockChatDatabase extends Mock implements DriftChatDatabase { _draftMessageDao ??= MockDraftMessageDao(); DraftMessageDao? _draftMessageDao; + @override + LocationDao get locationDao => _locationDao ??= MockLocationDao(); + LocationDao? _locationDao; + @override Future flush() => Future.value(); @@ -96,3 +100,5 @@ class MockPollDao extends Mock implements PollDao {} class MockPollVoteDao extends Mock implements PollVoteDao {} class MockDraftMessageDao extends Mock implements DraftMessageDao {} + +class MockLocationDao extends Mock implements LocationDao {} diff --git a/packages/stream_chat_persistence/test/src/dao/location_dao_test.dart b/packages/stream_chat_persistence/test/src/dao/location_dao_test.dart new file mode 100644 index 0000000000..2311ac8d2d --- /dev/null +++ b/packages/stream_chat_persistence/test/src/dao/location_dao_test.dart @@ -0,0 +1,318 @@ +// ignore_for_file: avoid_redundant_argument_values + +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_persistence/src/dao/dao.dart'; +import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; + +import '../../stream_chat_persistence_client_test.dart'; + +void main() { + late LocationDao locationDao; + late DriftChatDatabase database; + + setUp(() { + database = testDatabaseProvider('testUserId'); + locationDao = database.locationDao; + }); + + Future> _prepareLocationData({ + required String cid, + int count = 3, + }) async { + final channels = [ChannelModel(cid: cid)]; + final users = List.generate(count, (index) => User(id: 'testUserId$index')); + final messages = List.generate( + count, + (index) => Message( + id: 'testMessageId$cid$index', + type: 'testType', + user: users[index], + createdAt: DateTime.now(), + text: 'Test message #$index', + ), + ); + + final locations = List.generate( + count, + (index) => Location( + channelCid: cid, + messageId: messages[index].id, + userId: users[index].id, + latitude: 37.7749 + index * 0.001, // San Francisco area + longitude: -122.4194 + index * 0.001, + createdByDeviceId: 'testDevice$index', + endAt: index.isEven + ? DateTime.now().add(const Duration(hours: 1)) + : null, // Some live, some static + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + ), + ); + + await database.userDao.updateUsers(users); + await database.channelDao.updateChannels(channels); + await database.messageDao.updateMessages(cid, messages); + await locationDao.updateLocations(locations); + + return locations; + } + + test('getLocationsByCid', () async { + const cid = 'test:Cid'; + + // Should be empty initially + final locations = await locationDao.getLocationsByCid(cid); + expect(locations, isEmpty); + + // Adding sample locations + final insertedLocations = await _prepareLocationData(cid: cid); + expect(insertedLocations, isNotEmpty); + + // Fetched locations length should match inserted locations length + final fetchedLocations = await locationDao.getLocationsByCid(cid); + expect(fetchedLocations.length, insertedLocations.length); + + // Every location channelCid should match the provided cid + expect(fetchedLocations.every((it) => it.channelCid == cid), true); + }); + + test('updateLocations', () async { + const cid = 'test:Cid'; + + // Preparing test data + final insertedLocations = await _prepareLocationData(cid: cid); + + // Adding a new location + final newUser = User(id: 'newUserId'); + final newMessage = Message( + id: 'newMessageId', + type: 'testType', + user: newUser, + createdAt: DateTime.now(), + text: 'New test message', + ); + final newLocation = Location( + channelCid: cid, + messageId: newMessage.id, + userId: newUser.id, + latitude: 40.7128, // New York + longitude: -74.0060, + createdByDeviceId: 'newDevice', + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + ); + + await database.userDao.updateUsers([newUser]); + await database.messageDao.updateMessages(cid, [newMessage]); + await locationDao.updateLocations([newLocation]); + + // Fetched locations length should be one more than inserted locations + // Fetched locations should contain the newLocation + final fetchedLocations = await locationDao.getLocationsByCid(cid); + expect(fetchedLocations.length, insertedLocations.length + 1); + expect( + fetchedLocations.any((it) => + it.messageId == newLocation.messageId && + it.latitude == newLocation.latitude && + it.longitude == newLocation.longitude), + isTrue, + ); + }); + + test('getLocationByMessageId', () async { + const cid = 'test:Cid'; + + // Preparing test data + final insertedLocations = await _prepareLocationData(cid: cid); + + // Fetched location should not be null + final locationToFetch = insertedLocations.first; + final fetchedLocation = + await locationDao.getLocationByMessageId(locationToFetch.messageId!); + expect(fetchedLocation, isNotNull); + expect(fetchedLocation!.messageId, locationToFetch.messageId); + expect(fetchedLocation.latitude, locationToFetch.latitude); + expect(fetchedLocation.longitude, locationToFetch.longitude); + }); + + test( + 'getLocationByMessageId should return null for non-existent messageId', + () async { + // Should return null for non-existent messageId + final fetchedLocation = + await locationDao.getLocationByMessageId('nonExistentMessageId'); + expect(fetchedLocation, isNull); + }, + ); + + test('deleteLocationsByCid', () async { + const cid = 'test:Cid'; + + // Preparing test data + final insertedLocations = await _prepareLocationData(cid: cid); + + // Verify locations exist + final locationsBeforeDelete = await locationDao.getLocationsByCid(cid); + expect(locationsBeforeDelete.length, insertedLocations.length); + + // Deleting all locations for the channel + await locationDao.deleteLocationsByCid(cid); + + // Fetched location list should be empty + final fetchedLocations = await locationDao.getLocationsByCid(cid); + expect(fetchedLocations, isEmpty); + }); + + test('deleteLocationsByMessageIds', () async { + const cid = 'test:Cid'; + + // Preparing test data + final insertedLocations = await _prepareLocationData(cid: cid); + + // Deleting the first two locations by their message IDs + final messageIdsToDelete = + insertedLocations.take(2).map((it) => it.messageId!).toList(); + await locationDao.deleteLocationsByMessageIds(messageIdsToDelete); + + // Fetched location list should be one less than inserted locations + final fetchedLocations = await locationDao.getLocationsByCid(cid); + expect(fetchedLocations.length, + insertedLocations.length - messageIdsToDelete.length); + + // Deleted locations should not exist in fetched locations + expect( + fetchedLocations.any((it) => messageIdsToDelete.contains(it.messageId)), + isFalse, + ); + }); + + group('deleteLocationsByMessageIds', () { + test('should delete locations for specific message IDs only', () async { + const cid1 = 'test:Cid1'; + const cid2 = 'test:Cid2'; + + // Preparing test data for two channels + final insertedLocations1 = + await _prepareLocationData(cid: cid1, count: 2); + final insertedLocations2 = + await _prepareLocationData(cid: cid2, count: 2); + + // Verify all locations exist + final locations1 = await locationDao.getLocationsByCid(cid1); + final locations2 = await locationDao.getLocationsByCid(cid2); + expect(locations1.length, insertedLocations1.length); + expect(locations2.length, insertedLocations2.length); + + // Delete only locations from the first channel + final messageIdsToDelete = + insertedLocations1.map((it) => it.messageId!).toList(); + await locationDao.deleteLocationsByMessageIds(messageIdsToDelete); + + // Only locations from cid1 should be deleted + final fetchedLocations1 = await locationDao.getLocationsByCid(cid1); + final fetchedLocations2 = await locationDao.getLocationsByCid(cid2); + expect(fetchedLocations1, isEmpty); + expect(fetchedLocations2.length, insertedLocations2.length); + }); + }); + + group('Location entity references', () { + test( + 'should delete locations when referenced channel is deleted', + () async { + const cid = 'test:channelRefCascade'; + + // Prepare test data + await _prepareLocationData(cid: cid, count: 2); + + // Verify locations exist before channel deletion + final locationsBeforeDelete = await locationDao.getLocationsByCid(cid); + expect(locationsBeforeDelete, isNotEmpty); + expect(locationsBeforeDelete.length, 2); + + // Delete the channel + await database.channelDao.deleteChannelByCids([cid]); + + // Verify locations have been deleted (cascade) + final locationsAfterDelete = await locationDao.getLocationsByCid(cid); + expect(locationsAfterDelete, isEmpty); + }, + ); + + test( + 'should delete locations when referenced message is deleted', + () async { + const cid = 'test:messageRefCascade'; + + // Prepare test data + final insertedLocations = + await _prepareLocationData(cid: cid, count: 3); + final messageToDelete = insertedLocations.first.messageId!; + + // Verify location exists before message deletion + final locationBeforeDelete = + await locationDao.getLocationByMessageId(messageToDelete); + expect(locationBeforeDelete, isNotNull); + expect(locationBeforeDelete!.messageId, messageToDelete); + + // Verify all locations exist + final allLocationsBeforeDelete = + await locationDao.getLocationsByCid(cid); + expect(allLocationsBeforeDelete.length, 3); + + // Delete the message + await database.messageDao.deleteMessageByIds([messageToDelete]); + + // Verify the specific location has been deleted (cascade) + final locationAfterDelete = + await locationDao.getLocationByMessageId(messageToDelete); + expect(locationAfterDelete, isNull); + + // Verify other locations still exist + final allLocationsAfterDelete = + await locationDao.getLocationsByCid(cid); + expect(allLocationsAfterDelete.length, 2); + expect( + allLocationsAfterDelete.any((it) => it.messageId == messageToDelete), + isFalse, + ); + }, + ); + + test( + 'should delete all locations when multiple messages are deleted', + () async { + const cid = 'test:multipleMessageRefCascade'; + + // Prepare test data + final insertedLocations = + await _prepareLocationData(cid: cid, count: 3); + final messageIdsToDelete = + insertedLocations.take(2).map((it) => it.messageId!).toList(); + + // Verify locations exist before message deletion + final allLocationsBeforeDelete = + await locationDao.getLocationsByCid(cid); + expect(allLocationsBeforeDelete.length, 3); + + // Delete multiple messages + await database.messageDao.deleteMessageByIds(messageIdsToDelete); + + // Verify corresponding locations have been deleted (cascade) + final allLocationsAfterDelete = + await locationDao.getLocationsByCid(cid); + expect(allLocationsAfterDelete.length, 1); + expect( + allLocationsAfterDelete + .any((it) => messageIdsToDelete.contains(it.messageId)), + isFalse, + ); + }, + ); + }); + + tearDown(() async { + await database.disconnect(); + }); +} diff --git a/packages/stream_chat_persistence/test/src/mapper/location_mapper_test.dart b/packages/stream_chat_persistence/test/src/mapper/location_mapper_test.dart new file mode 100644 index 0000000000..622a76dcb2 --- /dev/null +++ b/packages/stream_chat_persistence/test/src/mapper/location_mapper_test.dart @@ -0,0 +1,141 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; +import 'package:stream_chat_persistence/src/mapper/location_mapper.dart'; + +void main() { + group('LocationMapper', () { + test('toLocation should map the entity into Location', () { + final createdAt = DateTime.now(); + final updatedAt = DateTime.now(); + final endAt = DateTime.now().add(const Duration(hours: 1)); + + final entity = LocationEntity( + channelCid: 'testCid', + userId: 'testUserId', + messageId: 'testMessageId', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'testDeviceId', + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, + ); + + final location = entity.toLocation(); + + expect(location, isA()); + expect(location.channelCid, entity.channelCid); + expect(location.userId, entity.userId); + expect(location.messageId, entity.messageId); + expect(location.latitude, entity.latitude); + expect(location.longitude, entity.longitude); + expect(location.createdByDeviceId, entity.createdByDeviceId); + expect(location.endAt, entity.endAt); + expect(location.createdAt, entity.createdAt); + expect(location.updatedAt, entity.updatedAt); + }); + + test('toEntity should map the Location into LocationEntity', () { + final createdAt = DateTime.now(); + final updatedAt = DateTime.now(); + final endAt = DateTime.now().add(const Duration(hours: 1)); + + final location = Location( + channelCid: 'testCid', + userId: 'testUserId', + messageId: 'testMessageId', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'testDeviceId', + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, + ); + + final entity = location.toEntity(); + + expect(entity, isA()); + expect(entity.channelCid, location.channelCid); + expect(entity.userId, location.userId); + expect(entity.messageId, location.messageId); + expect(entity.latitude, location.latitude); + expect(entity.longitude, location.longitude); + expect(entity.createdByDeviceId, location.createdByDeviceId); + expect(entity.endAt, location.endAt); + expect(entity.createdAt, location.createdAt); + expect(entity.updatedAt, location.updatedAt); + }); + + test('roundtrip conversion should preserve data', () { + final createdAt = DateTime.now(); + final updatedAt = DateTime.now(); + final endAt = DateTime.now().add(const Duration(hours: 1)); + + final originalLocation = Location( + channelCid: 'testCid', + userId: 'testUserId', + messageId: 'testMessageId', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'testDeviceId', + endAt: endAt, + createdAt: createdAt, + updatedAt: updatedAt, + ); + + final entity = originalLocation.toEntity(); + final convertedLocation = entity.toLocation(); + + expect(convertedLocation.channelCid, originalLocation.channelCid); + expect(convertedLocation.userId, originalLocation.userId); + expect(convertedLocation.messageId, originalLocation.messageId); + expect(convertedLocation.latitude, originalLocation.latitude); + expect(convertedLocation.longitude, originalLocation.longitude); + expect(convertedLocation.createdByDeviceId, + originalLocation.createdByDeviceId); + expect(convertedLocation.endAt, originalLocation.endAt); + expect(convertedLocation.createdAt, originalLocation.createdAt); + expect(convertedLocation.updatedAt, originalLocation.updatedAt); + }); + + test('should handle live location conversion', () { + final endAt = DateTime.now().add(const Duration(hours: 1)); + final location = Location( + channelCid: 'testCid', + userId: 'testUserId', + messageId: 'testMessageId', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'testDeviceId', + endAt: endAt, + ); + + final entity = location.toEntity(); + final convertedLocation = entity.toLocation(); + + expect(convertedLocation.isLive, isTrue); + expect(convertedLocation.isStatic, isFalse); + expect(convertedLocation.endAt, endAt); + }); + + test('should handle static location conversion', () { + final location = Location( + channelCid: 'testCid', + userId: 'testUserId', + messageId: 'testMessageId', + latitude: 40.7128, + longitude: -74.0060, + createdByDeviceId: 'testDeviceId', + // No endAt = static location + ); + + final entity = location.toEntity(); + final convertedLocation = entity.toLocation(); + + expect(convertedLocation.isLive, isFalse); + expect(convertedLocation.isStatic, isTrue); + expect(convertedLocation.endAt, isNull); + }); + }); +} diff --git a/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart b/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart index 3b0cb7314e..566e6f0313 100644 --- a/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart +++ b/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart @@ -699,6 +699,98 @@ void main() { .deleteDraftMessageByCid(cid, parentId: parentId)).called(1); }); + test('getLocationsByCid', () async { + const cid = 'testCid'; + final locations = List.generate( + 3, + (index) => Location( + channelCid: cid, + messageId: 'testMessageId$index', + userId: 'testUserId$index', + latitude: 37.7749 + index * 0.001, + longitude: -122.4194 + index * 0.001, + createdByDeviceId: 'testDevice$index', + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + ), + ); + + when(() => mockDatabase.locationDao.getLocationsByCid(cid)) + .thenAnswer((_) async => locations); + + final fetchedLocations = await client.getLocationsByCid(cid); + expect(fetchedLocations.length, locations.length); + verify(() => mockDatabase.locationDao.getLocationsByCid(cid)).called(1); + }); + + test('getLocationByMessageId', () async { + const messageId = 'testMessageId'; + final location = Location( + channelCid: 'testCid', + messageId: messageId, + userId: 'testUserId', + latitude: 37.7749, + longitude: -122.4194, + createdByDeviceId: 'testDevice', + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + ); + + when(() => mockDatabase.locationDao.getLocationByMessageId(messageId)) + .thenAnswer((_) async => location); + + final fetchedLocation = await client.getLocationByMessageId(messageId); + expect(fetchedLocation, isNotNull); + expect(fetchedLocation!.messageId, messageId); + verify(() => mockDatabase.locationDao.getLocationByMessageId(messageId)) + .called(1); + }); + + test('updateLocations', () async { + final locations = List.generate( + 3, + (index) => Location( + channelCid: 'testCid$index', + messageId: 'testMessageId$index', + userId: 'testUserId$index', + latitude: 37.7749 + index * 0.001, + longitude: -122.4194 + index * 0.001, + createdByDeviceId: 'testDevice$index', + createdAt: DateTime.now(), + updatedAt: DateTime.now(), + ), + ); + + when(() => mockDatabase.locationDao.updateLocations(locations)) + .thenAnswer((_) async {}); + + await client.updateLocations(locations); + verify(() => mockDatabase.locationDao.updateLocations(locations)) + .called(1); + }); + + test('deleteLocationsByCid', () async { + const cid = 'testCid'; + when(() => mockDatabase.locationDao.deleteLocationsByCid(cid)) + .thenAnswer((_) async {}); + + await client.deleteLocationsByCid(cid); + verify(() => mockDatabase.locationDao.deleteLocationsByCid(cid)) + .called(1); + }); + + test('deleteLocationsByMessageIds', () async { + final messageIds = ['testMessageId1', 'testMessageId2']; + when( + () => mockDatabase.locationDao.deleteLocationsByMessageIds(messageIds), + ).thenAnswer((_) async {}); + + await client.deleteLocationsByMessageIds(messageIds); + verify( + () => mockDatabase.locationDao.deleteLocationsByMessageIds(messageIds), + ).called(1); + }); + tearDown(() async { await client.disconnect(flush: true); }); From 7fe34aa7cd6d7875f9062d30b36b2c5e5d6ef77f Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 25 Jul 2025 11:06:20 +0200 Subject: [PATCH 21/34] feat(llc, ui, persistence)!: add support for reaction emoji_code (#2326) --- migrations/v10-migration.md | 63 +++ packages/stream_chat/CHANGELOG.md | 6 + .../stream_chat/lib/src/client/channel.dart | 76 ++-- .../stream_chat/lib/src/client/client.dart | 26 +- .../lib/src/core/api/message_api.dart | 15 +- .../lib/src/core/models/reaction.dart | 62 ++- .../lib/src/core/models/reaction.g.dart | 14 +- .../stream_chat/test/fixtures/reaction.json | 1 + .../test/src/client/channel_test.dart | 210 ++------- .../test/src/client/client_test.dart | 122 +----- .../test/src/core/api/message_api_test.dart | 37 +- .../test/src/core/models/reaction_test.dart | 30 +- packages/stream_chat_flutter/CHANGELOG.md | 7 + .../src/message_widget/message_widget.dart | 2 +- .../lib/src/misc/reaction_icon.dart | 35 +- .../reactions/desktop_reactions_builder.dart | 3 +- .../picker/reaction_picker_icon_list.dart | 2 +- packages/stream_chat_persistence/CHANGELOG.md | 1 + .../lib/src/db/drift_chat_database.dart | 2 +- .../lib/src/db/drift_chat_database.g.dart | 412 ++++++++++++++---- .../src/entity/pinned_message_reactions.dart | 5 +- .../lib/src/entity/reactions.dart | 13 +- .../pinned_message_reaction_mapper.dart | 16 +- .../lib/src/mapper/reaction_mapper.dart | 16 +- .../dao/pinned_message_reaction_dao_test.dart | 82 +++- .../test/src/dao/reaction_dao_test.dart | 80 +++- .../pinned_message_reaction_mapper_test.dart | 16 +- .../test/src/mapper/reaction_mapper_test.dart | 16 +- 28 files changed, 819 insertions(+), 551 deletions(-) diff --git a/migrations/v10-migration.md b/migrations/v10-migration.md index 0575d9eac0..951fd6c344 100644 --- a/migrations/v10-migration.md +++ b/migrations/v10-migration.md @@ -8,6 +8,10 @@ This guide includes breaking changes grouped by release phase: +### 🚧 v10.0.0-beta.4 + +- [SendReaction](#-sendreaction) + ### 🚧 v10.0.0-beta.3 - [AttachmentPickerType](#-attachmentpickertype) @@ -24,6 +28,65 @@ This guide includes breaking changes grouped by release phase: --- +## 🧪 Migration for v10.0.0-beta.4 + +### 🛠 SendReaction + +#### Key Changes: + +- `sendReaction` method now accepts a full `Reaction` object instead of individual parameters. + +#### Migration Steps: + +**Before:** +```dart +// Using individual parameters +channel.sendReaction( + message, + 'like', + score: 1, + extraData: {'custom_field': 'value'}, +); + +client.sendReaction( + messageId, + 'love', + enforceUnique: true, + extraData: {'custom_field': 'value'}, +); +``` + +**After:** +```dart +// Using Reaction object +channel.sendReaction( + message, + Reaction( + type: 'like', + score: 1, + emojiCode: '👍', + extraData: {'custom_field': 'value'}, + ), +); + +client.sendReaction( + messageId, + Reaction( + type: 'love', + emojiCode: '❤️', + extraData: {'custom_field': 'value'}, + ), + enforceUnique: true, +); +``` + +> ⚠️ **Important:** +> - The `sendReaction` method now requires a `Reaction` object +> - Optional parameters like `enforceUnique` and `skipPush` remain as method parameters +> - You can now specify custom emoji codes for reactions using the `emojiCode` field + +--- + ## 🧪 Migration for v10.0.0-beta.3 ### 🛠 AttachmentPickerType diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 4462d77e87..a101b3992a 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,5 +1,11 @@ ## Upcoming Beta +🛑️ Breaking + +- **Changed `sendReaction` method signature**: The `sendReaction` method on both `Client` and + `Channel` now accepts a full `Reaction` object instead of individual parameters (`type`, `score`, + `extraData`). This change provides more flexibility and better type safety. + ✅ Added - Added comprehensive location sharing support with static and live location features: diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index bab7aa8f3b..efb70cf0ff 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1407,28 +1407,17 @@ class Channel { /// Set [enforceUnique] to true to remove the existing user reaction. Future sendReaction( Message message, - String type, { - int score = 1, - Map extraData = const {}, + Reaction reaction, { + bool skipPush = false, bool enforceUnique = false, }) async { _checkInitialized(); - final currentUser = _client.state.currentUser; - if (currentUser == null) { - throw StateError( - 'Cannot send reaction: current user is not available. ' - 'Ensure the client is connected and a user is set.', - ); - } final messageId = message.id; - final reaction = Reaction( - type: type, + // ignore: parameter_assignments + reaction = reaction.copyWith( messageId: messageId, - user: currentUser, - score: score, - createdAt: DateTime.timestamp(), - extraData: extraData, + user: _client.state.currentUser, ); final updatedMessage = message.addMyReaction( @@ -1441,9 +1430,8 @@ class Channel { try { final reactionResp = await _client.sendReaction( messageId, - reaction.type, - score: reaction.score, - extraData: reaction.extraData, + reaction, + skipPush: skipPush, enforceUnique: enforceUnique, ); return reactionResp; @@ -1459,6 +1447,8 @@ class Channel { Message message, Reaction reaction, ) async { + _checkInitialized(); + final updatedMessage = message.deleteMyReaction( reactionType: reaction.type, ); @@ -2843,24 +2833,25 @@ class ChannelClientState { void _listenReactionDeleted() { _subscriptions.add( _channel.on(EventType.reactionDeleted).listen((event) { - final eventMessage = event.message; - if (eventMessage == null) return; - - final reaction = event.reaction; - if (reaction == null) return; + final (eventReaction, eventMessage) = (event.reaction, event.message); + if (eventReaction == null || eventMessage == null) return; final messageId = eventMessage.id; final parentId = eventMessage.parentId; for (final message in [...messages, ...?threads[parentId]]) { if (message.id == messageId) { - final updatedOwnReactions = message.ownReactions?.where((it) { - return it.userId != reaction.userId || it.type != reaction.type; - }); + final currentUserId = _channel.client.state.currentUser?.id; + + final currentMessage = switch (currentUserId) { + final userId? when userId == eventReaction.userId => + message.deleteMyReaction(reactionType: eventReaction.type), + _ => message, + }; return updateMessage( eventMessage.copyWith( - ownReactions: updatedOwnReactions?.toList(), + ownReactions: currentMessage.ownReactions, ), ); } @@ -2871,17 +2862,25 @@ class ChannelClientState { void _listenReactionNew() { _subscriptions.add(_channel.on(EventType.reactionNew).listen((event) { - final eventMessage = event.message; - if (eventMessage == null) return; + final (eventReaction, eventMessage) = (event.reaction, event.message); + if (eventReaction == null || eventMessage == null) return; final messageId = eventMessage.id; final parentId = eventMessage.parentId; for (final message in [...messages, ...?threads[parentId]]) { if (message.id == messageId) { + final currentUserId = _channel.client.state.currentUser?.id; + + final currentMessage = switch (currentUserId) { + final userId? when userId == eventReaction.userId => + message.addMyReaction(eventReaction), + _ => message, + }; + return updateMessage( eventMessage.copyWith( - ownReactions: message.ownReactions, + ownReactions: currentMessage.ownReactions, ), ); } @@ -2892,17 +2891,26 @@ class ChannelClientState { void _listenReactionUpdated() { _subscriptions.add( _channel.on(EventType.reactionUpdated).listen((event) { - final eventMessage = event.message; - if (eventMessage == null) return; + final (eventReaction, eventMessage) = (event.reaction, event.message); + if (eventReaction == null || eventMessage == null) return; final messageId = eventMessage.id; final parentId = eventMessage.parentId; for (final message in [...messages, ...?threads[parentId]]) { if (message.id == messageId) { + final currentUserId = _channel.client.state.currentUser?.id; + + final currentMessage = switch (currentUserId) { + final userId? when userId == eventReaction.userId => + // reaction.updated is only called if enforce_unique is true + message.addMyReaction(eventReaction, enforceUnique: true), + _ => message, + }; + return updateMessage( eventMessage.copyWith( - ownReactions: message.ownReactions, + ownReactions: currentMessage.ownReactions, ), ); } diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index e059436ff8..f68e8282b5 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -34,6 +34,7 @@ import 'package:stream_chat/src/core/models/own_user.dart'; import 'package:stream_chat/src/core/models/poll.dart'; import 'package:stream_chat/src/core/models/poll_option.dart'; import 'package:stream_chat/src/core/models/poll_vote.dart'; +import 'package:stream_chat/src/core/models/reaction.dart'; import 'package:stream_chat/src/core/models/thread.dart'; import 'package:stream_chat/src/core/models/user.dart'; import 'package:stream_chat/src/core/util/event_controller.dart'; @@ -1587,23 +1588,16 @@ class StreamChatClient { /// Set [enforceUnique] to true to remove the existing user reaction Future sendReaction( String messageId, - String reactionType, { - int score = 1, - Map extraData = const {}, + Reaction reaction, { + bool skipPush = false, bool enforceUnique = false, - }) { - final _extraData = { - 'score': score, - ...extraData, - }; - - return _chatApi.message.sendReaction( - messageId, - reactionType, - extraData: _extraData, - enforceUnique: enforceUnique, - ); - } + }) => + _chatApi.message.sendReaction( + messageId, + reaction, + skipPush: skipPush, + enforceUnique: enforceUnique, + ); /// Delete a [reactionType] from this [messageId] Future deleteReaction( diff --git a/packages/stream_chat/lib/src/core/api/message_api.dart b/packages/stream_chat/lib/src/core/api/message_api.dart index afd00caed6..f1f7fd1ade 100644 --- a/packages/stream_chat/lib/src/core/api/message_api.dart +++ b/packages/stream_chat/lib/src/core/api/message_api.dart @@ -8,6 +8,7 @@ import 'package:stream_chat/src/core/models/draft.dart'; import 'package:stream_chat/src/core/models/draft_message.dart'; import 'package:stream_chat/src/core/models/filter.dart'; import 'package:stream_chat/src/core/models/message.dart'; +import 'package:stream_chat/src/core/models/reaction.dart'; /// Defines the api dedicated to messages operations class MessageApi { @@ -208,19 +209,17 @@ class MessageApi { /// Set [enforceUnique] to true to remove the existing user reaction Future sendReaction( String messageId, - String reactionType, { - Map extraData = const {}, + Reaction reaction, { + bool skipPush = false, bool enforceUnique = false, }) async { - final reaction = Map.from(extraData) - ..addAll({'type': reactionType}); - final response = await _client.post( '/messages/$messageId/reaction', - data: { - 'reaction': reaction, + data: json.encode({ + 'reaction': reaction.toJson(), + 'skip_push': skipPush, 'enforce_unique': enforceUnique, - }, + }), ); return SendReactionResponse.fromJson(response.data); } diff --git a/packages/stream_chat/lib/src/core/models/reaction.dart b/packages/stream_chat/lib/src/core/models/reaction.dart index 474b6dff6a..dc62fd7ce7 100644 --- a/packages/stream_chat/lib/src/core/models/reaction.dart +++ b/packages/stream_chat/lib/src/core/models/reaction.dart @@ -1,3 +1,4 @@ +import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:stream_chat/src/core/models/user.dart'; import 'package:stream_chat/src/core/util/serializer.dart'; @@ -6,18 +7,21 @@ part 'reaction.g.dart'; /// The class that defines a reaction @JsonSerializable() -class Reaction { +class Reaction extends Equatable { /// Constructor used for json serialization Reaction({ this.messageId, - DateTime? createdAt, required this.type, this.user, String? userId, - this.score = 0, + this.score = 1, + this.emojiCode, + DateTime? createdAt, + DateTime? updatedAt, this.extraData = const {}, }) : userId = userId ?? user?.id, - createdAt = createdAt ?? DateTime.now(); + createdAt = createdAt ?? DateTime.timestamp(), + updatedAt = updatedAt ?? DateTime.timestamp(); /// Create a new instance from a json factory Reaction.fromJson(Map json) => @@ -27,37 +31,48 @@ class Reaction { )); /// The messageId to which the reaction belongs + @JsonKey(includeToJson: false) final String? messageId; /// The type of the reaction final String type; - /// The date of the reaction - @JsonKey(includeToJson: false) - final DateTime createdAt; + /// The score of the reaction (ie. number of reactions sent) + final int score; + + /// The emoji code of the reaction (used for notifications) + @JsonKey(includeIfNull: false) + final String? emojiCode; /// The user that sent the reaction @JsonKey(includeToJson: false) final User? user; - /// The score of the reaction (ie. number of reactions sent) - final int score; - /// The userId that sent the reaction @JsonKey(includeToJson: false) final String? userId; + /// The date of the reaction + @JsonKey(includeToJson: false) + final DateTime createdAt; + + /// The date of the reaction update + @JsonKey(includeToJson: false) + final DateTime updatedAt; + /// Reaction custom extraData final Map extraData; /// Map of custom user extraData static const topLevelFields = [ 'message_id', - 'created_at', 'type', 'user', 'user_id', 'score', + 'emoji_code', + 'created_at', + 'updated_at', ]; /// Serialize to json @@ -68,20 +83,24 @@ class Reaction { /// Creates a copy of [Reaction] with specified attributes overridden. Reaction copyWith({ String? messageId, - DateTime? createdAt, String? type, User? user, String? userId, int? score, + String? emojiCode, + DateTime? createdAt, + DateTime? updatedAt, Map? extraData, }) => Reaction( messageId: messageId ?? this.messageId, - createdAt: createdAt ?? this.createdAt, type: type ?? this.type, user: user ?? this.user, userId: userId ?? this.userId, score: score ?? this.score, + emojiCode: emojiCode ?? this.emojiCode, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, extraData: extraData ?? this.extraData, ); @@ -89,11 +108,26 @@ class Reaction { /// given [other] reaction. Reaction merge(Reaction other) => copyWith( messageId: other.messageId, - createdAt: other.createdAt, type: other.type, user: other.user, userId: other.userId, score: other.score, + emojiCode: other.emojiCode, + createdAt: other.createdAt, + updatedAt: other.updatedAt, extraData: other.extraData, ); + + @override + List get props => [ + messageId, + type, + user, + userId, + score, + emojiCode, + createdAt, + updatedAt, + extraData, + ]; } diff --git a/packages/stream_chat/lib/src/core/models/reaction.g.dart b/packages/stream_chat/lib/src/core/models/reaction.g.dart index 3be01abc33..f29c4e0931 100644 --- a/packages/stream_chat/lib/src/core/models/reaction.g.dart +++ b/packages/stream_chat/lib/src/core/models/reaction.g.dart @@ -8,21 +8,25 @@ part of 'reaction.dart'; Reaction _$ReactionFromJson(Map json) => Reaction( messageId: json['message_id'] as String?, - createdAt: json['created_at'] == null - ? null - : DateTime.parse(json['created_at'] as String), type: json['type'] as String, user: json['user'] == null ? null : User.fromJson(json['user'] as Map), userId: json['user_id'] as String?, - score: (json['score'] as num?)?.toInt() ?? 0, + score: (json['score'] as num?)?.toInt() ?? 1, + emojiCode: json['emoji_code'] as String?, + createdAt: json['created_at'] == null + ? null + : DateTime.parse(json['created_at'] as String), + updatedAt: json['updated_at'] == null + ? null + : DateTime.parse(json['updated_at'] as String), extraData: json['extra_data'] as Map? ?? const {}, ); Map _$ReactionToJson(Reaction instance) => { - 'message_id': instance.messageId, 'type': instance.type, 'score': instance.score, + if (instance.emojiCode case final value?) 'emoji_code': value, 'extra_data': instance.extraData, }; diff --git a/packages/stream_chat/test/fixtures/reaction.json b/packages/stream_chat/test/fixtures/reaction.json index ce87ca1d20..c0e8ef35c5 100644 --- a/packages/stream_chat/test/fixtures/reaction.json +++ b/packages/stream_chat/test/fixtures/reaction.json @@ -13,6 +13,7 @@ }, "type": "wow", "score": 1, + "emoji_code": "\uD83D\uDE2E", "created_at": "2020-01-28T22:17:31.108742Z", "updated_at": "2020-01-28T22:17:31.108742Z" } \ No newline at end of file diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index a07f7fbbae..f8bbb21e65 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -1505,67 +1505,24 @@ void main() { group('`.sendReaction`', () { test('should work fine', () async { - const type = 'test-reaction-type'; final message = Message( id: 'test-message-id', state: MessageState.sent, ); - final reaction = Reaction(type: type, messageId: message.id); + const type = 'like'; + const emojiCode = '👍'; + const score = 4; - when(() => client.sendReaction(message.id, type)).thenAnswer( - (_) async => SendReactionResponse() - ..message = message - ..reaction = reaction, - ); - - expectLater( - // skipping first seed message list -> [] messages - channel.state?.messagesStream.skip(1), - emitsInOrder([ - [ - isSameMessageAs( - message.copyWith( - state: MessageState.sent, - reactionGroups: {type: ReactionGroup(count: 1, sumScores: 1)}, - latestReactions: [reaction], - ownReactions: [reaction], - ), - matchReactions: true, - matchMessageState: true, - ), - ], - ]), - ); - - final res = await channel.sendReaction(message, type); - - expect(res, isNotNull); - expect(res.reaction.type, type); - expect(res.reaction.messageId, message.id); - - verify(() => client.sendReaction(message.id, type)).called(1); - }); - - test('should work fine with score passed explicitly', () async { - const type = 'test-reaction-type'; - final message = Message( - id: 'test-message-id', - state: MessageState.sent, - ); - - const score = 5; final reaction = Reaction( type: type, messageId: message.id, + emojiCode: emojiCode, score: score, + user: client.state.currentUser, ); - when(() => client.sendReaction( - message.id, - type, - score: score, - )).thenAnswer( + when(() => client.sendReaction(message.id, reaction)).thenAnswer( (_) async => SendReactionResponse() ..message = message ..reaction = reaction, @@ -1579,12 +1536,7 @@ void main() { isSameMessageAs( message.copyWith( state: MessageState.sent, - reactionGroups: { - type: ReactionGroup( - count: 1, - sumScores: score, - ) - }, + reactionGroups: {type: ReactionGroup(count: 1, sumScores: 1)}, latestReactions: [reaction], ownReactions: [reaction], ), @@ -1595,99 +1547,15 @@ void main() { ]), ); - final res = await channel.sendReaction( - message, - type, - score: score, - ); + final res = await channel.sendReaction(message, reaction); expect(res, isNotNull); expect(res.reaction.type, type); expect(res.reaction.messageId, message.id); + expect(res.reaction.emojiCode, emojiCode); expect(res.reaction.score, score); - verify(() => client.sendReaction( - message.id, - type, - score: score, - )).called(1); - }); - - test('should work fine with score passed explicitly and in extraData', - () async { - const type = 'test-reaction-type'; - final message = Message( - id: 'test-message-id', - state: MessageState.sent, - ); - - const score = 5; - const extraDataScore = 3; - const extraData = { - 'score': extraDataScore, - }; - final reaction = Reaction( - type: type, - messageId: message.id, - score: extraDataScore, - ); - - when(() => client.sendReaction( - message.id, - type, - score: score, - extraData: extraData, - )).thenAnswer( - (_) async => SendReactionResponse() - ..message = message - ..reaction = reaction, - ); - - expectLater( - // skipping first seed message list -> [] messages - channel.state?.messagesStream.skip(1), - emitsInOrder([ - [ - isSameMessageAs( - message.copyWith( - state: MessageState.sent, - reactionGroups: { - type: ReactionGroup( - count: 1, - sumScores: extraDataScore, - ) - }, - latestReactions: [reaction], - ownReactions: [reaction], - ), - matchReactions: true, - matchMessageState: true, - ), - ], - ]), - ); - - final res = await channel.sendReaction( - message, - type, - score: score, - extraData: extraData, - ); - - expect(res, isNotNull); - expect(res.reaction.type, type); - expect(res.reaction.messageId, message.id); - expect( - res.reaction.score, - extraDataScore, - ); - - verify(() => client.sendReaction( - message.id, - type, - score: score, - extraData: extraData, - )).called(1); + verify(() => client.sendReaction(message.id, reaction)).called(1); }); test( @@ -1699,9 +1567,13 @@ void main() { state: MessageState.sent, ); - final reaction = Reaction(type: type, messageId: message.id); + final reaction = Reaction( + type: type, + messageId: message.id, + user: client.state.currentUser, + ); - when(() => client.sendReaction(message.id, type)) + when(() => client.sendReaction(message.id, reaction)) .thenThrow(StreamChatNetworkError(ChatErrorCode.inputError)); expectLater( @@ -1736,25 +1608,24 @@ void main() { ); try { - await channel.sendReaction(message, type); + await channel.sendReaction(message, reaction); } catch (e) { expect(e, isA()); } - verify(() => client.sendReaction(message.id, type)).called(1); + verify(() => client.sendReaction(message.id, reaction)).called(1); }, ); test( '''should override previous reaction if present and `enforceUnique` is true''', () async { - const userId = 'test-user-id'; const messageId = 'test-message-id'; const prevType = 'test-reaction-type'; final prevReaction = Reaction( type: prevType, messageId: messageId, - userId: userId, + user: client.state.currentUser, ); final message = Message( id: messageId, @@ -1773,7 +1644,7 @@ void main() { final newReaction = Reaction( type: type, messageId: messageId, - userId: userId, + user: client.state.currentUser, ); final newMessage = message.copyWith( ownReactions: [newReaction], @@ -1784,7 +1655,7 @@ void main() { when(() => client.sendReaction( messageId, - type, + newReaction, enforceUnique: enforceUnique, )).thenAnswer( (_) async => SendReactionResponse() @@ -1808,7 +1679,7 @@ void main() { final res = await channel.sendReaction( message, - type, + newReaction, enforceUnique: enforceUnique, ); @@ -1818,7 +1689,7 @@ void main() { verify(() => client.sendReaction( messageId, - type, + newReaction, enforceUnique: enforceUnique, )).called(1); }, @@ -1834,9 +1705,13 @@ void main() { state: MessageState.sent, ); - final reaction = Reaction(type: type, messageId: message.id); + final reaction = Reaction( + type: type, + messageId: message.id, + user: client.state.currentUser, + ); - when(() => client.sendReaction(message.id, type)).thenAnswer( + when(() => client.sendReaction(message.id, reaction)).thenAnswer( (_) async => SendReactionResponse() ..message = message ..reaction = reaction, @@ -1869,13 +1744,13 @@ void main() { ]), ); - final res = await channel.sendReaction(message, type); + final res = await channel.sendReaction(message, reaction); expect(res, isNotNull); expect(res.reaction.type, type); expect(res.reaction.messageId, message.id); - verify(() => client.sendReaction(message.id, type)).called(1); + verify(() => client.sendReaction(message.id, reaction)).called(1); }); test( @@ -1888,9 +1763,13 @@ void main() { state: MessageState.sent, ); - final reaction = Reaction(type: type, messageId: message.id); + final reaction = Reaction( + type: type, + messageId: message.id, + user: client.state.currentUser, + ); - when(() => client.sendReaction(message.id, type)) + when(() => client.sendReaction(message.id, reaction)) .thenThrow(StreamChatNetworkError(ChatErrorCode.inputError)); expectLater( @@ -1929,26 +1808,25 @@ void main() { ); try { - await channel.sendReaction(message, type); + await channel.sendReaction(message, reaction); } catch (e) { expect(e, isA()); } - verify(() => client.sendReaction(message.id, type)).called(1); + verify(() => client.sendReaction(message.id, reaction)).called(1); }, ); test( '''should override previous thread reaction if present and `enforceUnique` is true''', () async { - const userId = 'test-user-id'; const messageId = 'test-message-id'; const parentId = 'test-parent-id'; const prevType = 'test-reaction-type'; final prevReaction = Reaction( type: prevType, messageId: messageId, - userId: userId, + user: client.state.currentUser, ); final message = Message( id: messageId, @@ -1968,7 +1846,7 @@ void main() { final newReaction = Reaction( type: type, messageId: messageId, - userId: userId, + user: client.state.currentUser, ); final newMessage = message.copyWith( ownReactions: [newReaction], @@ -1979,7 +1857,7 @@ void main() { when(() => client.sendReaction( messageId, - type, + newReaction, enforceUnique: enforceUnique, )).thenAnswer( (_) async => SendReactionResponse() @@ -2006,7 +1884,7 @@ void main() { final res = await channel.sendReaction( message, - type, + newReaction, enforceUnique: enforceUnique, ); @@ -2016,7 +1894,7 @@ void main() { verify(() => client.sendReaction( messageId, - type, + newReaction, enforceUnique: enforceUnique, )).called(1); }, diff --git a/packages/stream_chat/test/src/client/client_test.dart b/packages/stream_chat/test/src/client/client_test.dart index 95f48ab2c5..dd29a9e4c5 100644 --- a/packages/stream_chat/test/src/client/client_test.dart +++ b/packages/stream_chat/test/src/client/client_test.dart @@ -3231,109 +3231,35 @@ void main() { verifyNoMoreInteractions(api.channel); }); - group('`.sendReaction`', () { - test('`.sendReaction with default params`', () async { - const messageId = 'test-message-id'; - const reactionType = 'like'; - const extraData = {'score': 1}; - - when(() => api.message.sendReaction( - messageId, - reactionType, - extraData: extraData, - )).thenAnswer((_) async => SendReactionResponse() - ..message = Message(id: messageId) - ..reaction = Reaction(type: reactionType, messageId: messageId)); - - final res = await client.sendReaction(messageId, reactionType); - expect(res, isNotNull); - expect(res.message.id, messageId); - expect(res.reaction.type, reactionType); - expect(res.reaction.messageId, messageId); - - verify(() => api.message.sendReaction( - messageId, - reactionType, - extraData: extraData, - )).called(1); - verifyNoMoreInteractions(api.message); - }); - - test('`.sendReaction with score`', () async { - const messageId = 'test-message-id'; - const reactionType = 'like'; - const score = 3; - const extraData = {'score': score}; - - when(() => api.message.sendReaction( - messageId, - reactionType, - extraData: extraData, - )).thenAnswer((_) async => SendReactionResponse() - ..message = Message(id: messageId) - ..reaction = Reaction( - type: reactionType, - messageId: messageId, - score: score, - )); - - final res = await client.sendReaction( - messageId, - reactionType, - score: score, - ); - expect(res, isNotNull); - expect(res.message.id, messageId); - expect(res.reaction.type, reactionType); - expect(res.reaction.messageId, messageId); - expect(res.reaction.score, score); - - verify(() => api.message.sendReaction( - messageId, - reactionType, - extraData: extraData, - )).called(1); - verifyNoMoreInteractions(api.message); - }); + test('`.sendReaction`', () async { + const messageId = 'test-message-id'; + const reactionType = 'like'; + const emojiCode = '👍'; + const score = 4; - test('`.sendReaction with score passed in extradata also`', () async { - const messageId = 'test-message-id'; - const reactionType = 'like'; - const score = 3; - const extraDataScore = 5; - const extraData = {'score': extraDataScore}; + final reaction = Reaction( + type: reactionType, + messageId: messageId, + emojiCode: emojiCode, + score: score, + ); - when(() => api.message.sendReaction( - messageId, - reactionType, - extraData: extraData, - )).thenAnswer((_) async => SendReactionResponse() + when(() => api.message.sendReaction(messageId, reaction)).thenAnswer( + (_) async => SendReactionResponse() ..message = Message(id: messageId) - ..reaction = Reaction( - type: reactionType, - messageId: messageId, - score: extraDataScore, - )); + ..reaction = reaction, + ); - final res = await client.sendReaction( - messageId, - reactionType, - score: score, - extraData: extraData, - ); - expect(res, isNotNull); - expect(res.message.id, messageId); - expect(res.reaction.type, reactionType); - expect(res.reaction.messageId, messageId); - expect(res.reaction.score, extraDataScore); + final res = await client.sendReaction(messageId, reaction); + expect(res, isNotNull); + expect(res.message.id, messageId); + expect(res.reaction.type, reactionType); + expect(res.reaction.emojiCode, emojiCode); + expect(res.reaction.score, score); + expect(res.reaction.messageId, messageId); - verify(() => api.message.sendReaction( - messageId, - reactionType, - extraData: extraData, - )).called(1); - verifyNoMoreInteractions(api.message); - }); + verify(() => api.message.sendReaction(messageId, reaction)).called(1); + verifyNoMoreInteractions(api.message); }); test('`.deleteReaction`', () async { diff --git a/packages/stream_chat/test/src/core/api/message_api_test.dart b/packages/stream_chat/test/src/core/api/message_api_test.dart index 6f224e8764..ac726ccdb0 100644 --- a/packages/stream_chat/test/src/core/api/message_api_test.dart +++ b/packages/stream_chat/test/src/core/api/message_api_test.dart @@ -253,7 +253,6 @@ void main() { test('sendReaction', () async { const messageId = 'test-message-id'; const reactionType = 'test-reaction-type'; - const extraData = {'test-key': 'test-data'}; const path = '/messages/$messageId/reaction'; @@ -262,21 +261,17 @@ void main() { when(() => client.post( path, - data: { - 'reaction': Map.from(extraData) - ..addAll({'type': reactionType}), + data: jsonEncode({ + 'reaction': reaction.toJson(), + 'skip_push': false, 'enforce_unique': false, - }, + }), )).thenAnswer((_) async => successResponse(path, data: { 'message': message.toJson(), - 'reaction': reaction.toJson(), + 'reaction': {...reaction.toJson(), 'message_id': messageId}, })); - final res = await messageApi.sendReaction( - messageId, - reactionType, - extraData: extraData, - ); + final res = await messageApi.sendReaction(messageId, reaction); expect(res, isNotNull); expect(res.message.id, messageId); @@ -290,7 +285,6 @@ void main() { test('sendReaction with enforceUnique: true', () async { const messageId = 'test-message-id'; const reactionType = 'test-reaction-type'; - const extraData = {'test-key': 'test-data'}; const path = '/messages/$messageId/reaction'; @@ -299,20 +293,19 @@ void main() { when(() => client.post( path, - data: { - 'reaction': Map.from(extraData) - ..addAll({'type': reactionType}), + data: jsonEncode({ + 'reaction': reaction.toJson(), + 'skip_push': false, 'enforce_unique': true, - }, + }), )).thenAnswer((_) async => successResponse(path, data: { 'message': message.toJson(), - 'reaction': reaction.toJson(), + 'reaction': {...reaction.toJson(), 'message_id': messageId}, })); final res = await messageApi.sendReaction( messageId, - reactionType, - extraData: extraData, + reaction, enforceUnique: true, ); @@ -362,7 +355,11 @@ void main() { ...const PaginationParams().toJson(), }, )).thenAnswer((_) async => successResponse(path, data: { - 'reactions': [...reactions.map((it) => it.toJson())] + 'reactions': [ + ...reactions.map( + (it) => {...it.toJson(), 'message_id': messageId}, + ), + ] })); final res = await messageApi.getReactions(messageId, pagination: options); diff --git a/packages/stream_chat/test/src/core/models/reaction_test.dart b/packages/stream_chat/test/src/core/models/reaction_test.dart index 285d8a4614..6abd278d1e 100644 --- a/packages/stream_chat/test/src/core/models/reaction_test.dart +++ b/packages/stream_chat/test/src/core/models/reaction_test.dart @@ -10,6 +10,7 @@ void main() { final reaction = Reaction.fromJson(jsonFixture('reaction.json')); expect(reaction.messageId, '76cd8c82-b557-4e48-9d12-87995d3a0e04'); expect(reaction.createdAt, DateTime.parse('2020-01-28T22:17:31.108742Z')); + expect(reaction.updatedAt, DateTime.parse('2020-01-28T22:17:31.108742Z')); expect(reaction.type, 'wow'); expect( reaction.user?.toJson(), @@ -21,13 +22,14 @@ void main() { ); expect(reaction.score, 1); expect(reaction.userId, '2de0297c-f3f2-489d-b930-ef77342edccf'); - expect(reaction.extraData, {'updated_at': '2020-01-28T22:17:31.108742Z'}); + expect(reaction.emojiCode, '😮'); }); test('should serialize to json correctly', () { final reaction = Reaction( messageId: '76cd8c82-b557-4e48-9d12-87995d3a0e04', createdAt: DateTime.parse('2020-01-28T22:17:31.108742Z'), + updatedAt: DateTime.parse('2020-01-28T22:17:31.108742Z'), type: 'wow', user: User( id: '2de0297c-f3f2-489d-b930-ef77342edccf', @@ -35,16 +37,16 @@ void main() { name: 'Daisy Morgan', ), userId: '2de0297c-f3f2-489d-b930-ef77342edccf', - extraData: {'bananas': 'yes'}, - score: 1, + extraData: const {'bananas': 'yes'}, + emojiCode: '😮', ); expect( reaction.toJson(), { - 'message_id': '76cd8c82-b557-4e48-9d12-87995d3a0e04', 'type': 'wow', 'score': 1, + 'emoji_code': '😮', 'bananas': 'yes', }, ); @@ -56,6 +58,8 @@ void main() { expect(newReaction.messageId, '76cd8c82-b557-4e48-9d12-87995d3a0e04'); expect( newReaction.createdAt, DateTime.parse('2020-01-28T22:17:31.108742Z')); + expect( + newReaction.updatedAt, DateTime.parse('2020-01-28T22:17:31.108742Z')); expect(newReaction.type, 'wow'); expect( newReaction.user?.toJson(), @@ -67,14 +71,15 @@ void main() { ); expect(newReaction.score, 1); expect(newReaction.userId, '2de0297c-f3f2-489d-b930-ef77342edccf'); - expect( - newReaction.extraData, {'updated_at': '2020-01-28T22:17:31.108742Z'}); + expect(newReaction.emojiCode, '😮'); final newUserCreateTime = DateTime.now(); newReaction = reaction.copyWith( type: 'lol', + emojiCode: '😂', createdAt: DateTime.parse('2021-01-28T22:17:31.108742Z'), + updatedAt: DateTime.parse('2021-01-28T22:17:31.108742Z'), extraData: {}, messageId: 'test', score: 2, @@ -87,10 +92,15 @@ void main() { ); expect(newReaction.type, 'lol'); + expect(newReaction.emojiCode, '😂'); expect( newReaction.createdAt, DateTime.parse('2021-01-28T22:17:31.108742Z'), ); + expect( + newReaction.updatedAt, + DateTime.parse('2021-01-28T22:17:31.108742Z'), + ); expect(newReaction.extraData, {}); expect(newReaction.messageId, 'test'); expect(newReaction.score, 2); @@ -112,8 +122,9 @@ void main() { final newReaction = reaction.merge( Reaction( type: 'lol', + emojiCode: '😂', createdAt: DateTime.parse('2021-01-28T22:17:31.108742Z'), - extraData: {}, + updatedAt: DateTime.parse('2021-01-28T22:17:31.108742Z'), messageId: 'test', score: 2, user: User( @@ -126,10 +137,15 @@ void main() { ); expect(newReaction.type, 'lol'); + expect(newReaction.emojiCode, '😂'); expect( newReaction.createdAt, DateTime.parse('2021-01-28T22:17:31.108742Z'), ); + expect( + newReaction.updatedAt, + DateTime.parse('2021-01-28T22:17:31.108742Z'), + ); expect(newReaction.extraData, {}); expect(newReaction.messageId, 'test'); expect(newReaction.score, 2); diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 27f602c94c..548b912260 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,10 @@ +## Upcoming Beta + +✅ Added + +- Added `emojiCode` property to `StreamReactionIcon` to support custom emojis in reactions. +- Updated default reaction builders with standard emoji codes. (`❤️`, `👍`, `👎`, `😂`, `😮`) + ## Upcoming ✅ Added diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index 1e871fd7a2..6e6e621e10 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -1159,7 +1159,7 @@ class _StreamMessageWidgetState extends State return channel.sendReaction( message, - reaction.type, + reaction, enforceUnique: enforceUnique, ); } diff --git a/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart b/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart index 09dd2f097b..fb5ccde92e 100644 --- a/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart +++ b/packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/icons/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; +import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// {@template reactionIconBuilder} /// Signature for a function that builds a reaction icon. @@ -20,17 +21,27 @@ class StreamReactionIcon { /// {@macro streamReactionIcon} const StreamReactionIcon({ required this.type, + this.emojiCode, required this.builder, }); /// Creates a reaction icon with a default unknown icon. const StreamReactionIcon.unknown() : type = 'unknown', - builder = _unknownReactionBuilder; + emojiCode = null, + builder = _unknownBuilder; + + /// Converts this [StreamReactionIcon] to a [Reaction] object. + Reaction toReaction() => Reaction(type: type, emojiCode: emojiCode); /// Type of reaction final String type; + /// Optional emoji code for the reaction. + /// + /// Used to display a custom emoji in the notification. + final String? emojiCode; + /// {@macro reactionIconBuilder} final ReactionIconBuilder builder; @@ -46,14 +57,14 @@ class StreamReactionIcon { /// These default reactions can be used directly or as a starting point for /// custom reaction configurations. static const List defaultReactions = [ - StreamReactionIcon(type: 'love', builder: _loveReactionBuilder), - StreamReactionIcon(type: 'like', builder: _likeReactionBuilder), - StreamReactionIcon(type: 'sad', builder: _sadReactionBuilder), - StreamReactionIcon(type: 'haha', builder: _hahaReactionBuilder), - StreamReactionIcon(type: 'wow', builder: _wowReactionBuilder), + StreamReactionIcon(type: 'love', emojiCode: '❤️', builder: _loveBuilder), + StreamReactionIcon(type: 'like', emojiCode: '👍', builder: _likeBuilder), + StreamReactionIcon(type: 'sad', emojiCode: '👎', builder: _sadBuilder), + StreamReactionIcon(type: 'haha', emojiCode: '😂', builder: _hahaBuilder), + StreamReactionIcon(type: 'wow', emojiCode: '😮', builder: _wowBuilder), ]; - static Widget _loveReactionBuilder( + static Widget _loveBuilder( BuildContext context, bool highlighted, double size, @@ -71,7 +82,7 @@ class StreamReactionIcon { ); } - static Widget _likeReactionBuilder( + static Widget _likeBuilder( BuildContext context, bool highlighted, double size, @@ -89,7 +100,7 @@ class StreamReactionIcon { ); } - static Widget _sadReactionBuilder( + static Widget _sadBuilder( BuildContext context, bool highlighted, double size, @@ -107,7 +118,7 @@ class StreamReactionIcon { ); } - static Widget _hahaReactionBuilder( + static Widget _hahaBuilder( BuildContext context, bool highlighted, double size, @@ -125,7 +136,7 @@ class StreamReactionIcon { ); } - static Widget _wowReactionBuilder( + static Widget _wowBuilder( BuildContext context, bool highlighted, double size, @@ -143,7 +154,7 @@ class StreamReactionIcon { ); } - static Widget _unknownReactionBuilder( + static Widget _unknownBuilder( BuildContext context, bool highlighted, double size, diff --git a/packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart b/packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart index 390a05c11f..f228833564 100644 --- a/packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart @@ -183,8 +183,7 @@ class _BottomReaction extends StatelessWidget { } else if (reactionIcon != null) { StreamChannel.of(context).channel.sendReaction( message, - reactionIcon!.type, - score: reaction.score + 1, + reactionIcon!.toReaction(), enforceUnique: StreamChatConfiguration.of(context).enforceUniqueReactions, ); diff --git a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart index 5c2a4ad06a..0fc775fad0 100644 --- a/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart +++ b/packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart @@ -184,7 +184,7 @@ class _ReactionPickerIconListState extends State { final onPressed = switch (widget.onReactionPicked) { final onPicked? => () { - final picked = reaction ?? Reaction(type: icon.type); + final picked = reaction ?? icon.toReaction(); return onPicked(picked); }, _ => null, diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 6359160320..adc05069b5 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,6 +1,7 @@ ## Upcoming Beta - Added support for `Location` entity in the database. +- Added support for `emojiCode` and `updatedAt` fields in `Reaction` entity. ## Upcoming diff --git a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart index eaca779f8e..aa8cd3ef71 100644 --- a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart +++ b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.dart @@ -57,7 +57,7 @@ class DriftChatDatabase extends _$DriftChatDatabase { // you should bump this number whenever you change or add a table definition. @override - int get schemaVersion => 1000 + 23; + int get schemaVersion => 1000 + 24; @override MigrationStrategy get migration => MigrationStrategy( diff --git a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart index c8770ea2e2..2ec585f138 100644 --- a/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart +++ b/packages/stream_chat_persistence/lib/src/db/drift_chat_database.g.dart @@ -5905,15 +5905,15 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override late final GeneratedColumn userId = GeneratedColumn( - 'user_id', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); + 'user_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); static const VerificationMeta _messageIdMeta = const VerificationMeta('messageId'); @override late final GeneratedColumn messageId = GeneratedColumn( - 'message_id', aliasedName, false, + 'message_id', aliasedName, true, type: DriftSqlType.string, - requiredDuringInsert: true, + requiredDuringInsert: false, defaultConstraints: GeneratedColumn.constraintIsAlways( 'REFERENCES pinned_messages (id) ON DELETE CASCADE')); static const VerificationMeta _typeMeta = const VerificationMeta('type'); @@ -5921,6 +5921,12 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions late final GeneratedColumn type = GeneratedColumn( 'type', aliasedName, false, type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _emojiCodeMeta = + const VerificationMeta('emojiCode'); + @override + late final GeneratedColumn emojiCode = GeneratedColumn( + 'emoji_code', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); static const VerificationMeta _createdAtMeta = const VerificationMeta('createdAt'); @override @@ -5929,6 +5935,14 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions type: DriftSqlType.dateTime, requiredDuringInsert: false, defaultValue: currentDateAndTime); + static const VerificationMeta _updatedAtMeta = + const VerificationMeta('updatedAt'); + @override + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); static const VerificationMeta _scoreMeta = const VerificationMeta('score'); @override late final GeneratedColumn score = GeneratedColumn( @@ -5943,8 +5957,16 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions .withConverter?>( $PinnedMessageReactionsTable.$converterextraDatan); @override - List get $columns => - [userId, messageId, type, createdAt, score, extraData]; + List get $columns => [ + userId, + messageId, + type, + emojiCode, + createdAt, + updatedAt, + score, + extraData + ]; @override String get aliasedName => _alias ?? actualTableName; @override @@ -5959,14 +5981,10 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions if (data.containsKey('user_id')) { context.handle(_userIdMeta, userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); - } else if (isInserting) { - context.missing(_userIdMeta); } if (data.containsKey('message_id')) { context.handle(_messageIdMeta, messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta)); - } else if (isInserting) { - context.missing(_messageIdMeta); } if (data.containsKey('type')) { context.handle( @@ -5974,10 +5992,18 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions } else if (isInserting) { context.missing(_typeMeta); } + if (data.containsKey('emoji_code')) { + context.handle(_emojiCodeMeta, + emojiCode.isAcceptableOrUnknown(data['emoji_code']!, _emojiCodeMeta)); + } if (data.containsKey('created_at')) { context.handle(_createdAtMeta, createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); } + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + } if (data.containsKey('score')) { context.handle( _scoreMeta, score.isAcceptableOrUnknown(data['score']!, _scoreMeta)); @@ -5993,13 +6019,17 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return PinnedMessageReactionEntity( userId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, + .read(DriftSqlType.string, data['${effectivePrefix}user_id']), messageId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}message_id'])!, + .read(DriftSqlType.string, data['${effectivePrefix}message_id']), type: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}type'])!, + emojiCode: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}emoji_code']), createdAt: attachedDatabase.typeMapping .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + updatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, score: attachedDatabase.typeMapping .read(DriftSqlType.int, data['${effectivePrefix}score'])!, extraData: $PinnedMessageReactionsTable.$converterextraDatan.fromSql( @@ -6022,36 +6052,52 @@ class $PinnedMessageReactionsTable extends PinnedMessageReactions class PinnedMessageReactionEntity extends DataClass implements Insertable { /// The id of the user that sent the reaction - final String userId; + final String? userId; /// The messageId to which the reaction belongs - final String messageId; + final String? messageId; /// The type of the reaction final String type; + /// The emoji code for the reaction + final String? emojiCode; + /// The DateTime on which the reaction is created final DateTime createdAt; + /// The DateTime on which the reaction was last updated + final DateTime updatedAt; + /// The score of the reaction (ie. number of reactions sent) final int score; /// Reaction custom extraData final Map? extraData; const PinnedMessageReactionEntity( - {required this.userId, - required this.messageId, + {this.userId, + this.messageId, required this.type, + this.emojiCode, required this.createdAt, + required this.updatedAt, required this.score, this.extraData}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['user_id'] = Variable(userId); - map['message_id'] = Variable(messageId); + if (!nullToAbsent || userId != null) { + map['user_id'] = Variable(userId); + } + if (!nullToAbsent || messageId != null) { + map['message_id'] = Variable(messageId); + } map['type'] = Variable(type); + if (!nullToAbsent || emojiCode != null) { + map['emoji_code'] = Variable(emojiCode); + } map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); map['score'] = Variable(score); if (!nullToAbsent || extraData != null) { map['extra_data'] = Variable( @@ -6064,10 +6110,12 @@ class PinnedMessageReactionEntity extends DataClass {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return PinnedMessageReactionEntity( - userId: serializer.fromJson(json['userId']), - messageId: serializer.fromJson(json['messageId']), + userId: serializer.fromJson(json['userId']), + messageId: serializer.fromJson(json['messageId']), type: serializer.fromJson(json['type']), + emojiCode: serializer.fromJson(json['emojiCode']), createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), score: serializer.fromJson(json['score']), extraData: serializer.fromJson?>(json['extraData']), ); @@ -6076,27 +6124,33 @@ class PinnedMessageReactionEntity extends DataClass Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'userId': serializer.toJson(userId), - 'messageId': serializer.toJson(messageId), + 'userId': serializer.toJson(userId), + 'messageId': serializer.toJson(messageId), 'type': serializer.toJson(type), + 'emojiCode': serializer.toJson(emojiCode), 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), 'score': serializer.toJson(score), 'extraData': serializer.toJson?>(extraData), }; } PinnedMessageReactionEntity copyWith( - {String? userId, - String? messageId, + {Value userId = const Value.absent(), + Value messageId = const Value.absent(), String? type, + Value emojiCode = const Value.absent(), DateTime? createdAt, + DateTime? updatedAt, int? score, Value?> extraData = const Value.absent()}) => PinnedMessageReactionEntity( - userId: userId ?? this.userId, - messageId: messageId ?? this.messageId, + userId: userId.present ? userId.value : this.userId, + messageId: messageId.present ? messageId.value : this.messageId, type: type ?? this.type, + emojiCode: emojiCode.present ? emojiCode.value : this.emojiCode, createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, score: score ?? this.score, extraData: extraData.present ? extraData.value : this.extraData, ); @@ -6106,7 +6160,9 @@ class PinnedMessageReactionEntity extends DataClass userId: data.userId.present ? data.userId.value : this.userId, messageId: data.messageId.present ? data.messageId.value : this.messageId, type: data.type.present ? data.type.value : this.type, + emojiCode: data.emojiCode.present ? data.emojiCode.value : this.emojiCode, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, score: data.score.present ? data.score.value : this.score, extraData: data.extraData.present ? data.extraData.value : this.extraData, ); @@ -6118,7 +6174,9 @@ class PinnedMessageReactionEntity extends DataClass ..write('userId: $userId, ') ..write('messageId: $messageId, ') ..write('type: $type, ') + ..write('emojiCode: $emojiCode, ') ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') ..write('score: $score, ') ..write('extraData: $extraData') ..write(')')) @@ -6126,8 +6184,8 @@ class PinnedMessageReactionEntity extends DataClass } @override - int get hashCode => - Object.hash(userId, messageId, type, createdAt, score, extraData); + int get hashCode => Object.hash(userId, messageId, type, emojiCode, createdAt, + updatedAt, score, extraData); @override bool operator ==(Object other) => identical(this, other) || @@ -6135,17 +6193,21 @@ class PinnedMessageReactionEntity extends DataClass other.userId == this.userId && other.messageId == this.messageId && other.type == this.type && + other.emojiCode == this.emojiCode && other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && other.score == this.score && other.extraData == this.extraData); } class PinnedMessageReactionsCompanion extends UpdateCompanion { - final Value userId; - final Value messageId; + final Value userId; + final Value messageId; final Value type; + final Value emojiCode; final Value createdAt; + final Value updatedAt; final Value score; final Value?> extraData; final Value rowid; @@ -6153,27 +6215,31 @@ class PinnedMessageReactionsCompanion this.userId = const Value.absent(), this.messageId = const Value.absent(), this.type = const Value.absent(), + this.emojiCode = const Value.absent(), this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.score = const Value.absent(), this.extraData = const Value.absent(), this.rowid = const Value.absent(), }); PinnedMessageReactionsCompanion.insert({ - required String userId, - required String messageId, + this.userId = const Value.absent(), + this.messageId = const Value.absent(), required String type, + this.emojiCode = const Value.absent(), this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.score = const Value.absent(), this.extraData = const Value.absent(), this.rowid = const Value.absent(), - }) : userId = Value(userId), - messageId = Value(messageId), - type = Value(type); + }) : type = Value(type); static Insertable custom({ Expression? userId, Expression? messageId, Expression? type, + Expression? emojiCode, Expression? createdAt, + Expression? updatedAt, Expression? score, Expression? extraData, Expression? rowid, @@ -6182,7 +6248,9 @@ class PinnedMessageReactionsCompanion if (userId != null) 'user_id': userId, if (messageId != null) 'message_id': messageId, if (type != null) 'type': type, + if (emojiCode != null) 'emoji_code': emojiCode, if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, if (score != null) 'score': score, if (extraData != null) 'extra_data': extraData, if (rowid != null) 'rowid': rowid, @@ -6190,10 +6258,12 @@ class PinnedMessageReactionsCompanion } PinnedMessageReactionsCompanion copyWith( - {Value? userId, - Value? messageId, + {Value? userId, + Value? messageId, Value? type, + Value? emojiCode, Value? createdAt, + Value? updatedAt, Value? score, Value?>? extraData, Value? rowid}) { @@ -6201,7 +6271,9 @@ class PinnedMessageReactionsCompanion userId: userId ?? this.userId, messageId: messageId ?? this.messageId, type: type ?? this.type, + emojiCode: emojiCode ?? this.emojiCode, createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, score: score ?? this.score, extraData: extraData ?? this.extraData, rowid: rowid ?? this.rowid, @@ -6220,9 +6292,15 @@ class PinnedMessageReactionsCompanion if (type.present) { map['type'] = Variable(type.value); } + if (emojiCode.present) { + map['emoji_code'] = Variable(emojiCode.value); + } if (createdAt.present) { map['created_at'] = Variable(createdAt.value); } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } if (score.present) { map['score'] = Variable(score.value); } @@ -6243,7 +6321,9 @@ class PinnedMessageReactionsCompanion ..write('userId: $userId, ') ..write('messageId: $messageId, ') ..write('type: $type, ') + ..write('emojiCode: $emojiCode, ') ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') ..write('score: $score, ') ..write('extraData: $extraData, ') ..write('rowid: $rowid') @@ -6261,15 +6341,15 @@ class $ReactionsTable extends Reactions static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override late final GeneratedColumn userId = GeneratedColumn( - 'user_id', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); + 'user_id', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); static const VerificationMeta _messageIdMeta = const VerificationMeta('messageId'); @override late final GeneratedColumn messageId = GeneratedColumn( - 'message_id', aliasedName, false, + 'message_id', aliasedName, true, type: DriftSqlType.string, - requiredDuringInsert: true, + requiredDuringInsert: false, defaultConstraints: GeneratedColumn.constraintIsAlways( 'REFERENCES messages (id) ON DELETE CASCADE')); static const VerificationMeta _typeMeta = const VerificationMeta('type'); @@ -6277,6 +6357,12 @@ class $ReactionsTable extends Reactions late final GeneratedColumn type = GeneratedColumn( 'type', aliasedName, false, type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _emojiCodeMeta = + const VerificationMeta('emojiCode'); + @override + late final GeneratedColumn emojiCode = GeneratedColumn( + 'emoji_code', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); static const VerificationMeta _createdAtMeta = const VerificationMeta('createdAt'); @override @@ -6285,6 +6371,14 @@ class $ReactionsTable extends Reactions type: DriftSqlType.dateTime, requiredDuringInsert: false, defaultValue: currentDateAndTime); + static const VerificationMeta _updatedAtMeta = + const VerificationMeta('updatedAt'); + @override + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); static const VerificationMeta _scoreMeta = const VerificationMeta('score'); @override late final GeneratedColumn score = GeneratedColumn( @@ -6299,8 +6393,16 @@ class $ReactionsTable extends Reactions .withConverter?>( $ReactionsTable.$converterextraDatan); @override - List get $columns => - [userId, messageId, type, createdAt, score, extraData]; + List get $columns => [ + userId, + messageId, + type, + emojiCode, + createdAt, + updatedAt, + score, + extraData + ]; @override String get aliasedName => _alias ?? actualTableName; @override @@ -6314,14 +6416,10 @@ class $ReactionsTable extends Reactions if (data.containsKey('user_id')) { context.handle(_userIdMeta, userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); - } else if (isInserting) { - context.missing(_userIdMeta); } if (data.containsKey('message_id')) { context.handle(_messageIdMeta, messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta)); - } else if (isInserting) { - context.missing(_messageIdMeta); } if (data.containsKey('type')) { context.handle( @@ -6329,10 +6427,18 @@ class $ReactionsTable extends Reactions } else if (isInserting) { context.missing(_typeMeta); } + if (data.containsKey('emoji_code')) { + context.handle(_emojiCodeMeta, + emojiCode.isAcceptableOrUnknown(data['emoji_code']!, _emojiCodeMeta)); + } if (data.containsKey('created_at')) { context.handle(_createdAtMeta, createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); } + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + } if (data.containsKey('score')) { context.handle( _scoreMeta, score.isAcceptableOrUnknown(data['score']!, _scoreMeta)); @@ -6347,13 +6453,17 @@ class $ReactionsTable extends Reactions final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return ReactionEntity( userId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, + .read(DriftSqlType.string, data['${effectivePrefix}user_id']), messageId: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}message_id'])!, + .read(DriftSqlType.string, data['${effectivePrefix}message_id']), type: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}type'])!, + emojiCode: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}emoji_code']), createdAt: attachedDatabase.typeMapping .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + updatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, score: attachedDatabase.typeMapping .read(DriftSqlType.int, data['${effectivePrefix}score'])!, extraData: $ReactionsTable.$converterextraDatan.fromSql(attachedDatabase @@ -6375,36 +6485,52 @@ class $ReactionsTable extends Reactions class ReactionEntity extends DataClass implements Insertable { /// The id of the user that sent the reaction - final String userId; + final String? userId; /// The messageId to which the reaction belongs - final String messageId; + final String? messageId; /// The type of the reaction final String type; + /// The emoji code for the reaction + final String? emojiCode; + /// The DateTime on which the reaction is created final DateTime createdAt; + /// The DateTime on which the reaction was last updated + final DateTime updatedAt; + /// The score of the reaction (ie. number of reactions sent) final int score; /// Reaction custom extraData final Map? extraData; const ReactionEntity( - {required this.userId, - required this.messageId, + {this.userId, + this.messageId, required this.type, + this.emojiCode, required this.createdAt, + required this.updatedAt, required this.score, this.extraData}); @override Map toColumns(bool nullToAbsent) { final map = {}; - map['user_id'] = Variable(userId); - map['message_id'] = Variable(messageId); + if (!nullToAbsent || userId != null) { + map['user_id'] = Variable(userId); + } + if (!nullToAbsent || messageId != null) { + map['message_id'] = Variable(messageId); + } map['type'] = Variable(type); + if (!nullToAbsent || emojiCode != null) { + map['emoji_code'] = Variable(emojiCode); + } map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); map['score'] = Variable(score); if (!nullToAbsent || extraData != null) { map['extra_data'] = Variable( @@ -6417,10 +6543,12 @@ class ReactionEntity extends DataClass implements Insertable { {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return ReactionEntity( - userId: serializer.fromJson(json['userId']), - messageId: serializer.fromJson(json['messageId']), + userId: serializer.fromJson(json['userId']), + messageId: serializer.fromJson(json['messageId']), type: serializer.fromJson(json['type']), + emojiCode: serializer.fromJson(json['emojiCode']), createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), score: serializer.fromJson(json['score']), extraData: serializer.fromJson?>(json['extraData']), ); @@ -6429,27 +6557,33 @@ class ReactionEntity extends DataClass implements Insertable { Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'userId': serializer.toJson(userId), - 'messageId': serializer.toJson(messageId), + 'userId': serializer.toJson(userId), + 'messageId': serializer.toJson(messageId), 'type': serializer.toJson(type), + 'emojiCode': serializer.toJson(emojiCode), 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), 'score': serializer.toJson(score), 'extraData': serializer.toJson?>(extraData), }; } ReactionEntity copyWith( - {String? userId, - String? messageId, + {Value userId = const Value.absent(), + Value messageId = const Value.absent(), String? type, + Value emojiCode = const Value.absent(), DateTime? createdAt, + DateTime? updatedAt, int? score, Value?> extraData = const Value.absent()}) => ReactionEntity( - userId: userId ?? this.userId, - messageId: messageId ?? this.messageId, + userId: userId.present ? userId.value : this.userId, + messageId: messageId.present ? messageId.value : this.messageId, type: type ?? this.type, + emojiCode: emojiCode.present ? emojiCode.value : this.emojiCode, createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, score: score ?? this.score, extraData: extraData.present ? extraData.value : this.extraData, ); @@ -6458,7 +6592,9 @@ class ReactionEntity extends DataClass implements Insertable { userId: data.userId.present ? data.userId.value : this.userId, messageId: data.messageId.present ? data.messageId.value : this.messageId, type: data.type.present ? data.type.value : this.type, + emojiCode: data.emojiCode.present ? data.emojiCode.value : this.emojiCode, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, score: data.score.present ? data.score.value : this.score, extraData: data.extraData.present ? data.extraData.value : this.extraData, ); @@ -6470,7 +6606,9 @@ class ReactionEntity extends DataClass implements Insertable { ..write('userId: $userId, ') ..write('messageId: $messageId, ') ..write('type: $type, ') + ..write('emojiCode: $emojiCode, ') ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') ..write('score: $score, ') ..write('extraData: $extraData') ..write(')')) @@ -6478,8 +6616,8 @@ class ReactionEntity extends DataClass implements Insertable { } @override - int get hashCode => - Object.hash(userId, messageId, type, createdAt, score, extraData); + int get hashCode => Object.hash(userId, messageId, type, emojiCode, createdAt, + updatedAt, score, extraData); @override bool operator ==(Object other) => identical(this, other) || @@ -6487,16 +6625,20 @@ class ReactionEntity extends DataClass implements Insertable { other.userId == this.userId && other.messageId == this.messageId && other.type == this.type && + other.emojiCode == this.emojiCode && other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && other.score == this.score && other.extraData == this.extraData); } class ReactionsCompanion extends UpdateCompanion { - final Value userId; - final Value messageId; + final Value userId; + final Value messageId; final Value type; + final Value emojiCode; final Value createdAt; + final Value updatedAt; final Value score; final Value?> extraData; final Value rowid; @@ -6504,27 +6646,31 @@ class ReactionsCompanion extends UpdateCompanion { this.userId = const Value.absent(), this.messageId = const Value.absent(), this.type = const Value.absent(), + this.emojiCode = const Value.absent(), this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.score = const Value.absent(), this.extraData = const Value.absent(), this.rowid = const Value.absent(), }); ReactionsCompanion.insert({ - required String userId, - required String messageId, + this.userId = const Value.absent(), + this.messageId = const Value.absent(), required String type, + this.emojiCode = const Value.absent(), this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), this.score = const Value.absent(), this.extraData = const Value.absent(), this.rowid = const Value.absent(), - }) : userId = Value(userId), - messageId = Value(messageId), - type = Value(type); + }) : type = Value(type); static Insertable custom({ Expression? userId, Expression? messageId, Expression? type, + Expression? emojiCode, Expression? createdAt, + Expression? updatedAt, Expression? score, Expression? extraData, Expression? rowid, @@ -6533,7 +6679,9 @@ class ReactionsCompanion extends UpdateCompanion { if (userId != null) 'user_id': userId, if (messageId != null) 'message_id': messageId, if (type != null) 'type': type, + if (emojiCode != null) 'emoji_code': emojiCode, if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, if (score != null) 'score': score, if (extraData != null) 'extra_data': extraData, if (rowid != null) 'rowid': rowid, @@ -6541,10 +6689,12 @@ class ReactionsCompanion extends UpdateCompanion { } ReactionsCompanion copyWith( - {Value? userId, - Value? messageId, + {Value? userId, + Value? messageId, Value? type, + Value? emojiCode, Value? createdAt, + Value? updatedAt, Value? score, Value?>? extraData, Value? rowid}) { @@ -6552,7 +6702,9 @@ class ReactionsCompanion extends UpdateCompanion { userId: userId ?? this.userId, messageId: messageId ?? this.messageId, type: type ?? this.type, + emojiCode: emojiCode ?? this.emojiCode, createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, score: score ?? this.score, extraData: extraData ?? this.extraData, rowid: rowid ?? this.rowid, @@ -6571,9 +6723,15 @@ class ReactionsCompanion extends UpdateCompanion { if (type.present) { map['type'] = Variable(type.value); } + if (emojiCode.present) { + map['emoji_code'] = Variable(emojiCode.value); + } if (createdAt.present) { map['created_at'] = Variable(createdAt.value); } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } if (score.present) { map['score'] = Variable(score.value); } @@ -6593,7 +6751,9 @@ class ReactionsCompanion extends UpdateCompanion { ..write('userId: $userId, ') ..write('messageId: $messageId, ') ..write('type: $type, ') + ..write('emojiCode: $emojiCode, ') ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') ..write('score: $score, ') ..write('extraData: $extraData, ') ..write('rowid: $rowid') @@ -12876,20 +13036,24 @@ typedef $$PollVotesTableProcessedTableManager = ProcessedTableManager< PrefetchHooks Function({bool pollId})>; typedef $$PinnedMessageReactionsTableCreateCompanionBuilder = PinnedMessageReactionsCompanion Function({ - required String userId, - required String messageId, + Value userId, + Value messageId, required String type, + Value emojiCode, Value createdAt, + Value updatedAt, Value score, Value?> extraData, Value rowid, }); typedef $$PinnedMessageReactionsTableUpdateCompanionBuilder = PinnedMessageReactionsCompanion Function({ - Value userId, - Value messageId, + Value userId, + Value messageId, Value type, + Value emojiCode, Value createdAt, + Value updatedAt, Value score, Value?> extraData, Value rowid, @@ -12906,9 +13070,9 @@ final class $$PinnedMessageReactionsTableReferences extends BaseReferences< db.pinnedMessages.createAlias($_aliasNameGenerator( db.pinnedMessageReactions.messageId, db.pinnedMessages.id)); - $$PinnedMessagesTableProcessedTableManager get messageId { - final $_column = $_itemColumn('message_id')!; - + $$PinnedMessagesTableProcessedTableManager? get messageId { + final $_column = $_itemColumn('message_id'); + if ($_column == null) return null; final manager = $$PinnedMessagesTableTableManager($_db, $_db.pinnedMessages) .filter((f) => f.id.sqlEquals($_column)); final item = $_typedResult.readTableOrNull(_messageIdTable($_db)); @@ -12933,9 +13097,15 @@ class $$PinnedMessageReactionsTableFilterComposer ColumnFilters get type => $composableBuilder( column: $table.type, builder: (column) => ColumnFilters(column)); + ColumnFilters get emojiCode => $composableBuilder( + column: $table.emojiCode, builder: (column) => ColumnFilters(column)); + ColumnFilters get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get score => $composableBuilder( column: $table.score, builder: (column) => ColumnFilters(column)); @@ -12981,9 +13151,15 @@ class $$PinnedMessageReactionsTableOrderingComposer ColumnOrderings get type => $composableBuilder( column: $table.type, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get emojiCode => $composableBuilder( + column: $table.emojiCode, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get score => $composableBuilder( column: $table.score, builder: (column) => ColumnOrderings(column)); @@ -13026,9 +13202,15 @@ class $$PinnedMessageReactionsTableAnnotationComposer GeneratedColumn get type => $composableBuilder(column: $table.type, builder: (column) => column); + GeneratedColumn get emojiCode => + $composableBuilder(column: $table.emojiCode, builder: (column) => column); + GeneratedColumn get createdAt => $composableBuilder(column: $table.createdAt, builder: (column) => column); + GeneratedColumn get updatedAt => + $composableBuilder(column: $table.updatedAt, builder: (column) => column); + GeneratedColumn get score => $composableBuilder(column: $table.score, builder: (column) => column); @@ -13084,10 +13266,12 @@ class $$PinnedMessageReactionsTableTableManager extends RootTableManager< $$PinnedMessageReactionsTableAnnotationComposer( $db: db, $table: table), updateCompanionCallback: ({ - Value userId = const Value.absent(), - Value messageId = const Value.absent(), + Value userId = const Value.absent(), + Value messageId = const Value.absent(), Value type = const Value.absent(), + Value emojiCode = const Value.absent(), Value createdAt = const Value.absent(), + Value updatedAt = const Value.absent(), Value score = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), @@ -13096,16 +13280,20 @@ class $$PinnedMessageReactionsTableTableManager extends RootTableManager< userId: userId, messageId: messageId, type: type, + emojiCode: emojiCode, createdAt: createdAt, + updatedAt: updatedAt, score: score, extraData: extraData, rowid: rowid, ), createCompanionCallback: ({ - required String userId, - required String messageId, + Value userId = const Value.absent(), + Value messageId = const Value.absent(), required String type, + Value emojiCode = const Value.absent(), Value createdAt = const Value.absent(), + Value updatedAt = const Value.absent(), Value score = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), @@ -13114,7 +13302,9 @@ class $$PinnedMessageReactionsTableTableManager extends RootTableManager< userId: userId, messageId: messageId, type: type, + emojiCode: emojiCode, createdAt: createdAt, + updatedAt: updatedAt, score: score, extraData: extraData, rowid: rowid, @@ -13178,19 +13368,23 @@ typedef $$PinnedMessageReactionsTableProcessedTableManager PinnedMessageReactionEntity, PrefetchHooks Function({bool messageId})>; typedef $$ReactionsTableCreateCompanionBuilder = ReactionsCompanion Function({ - required String userId, - required String messageId, + Value userId, + Value messageId, required String type, + Value emojiCode, Value createdAt, + Value updatedAt, Value score, Value?> extraData, Value rowid, }); typedef $$ReactionsTableUpdateCompanionBuilder = ReactionsCompanion Function({ - Value userId, - Value messageId, + Value userId, + Value messageId, Value type, + Value emojiCode, Value createdAt, + Value updatedAt, Value score, Value?> extraData, Value rowid, @@ -13204,9 +13398,9 @@ final class $$ReactionsTableReferences extends BaseReferences< db.messages.createAlias( $_aliasNameGenerator(db.reactions.messageId, db.messages.id)); - $$MessagesTableProcessedTableManager get messageId { - final $_column = $_itemColumn('message_id')!; - + $$MessagesTableProcessedTableManager? get messageId { + final $_column = $_itemColumn('message_id'); + if ($_column == null) return null; final manager = $$MessagesTableTableManager($_db, $_db.messages) .filter((f) => f.id.sqlEquals($_column)); final item = $_typedResult.readTableOrNull(_messageIdTable($_db)); @@ -13231,9 +13425,15 @@ class $$ReactionsTableFilterComposer ColumnFilters get type => $composableBuilder( column: $table.type, builder: (column) => ColumnFilters(column)); + ColumnFilters get emojiCode => $composableBuilder( + column: $table.emojiCode, builder: (column) => ColumnFilters(column)); + ColumnFilters get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get score => $composableBuilder( column: $table.score, builder: (column) => ColumnFilters(column)); @@ -13279,9 +13479,15 @@ class $$ReactionsTableOrderingComposer ColumnOrderings get type => $composableBuilder( column: $table.type, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get emojiCode => $composableBuilder( + column: $table.emojiCode, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get score => $composableBuilder( column: $table.score, builder: (column) => ColumnOrderings(column)); @@ -13324,9 +13530,15 @@ class $$ReactionsTableAnnotationComposer GeneratedColumn get type => $composableBuilder(column: $table.type, builder: (column) => column); + GeneratedColumn get emojiCode => + $composableBuilder(column: $table.emojiCode, builder: (column) => column); + GeneratedColumn get createdAt => $composableBuilder(column: $table.createdAt, builder: (column) => column); + GeneratedColumn get updatedAt => + $composableBuilder(column: $table.updatedAt, builder: (column) => column); + GeneratedColumn get score => $composableBuilder(column: $table.score, builder: (column) => column); @@ -13378,10 +13590,12 @@ class $$ReactionsTableTableManager extends RootTableManager< createComputedFieldComposer: () => $$ReactionsTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ - Value userId = const Value.absent(), - Value messageId = const Value.absent(), + Value userId = const Value.absent(), + Value messageId = const Value.absent(), Value type = const Value.absent(), + Value emojiCode = const Value.absent(), Value createdAt = const Value.absent(), + Value updatedAt = const Value.absent(), Value score = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), @@ -13390,16 +13604,20 @@ class $$ReactionsTableTableManager extends RootTableManager< userId: userId, messageId: messageId, type: type, + emojiCode: emojiCode, createdAt: createdAt, + updatedAt: updatedAt, score: score, extraData: extraData, rowid: rowid, ), createCompanionCallback: ({ - required String userId, - required String messageId, + Value userId = const Value.absent(), + Value messageId = const Value.absent(), required String type, + Value emojiCode = const Value.absent(), Value createdAt = const Value.absent(), + Value updatedAt = const Value.absent(), Value score = const Value.absent(), Value?> extraData = const Value.absent(), Value rowid = const Value.absent(), @@ -13408,7 +13626,9 @@ class $$ReactionsTableTableManager extends RootTableManager< userId: userId, messageId: messageId, type: type, + emojiCode: emojiCode, createdAt: createdAt, + updatedAt: updatedAt, score: score, extraData: extraData, rowid: rowid, diff --git a/packages/stream_chat_persistence/lib/src/entity/pinned_message_reactions.dart b/packages/stream_chat_persistence/lib/src/entity/pinned_message_reactions.dart index e4c9b06e58..6e490cf8fc 100644 --- a/packages/stream_chat_persistence/lib/src/entity/pinned_message_reactions.dart +++ b/packages/stream_chat_persistence/lib/src/entity/pinned_message_reactions.dart @@ -8,6 +8,7 @@ import 'package:stream_chat_persistence/src/entity/reactions.dart'; class PinnedMessageReactions extends Reactions { /// The messageId to which the reaction belongs @override - TextColumn get messageId => - text().references(PinnedMessages, #id, onDelete: KeyAction.cascade)(); + TextColumn get messageId => text() + .nullable() + .references(PinnedMessages, #id, onDelete: KeyAction.cascade)(); } diff --git a/packages/stream_chat_persistence/lib/src/entity/reactions.dart b/packages/stream_chat_persistence/lib/src/entity/reactions.dart index 39bf42589f..64d23bf979 100644 --- a/packages/stream_chat_persistence/lib/src/entity/reactions.dart +++ b/packages/stream_chat_persistence/lib/src/entity/reactions.dart @@ -7,18 +7,25 @@ import 'package:stream_chat_persistence/src/entity/messages.dart'; @DataClassName('ReactionEntity') class Reactions extends Table { /// The id of the user that sent the reaction - TextColumn get userId => text()(); + TextColumn get userId => text().nullable()(); /// The messageId to which the reaction belongs - TextColumn get messageId => - text().references(Messages, #id, onDelete: KeyAction.cascade)(); + TextColumn get messageId => text() + .nullable() + .references(Messages, #id, onDelete: KeyAction.cascade)(); /// The type of the reaction TextColumn get type => text()(); + /// The emoji code for the reaction + TextColumn get emojiCode => text().nullable()(); + /// The DateTime on which the reaction is created DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); + /// The DateTime on which the reaction was last updated + DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)(); + /// The score of the reaction (ie. number of reactions sent) IntColumn get score => integer().withDefault(const Constant(0))(); diff --git a/packages/stream_chat_persistence/lib/src/mapper/pinned_message_reaction_mapper.dart b/packages/stream_chat_persistence/lib/src/mapper/pinned_message_reaction_mapper.dart index ecab7cb40e..00deda65d2 100644 --- a/packages/stream_chat_persistence/lib/src/mapper/pinned_message_reaction_mapper.dart +++ b/packages/stream_chat_persistence/lib/src/mapper/pinned_message_reaction_mapper.dart @@ -5,13 +5,15 @@ import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; extension PinnedMessageReactionEntityX on PinnedMessageReactionEntity { /// Maps a [PinnedMessageReactionEntity] into [Reaction] Reaction toReaction({User? user}) => Reaction( - extraData: extraData ?? {}, type: type, - createdAt: createdAt, userId: userId, user: user, messageId: messageId, score: score, + emojiCode: emojiCode, + createdAt: createdAt, + updatedAt: updatedAt, + extraData: extraData ?? {}, ); } @@ -19,11 +21,13 @@ extension PinnedMessageReactionEntityX on PinnedMessageReactionEntity { extension PReactionX on Reaction { /// Maps a [Reaction] into [ReactionEntity] PinnedMessageReactionEntity toPinnedEntity() => PinnedMessageReactionEntity( - extraData: extraData, type: type, - createdAt: createdAt, - userId: userId!, - messageId: messageId!, + userId: userId ?? user?.id, + messageId: messageId, score: score, + emojiCode: emojiCode, + createdAt: createdAt, + updatedAt: updatedAt, + extraData: extraData, ); } diff --git a/packages/stream_chat_persistence/lib/src/mapper/reaction_mapper.dart b/packages/stream_chat_persistence/lib/src/mapper/reaction_mapper.dart index a524fafe1c..81b2bd4419 100644 --- a/packages/stream_chat_persistence/lib/src/mapper/reaction_mapper.dart +++ b/packages/stream_chat_persistence/lib/src/mapper/reaction_mapper.dart @@ -5,13 +5,15 @@ import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; extension ReactionEntityX on ReactionEntity { /// Maps a [ReactionEntity] into [Reaction] Reaction toReaction({User? user}) => Reaction( - extraData: extraData ?? {}, type: type, - createdAt: createdAt, userId: userId, user: user, messageId: messageId, score: score, + emojiCode: emojiCode, + createdAt: createdAt, + updatedAt: updatedAt, + extraData: extraData ?? {}, ); } @@ -19,11 +21,13 @@ extension ReactionEntityX on ReactionEntity { extension ReactionX on Reaction { /// Maps a [Reaction] into [ReactionEntity] ReactionEntity toEntity() => ReactionEntity( - extraData: extraData, type: type, - createdAt: createdAt, - userId: userId!, - messageId: messageId!, + userId: userId ?? user?.id, + messageId: messageId, score: score, + emojiCode: emojiCode, + createdAt: createdAt, + updatedAt: updatedAt, + extraData: extraData, ); } diff --git a/packages/stream_chat_persistence/test/src/dao/pinned_message_reaction_dao_test.dart b/packages/stream_chat_persistence/test/src/dao/pinned_message_reaction_dao_test.dart index 44abc4a644..57482c4317 100644 --- a/packages/stream_chat_persistence/test/src/dao/pinned_message_reaction_dao_test.dart +++ b/packages/stream_chat_persistence/test/src/dao/pinned_message_reaction_dao_test.dart @@ -6,6 +6,7 @@ import 'package:stream_chat_persistence/src/dao/pinned_message_reaction_dao.dart import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; import '../../stream_chat_persistence_client_test.dart'; +import '../utils/date_matcher.dart'; void main() { late PinnedMessageReactionDao pinnedMessageReactionDao; @@ -39,16 +40,23 @@ void main() { pinnedAt: DateTime.now(), pinnedBy: users.first, ); + + final now = DateTime.now(); final reactions = List.generate( count, - (index) => Reaction( - type: 'testType$index', - createdAt: DateTime.now(), - userId: userId ?? users[index].id, - messageId: message.id, - score: count + 3, - extraData: {'extra_test_field': 'extraTestData'}, - ), + (index) { + final createdAt = now.add(Duration(minutes: index)); + return Reaction( + type: 'testType$index', + createdAt: createdAt, + updatedAt: createdAt.add(const Duration(minutes: 5)), + userId: userId ?? users[index].id, + messageId: message.id, + score: count + 3, + emojiCode: '😂$index', + extraData: const {'extra_test_field': 'extraTestData'}, + ); + }, ); await database.userDao.updateUsers(users); @@ -76,6 +84,14 @@ void main() { await pinnedMessageReactionDao.getReactions(messageId); expect(fetchedReactions.length, insertedReactions.length); expect(fetchedReactions.every((it) => it.messageId == messageId), true); + + // Verify score and emojiCode are preserved + for (var i = 0; i < fetchedReactions.length; i++) { + final inserted = insertedReactions[i]; + final fetched = fetchedReactions[i]; + expect(fetched.score, inserted.score); + expect(fetched.emojiCode, inserted.emojiCode); + } }); test('getReactionsByUserId', () async { @@ -100,6 +116,14 @@ void main() { expect(fetchedReactions.length, insertedReactions.length); expect(fetchedReactions.every((it) => it.messageId == messageId), true); expect(fetchedReactions.every((it) => it.userId == userId), true); + + // Verify score and emojiCode are preserved + for (var i = 0; i < fetchedReactions.length; i++) { + final inserted = insertedReactions[i]; + final fetched = fetchedReactions[i]; + expect(fetched.score, inserted.score); + expect(fetched.emojiCode, inserted.emojiCode); + } }); test('updateReactions', () async { @@ -109,37 +133,46 @@ void main() { final reactions = await _prepareReactionData(messageId); // Modifying one of the reaction and also adding one new - final copyReaction = reactions.first.copyWith(score: 33); + final now = DateTime.now(); + final copyReaction = reactions.first.copyWith( + score: 33, + emojiCode: '🎉', + updatedAt: now, + ); final newReaction = Reaction( type: 'testType3', - createdAt: DateTime.now(), + createdAt: now, + updatedAt: now.add(const Duration(minutes: 5)), userId: 'testUserId3', messageId: messageId, score: 30, - extraData: {'extra_test_field': 'extraTestData'}, + emojiCode: '🎈', + extraData: const {'extra_test_field': 'extraTestData'}, ); await pinnedMessageReactionDao.updateReactions([copyReaction, newReaction]); // Fetched reaction length should be one more than inserted reactions. - // copyReaction `score` modified field should be 33. + // copyReaction modified fields should match // Fetched reactions should contain the newReaction. final fetchedReactions = await pinnedMessageReactionDao.getReactions(messageId); expect(fetchedReactions.length, reactions.length + 1); - expect( - fetchedReactions - .firstWhere((it) => - it.userId == copyReaction.userId && it.type == copyReaction.type) - .score, - 33, + + final fetchedCopyReaction = fetchedReactions.firstWhere( + (it) => it.userId == copyReaction.userId && it.type == copyReaction.type, ); + expect(fetchedCopyReaction.score, 33); + expect(fetchedCopyReaction.emojiCode, '🎉'); + expect(fetchedCopyReaction.updatedAt, isSameDateAs(now)); + + final fetchedNewReaction = fetchedReactions.firstWhere( + (it) => it.userId == newReaction.userId && it.type == newReaction.type, + ); + expect(fetchedNewReaction.emojiCode, '🎈'); expect( - fetchedReactions - .where((it) => - it.userId == newReaction.userId && it.type == newReaction.type) - .isNotEmpty, - true, + fetchedNewReaction.updatedAt, + isSameDateAs(now.add(const Duration(minutes: 5))), ); }); @@ -171,7 +204,8 @@ void main() { expect(fetchedReactions1, isEmpty); expect(fetchedReactions2, isNotEmpty); }); - test('should delete all the messages of both message', () async { + + test('should delete all the reactions of both message', () async { // Preparing test data final insertedReactions1 = await _prepareReactionData(messageId1); final insertedReactions2 = await _prepareReactionData(messageId2); diff --git a/packages/stream_chat_persistence/test/src/dao/reaction_dao_test.dart b/packages/stream_chat_persistence/test/src/dao/reaction_dao_test.dart index 7fa3569e4e..ddd01f09ff 100644 --- a/packages/stream_chat_persistence/test/src/dao/reaction_dao_test.dart +++ b/packages/stream_chat_persistence/test/src/dao/reaction_dao_test.dart @@ -6,6 +6,7 @@ import 'package:stream_chat_persistence/src/dao/reaction_dao.dart'; import 'package:stream_chat_persistence/src/db/drift_chat_database.dart'; import '../../stream_chat_persistence_client_test.dart'; +import '../utils/date_matcher.dart'; void main() { late ReactionDao reactionDao; @@ -39,16 +40,23 @@ void main() { pinnedAt: DateTime.now(), pinnedBy: users.first, ); + + final now = DateTime.now(); final reactions = List.generate( count, - (index) => Reaction( - type: 'testType$index', - createdAt: DateTime.now(), - userId: userId ?? users[index].id, - messageId: message.id, - score: count + 3, - extraData: {'extra_test_field': 'extraTestData'}, - ), + (index) { + final createdAt = now.add(Duration(minutes: index)); + return Reaction( + type: 'testType$index', + createdAt: createdAt, + updatedAt: createdAt.add(const Duration(minutes: 5)), + userId: userId ?? users[index].id, + messageId: message.id, + score: count + 3, + emojiCode: '😂$index', + extraData: const {'extra_test_field': 'extraTestData'}, + ); + }, ); await database.userDao.updateUsers(users); @@ -75,6 +83,14 @@ void main() { final fetchedReactions = await reactionDao.getReactions(messageId); expect(fetchedReactions.length, insertedReactions.length); expect(fetchedReactions.every((it) => it.messageId == messageId), true); + + // Verify score and emojiCode are preserved + for (var i = 0; i < fetchedReactions.length; i++) { + final inserted = insertedReactions[i]; + final fetched = fetchedReactions[i]; + expect(fetched.score, inserted.score); + expect(fetched.emojiCode, inserted.emojiCode); + } }); test('getReactionsByUserId', () async { @@ -98,6 +114,14 @@ void main() { expect(fetchedReactions.length, insertedReactions.length); expect(fetchedReactions.every((it) => it.messageId == messageId), true); expect(fetchedReactions.every((it) => it.userId == userId), true); + + // Verify score and emojiCode are preserved + for (var i = 0; i < fetchedReactions.length; i++) { + final inserted = insertedReactions[i]; + final fetched = fetchedReactions[i]; + expect(fetched.score, inserted.score); + expect(fetched.emojiCode, inserted.emojiCode); + } }); test('updateReactions', () async { @@ -107,36 +131,45 @@ void main() { final reactions = await _prepareReactionData(messageId); // Modifying one of the reaction and also adding one new - final copyReaction = reactions.first.copyWith(score: 33); + final now = DateTime.now(); + final copyReaction = reactions.first.copyWith( + score: 33, + emojiCode: '🎉', + updatedAt: now, + ); final newReaction = Reaction( type: 'testType3', - createdAt: DateTime.now(), + createdAt: now, + updatedAt: now.add(const Duration(minutes: 5)), userId: 'testUserId3', messageId: messageId, score: 30, - extraData: {'extra_test_field': 'extraTestData'}, + emojiCode: '🎈', + extraData: const {'extra_test_field': 'extraTestData'}, ); await reactionDao.updateReactions([copyReaction, newReaction]); // Fetched reaction length should be one more than inserted reactions. - // copyReaction `score` modified field should be 33. + // copyReaction modified fields should match // Fetched reactions should contain the newReaction. final fetchedReactions = await reactionDao.getReactions(messageId); expect(fetchedReactions.length, reactions.length + 1); - expect( - fetchedReactions - .firstWhere((it) => - it.userId == copyReaction.userId && it.type == copyReaction.type) - .score, - 33, + + final fetchedCopyReaction = fetchedReactions.firstWhere( + (it) => it.userId == copyReaction.userId && it.type == copyReaction.type, ); + expect(fetchedCopyReaction.score, 33); + expect(fetchedCopyReaction.emojiCode, '🎉'); + expect(fetchedCopyReaction.updatedAt, isSameDateAs(now)); + + final fetchedNewReaction = fetchedReactions.firstWhere( + (it) => it.userId == newReaction.userId && it.type == newReaction.type, + ); + expect(fetchedNewReaction.emojiCode, '🎈'); expect( - fetchedReactions - .where((it) => - it.userId == newReaction.userId && it.type == newReaction.type) - .isNotEmpty, - true, + fetchedNewReaction.updatedAt, + isSameDateAs(now.add(const Duration(minutes: 5))), ); }); @@ -164,6 +197,7 @@ void main() { expect(fetchedReactions1, isEmpty); expect(fetchedReactions2, isNotEmpty); }); + test('should delete all the reactions of both message', () async { // Preparing test data final insertedReactions1 = await _prepareReactionData(messageId1); diff --git a/packages/stream_chat_persistence/test/src/mapper/pinned_message_reaction_mapper_test.dart b/packages/stream_chat_persistence/test/src/mapper/pinned_message_reaction_mapper_test.dart index 2753f4f4ce..d2b4a67094 100644 --- a/packages/stream_chat_persistence/test/src/mapper/pinned_message_reaction_mapper_test.dart +++ b/packages/stream_chat_persistence/test/src/mapper/pinned_message_reaction_mapper_test.dart @@ -9,12 +9,15 @@ void main() { test('toReaction should map the entity into Reaction', () { final user = User(id: 'testUserId'); final message = Message(id: 'testMessageId'); + final now = DateTime.now(); final entity = PinnedMessageReactionEntity( userId: user.id, messageId: message.id, type: 'haha', score: 33, - createdAt: DateTime.now(), + emojiCode: '😂', + createdAt: now, + updatedAt: now.add(const Duration(minutes: 5)), extraData: {'extra_test_data': 'extraData'}, ); @@ -24,20 +27,25 @@ void main() { expect(reaction.messageId, entity.messageId); expect(reaction.type, entity.type); expect(reaction.score, entity.score); + expect(reaction.emojiCode, entity.emojiCode); expect(reaction.createdAt, isSameDateAs(entity.createdAt)); + expect(reaction.updatedAt, isSameDateAs(entity.updatedAt)); expect(reaction.extraData, entity.extraData); }); test('toEntity should map reaction into PinnedMessageReactionEntity', () { final user = User(id: 'testUserId'); final message = Message(id: 'testMessageId'); + final now = DateTime.now(); final reaction = Reaction( userId: user.id, messageId: message.id, type: 'haha', score: 33, - createdAt: DateTime.now(), - extraData: {'extra_test_data': 'extraData'}, + emojiCode: '😂', + createdAt: now, + updatedAt: now.add(const Duration(minutes: 5)), + extraData: const {'extra_test_data': 'extraData'}, ); final entity = reaction.toPinnedEntity(); @@ -46,7 +54,9 @@ void main() { expect(entity.messageId, reaction.messageId); expect(entity.type, reaction.type); expect(entity.score, reaction.score); + expect(entity.emojiCode, reaction.emojiCode); expect(entity.createdAt, isSameDateAs(reaction.createdAt)); + expect(entity.updatedAt, isSameDateAs(reaction.updatedAt)); expect(entity.extraData, reaction.extraData); }); } diff --git a/packages/stream_chat_persistence/test/src/mapper/reaction_mapper_test.dart b/packages/stream_chat_persistence/test/src/mapper/reaction_mapper_test.dart index 844eb3b86b..43a3b93cfb 100644 --- a/packages/stream_chat_persistence/test/src/mapper/reaction_mapper_test.dart +++ b/packages/stream_chat_persistence/test/src/mapper/reaction_mapper_test.dart @@ -9,12 +9,15 @@ void main() { test('toReaction should map the entity into Reaction', () { final user = User(id: 'testUserId'); final message = Message(id: 'testMessageId'); + final now = DateTime.now(); final entity = ReactionEntity( userId: user.id, messageId: message.id, type: 'haha', score: 33, - createdAt: DateTime.now(), + emojiCode: '😂', + createdAt: now, + updatedAt: now.add(const Duration(minutes: 5)), extraData: {'extra_test_data': 'extraData'}, ); @@ -24,20 +27,25 @@ void main() { expect(reaction.messageId, entity.messageId); expect(reaction.type, entity.type); expect(reaction.score, entity.score); + expect(reaction.emojiCode, entity.emojiCode); expect(reaction.createdAt, isSameDateAs(entity.createdAt)); + expect(reaction.updatedAt, isSameDateAs(entity.updatedAt)); expect(reaction.extraData, entity.extraData); }); test('toEntity should map reaction into ReactionEntity', () { final user = User(id: 'testUserId'); final message = Message(id: 'testMessageId'); + final now = DateTime.now(); final reaction = Reaction( userId: user.id, messageId: message.id, type: 'haha', score: 33, - createdAt: DateTime.now(), - extraData: {'extra_test_data': 'extraData'}, + emojiCode: '😂', + createdAt: now, + updatedAt: now.add(const Duration(minutes: 5)), + extraData: const {'extra_test_data': 'extraData'}, ); final entity = reaction.toEntity(); @@ -46,7 +54,9 @@ void main() { expect(entity.messageId, reaction.messageId); expect(entity.type, reaction.type); expect(entity.score, reaction.score); + expect(entity.emojiCode, reaction.emojiCode); expect(entity.createdAt, isSameDateAs(reaction.createdAt)); + expect(entity.updatedAt, isSameDateAs(reaction.updatedAt)); expect(entity.extraData, reaction.extraData); }); } From bf33673c13902c26f1de61299026401c14a0a1d3 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 25 Jul 2025 12:25:34 +0200 Subject: [PATCH 22/34] feat(ui): add `StreamChatConfiguration.maybeOf()` method This method allows for safe access to the `StreamChatConfigurationData` from a `BuildContext`, returning null if no ancestor `StreamChatConfiguration` is found. This is useful for async operations where the context might not be guaranteed to have a `StreamChatConfiguration` above it. The `StreamChatConfiguration.of()` method has been updated to use `maybeOf()` internally and now provides more detailed error messages if a `StreamChatConfiguration` is not found. --- packages/stream_chat_flutter/CHANGELOG.md | 1 + .../lib/src/stream_chat_configuration.dart | 69 ++++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 548b912260..a8d8635247 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -4,6 +4,7 @@ - Added `emojiCode` property to `StreamReactionIcon` to support custom emojis in reactions. - Updated default reaction builders with standard emoji codes. (`❤️`, `👍`, `👎`, `😂`, `😮`) +- Added `StreamChatConfiguration.maybeOf()` method for safe context access in async operations. ## Upcoming diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart index d680344059..64a482d4e8 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart @@ -21,18 +21,69 @@ class StreamChatConfiguration extends InheritedWidget { bool updateShouldNotify(StreamChatConfiguration oldWidget) => data != oldWidget.data; - /// Use this method to get the current [StreamChatThemeData] instance + /// Finds the [StreamChatConfigurationData] from the closest + /// [StreamChatConfiguration] ancestor that encloses the given context. + /// + /// This will throw a [FlutterError] if no [StreamChatConfiguration] is found + /// in the widget tree above the given context. + /// + /// Typical usage: + /// + /// ```dart + /// final config = StreamChatConfiguration.of(context); + /// ``` + /// + /// If you're calling this in the same `build()` method that creates the + /// `StreamChatConfiguration`, consider using a `Builder` or refactoring into + /// a separate widget to obtain a context below the [StreamChatConfiguration]. + /// + /// If you want to return null instead of throwing, use [maybeOf]. static StreamChatConfigurationData of(BuildContext context) { - final streamChatConfiguration = - context.dependOnInheritedWidgetOfExactType(); + final result = maybeOf(context); + if (result != null) return result; - assert( - streamChatConfiguration != null, - ''' -You must have a StreamChatConfigurationProvider widget at the top of your widget tree''', - ); + throw FlutterError.fromParts([ + ErrorSummary( + 'StreamChatConfiguration.of() called with a context that does not ' + 'contain a StreamChatConfiguration.', + ), + ErrorDescription( + 'No StreamChatConfiguration ancestor could be found starting from the ' + 'context that was passed to StreamChatConfiguration.of(). This usually ' + 'happens when the context used comes from the widget that creates the ' + 'StreamChatConfiguration itself.', + ), + ErrorHint( + 'To fix this, ensure that you are using a context that is a descendant ' + 'of the StreamChatConfiguration. You can use a Builder to get a new ' + 'context that is under the StreamChatConfiguration:\n\n' + ' Builder(\n' + ' builder: (context) {\n' + ' final config = StreamChatConfiguration.of(context);\n' + ' ...\n' + ' },\n' + ' )', + ), + ErrorHint( + 'Alternatively, split your build method into smaller widgets so that ' + 'you get a new BuildContext that is below the StreamChatConfiguration ' + 'in the widget tree.', + ), + context.describeElement('The context used was'), + ]); + } - return streamChatConfiguration!.data; + /// Finds the [StreamChatConfigurationData] from the closest + /// [StreamChatConfiguration] ancestor that encloses the given context. + /// + /// Returns null if no such ancestor exists. + /// + /// See also: + /// * [of], which throws if no [StreamChatConfiguration] is found. + static StreamChatConfigurationData? maybeOf(BuildContext context) { + final streamChatConfiguration = + context.dependOnInheritedWidgetOfExactType(); + return streamChatConfiguration?.data; } } From 0a6b93258f0c73ac9c0ff206e749c7ba3e953f99 Mon Sep 17 00:00:00 2001 From: xsahil03x <25670178+xsahil03x@users.noreply.github.com> Date: Fri, 25 Jul 2025 11:54:35 +0000 Subject: [PATCH 23/34] chore: Update Goldens --- .../ci/channel_header_bottom_widget.png | Bin 1555 -> 1567 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.png b/packages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.png index 6c3aa5467e90155679e2984ba329437ee24a6d66..4c1c782fa9011fcb9b641bcdaf14981c79e82daf 100644 GIT binary patch delta 1476 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 From d1819c12db98490bfd03aa1f4ce31b81e69bb158 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 25 Jul 2025 14:14:18 +0200 Subject: [PATCH 24/34] chore(repo): release v10.0.0-beta.4 (#2333) --- melos.yaml | 10 +++++----- packages/stream_chat/CHANGELOG.md | 16 +++++++++------- packages/stream_chat/example/pubspec.yaml | 2 +- packages/stream_chat/lib/version.dart | 2 +- packages/stream_chat/pubspec.yaml | 2 +- packages/stream_chat_flutter/CHANGELOG.md | 4 +++- .../stream_chat_flutter/example/pubspec.yaml | 6 +++--- packages/stream_chat_flutter/pubspec.yaml | 4 ++-- packages/stream_chat_flutter_core/CHANGELOG.md | 4 ++++ .../example/pubspec.yaml | 2 +- packages/stream_chat_flutter_core/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/CHANGELOG.md | 4 +++- .../example/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/CHANGELOG.md | 4 +++- .../stream_chat_persistence/example/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/pubspec.yaml | 4 ++-- sample_app/pubspec.yaml | 6 +++--- 18 files changed, 49 insertions(+), 37 deletions(-) diff --git a/melos.yaml b/melos.yaml index 22db60394e..2a7740dbb6 100644 --- a/melos.yaml +++ b/melos.yaml @@ -85,11 +85,11 @@ command: share_plus: ^11.0.0 shimmer: ^3.0.0 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.3 - stream_chat_flutter: ^10.0.0-beta.3 - stream_chat_flutter_core: ^10.0.0-beta.3 - stream_chat_localizations: ^10.0.0-beta.3 - stream_chat_persistence: ^10.0.0-beta.3 + stream_chat: ^10.0.0-beta.4 + stream_chat_flutter: ^10.0.0-beta.4 + stream_chat_flutter_core: ^10.0.0-beta.4 + stream_chat_localizations: ^10.0.0-beta.4 + stream_chat_persistence: ^10.0.0-beta.4 streaming_shared_preferences: ^2.0.0 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index f7b76cd10d..ee4b1e1ceb 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.4 🛑️ Breaking @@ -9,11 +9,13 @@ ✅ Added - Added comprehensive location sharing support with static and live location features: - - `Channel.sendStaticLocation()` - Send a static location message to the channel - - `Channel.startLiveLocationSharing()` - Start sharing live location with automatic updates - - `Channel.activeLiveLocations` - Track members active live location shares in the channel - - `Client.activeLiveLocations` - Access current user active live location shares across channels - - Location event listeners for `locationShared`, `locationUpdated`, and `locationExpired` events + - `Channel.sendStaticLocation()` - Send a static location message to the channel + - `Channel.startLiveLocationSharing()` - Start sharing live location with automatic updates + - `Channel.activeLiveLocations` - Track members active live location shares in the channel + - `Client.activeLiveLocations` - Access current user active live location shares across channels + - Location event listeners for `locationShared`, `locationUpdated`, and `locationExpired` events + +- Included the changes from version [`9.15.0`](https://pub.dev/packages/stream_chat/changelog). ## 9.15.0 @@ -39,7 +41,7 @@ - **Removed Properties**: `reactionCounts` and `reactionScores` getters from `Message` (use `reactionGroups` instead), `call` property from `StreamChatApi` - **Removed Files**: `permission_type.dart`, `call_api.dart`, `call_payload.dart` and their associated tests -- Included the changes from version [`9.13.0`](https://pub.dev/packages/stream_chat/changelog). +- Included the changes from version [`9.14.0`](https://pub.dev/packages/stream_chat/changelog). ## 9.14.0 diff --git a/packages/stream_chat/example/pubspec.yaml b/packages/stream_chat/example/pubspec.yaml index 6a8d248238..12656250cd 100644 --- a/packages/stream_chat/example/pubspec.yaml +++ b/packages/stream_chat/example/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.3 + stream_chat: ^10.0.0-beta.4 flutter: uses-material-design: true diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index fe07491c67..875d1b58ae 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -9,4 +9,4 @@ /// Current package version /// Used in [SystemEnvironmentManager] to build the `x-stream-client` header -const PACKAGE_VERSION = '10.0.0-beta.3'; +const PACKAGE_VERSION = '10.0.0-beta.4'; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index 3d38890367..e984cf3c77 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat homepage: https://getstream.io/ description: The official Dart client for Stream Chat, a service for building chat applications. -version: 10.0.0-beta.3 +version: 10.0.0-beta.4 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index c56113dd9e..7ca1429c64 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,4 +1,4 @@ -## Upcoming Beta +## 10.0.0-beta.4 ✅ Added @@ -6,6 +6,8 @@ - Updated default reaction builders with standard emoji codes. (`❤️`, `👍`, `👎`, `😂`, `😮`) - Added `StreamChatConfiguration.maybeOf()` method for safe context access in async operations. +- Included the changes from version [`9.15.0`](https://pub.dev/packages/stream_chat_flutter/changelog). + ## 9.15.0 ✅ Added diff --git a/packages/stream_chat_flutter/example/pubspec.yaml b/packages/stream_chat_flutter/example/pubspec.yaml index 470b719249..0be2b29afe 100644 --- a/packages/stream_chat_flutter/example/pubspec.yaml +++ b/packages/stream_chat_flutter/example/pubspec.yaml @@ -25,9 +25,9 @@ dependencies: flutter: sdk: flutter responsive_builder: ^0.7.0 - stream_chat_flutter: ^10.0.0-beta.3 - stream_chat_localizations: ^10.0.0-beta.3 - stream_chat_persistence: ^10.0.0-beta.3 + stream_chat_flutter: ^10.0.0-beta.4 + stream_chat_localizations: ^10.0.0-beta.4 + stream_chat_persistence: ^10.0.0-beta.4 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index ec6309a9f0..05111710ae 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.3 +version: 10.0.0-beta.4 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -56,7 +56,7 @@ dependencies: rxdart: ^0.28.0 share_plus: ^11.0.0 shimmer: ^3.0.0 - stream_chat_flutter_core: ^10.0.0-beta.3 + stream_chat_flutter_core: ^10.0.0-beta.4 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 thumblr: ^0.0.4 diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 9123285901..7b74002e67 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.4 + +- Included the changes from version [`9.15.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog). + ## 9.15.0 ✅ Added diff --git a/packages/stream_chat_flutter_core/example/pubspec.yaml b/packages/stream_chat_flutter_core/example/pubspec.yaml index a67a1bd2ea..564a8c0985 100644 --- a/packages/stream_chat_flutter_core/example/pubspec.yaml +++ b/packages/stream_chat_flutter_core/example/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter_core: ^10.0.0-beta.3 + stream_chat_flutter_core: ^10.0.0-beta.4 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index cfec662493..43e96aa062 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter_core homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.3 +version: 10.0.0-beta.4 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -31,7 +31,7 @@ dependencies: meta: ^1.9.1 package_info_plus: ^8.3.0 rxdart: ^0.28.0 - stream_chat: ^10.0.0-beta.3 + stream_chat: ^10.0.0-beta.4 dev_dependencies: build_runner: ^2.4.9 diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 51c96f1ca6..2bc7adaf28 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,7 +1,9 @@ -## Upcoming Beta +## 10.0.0-beta.4 - Added translations for new `locationLabel` label. +- Included the changes from version [`9.15.0`](https://pub.dev/packages/stream_chat_localizations/changelog). + ## 9.15.0 - Updated `stream_chat_flutter` dependency to [`9.15.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_localizations/example/pubspec.yaml b/packages/stream_chat_localizations/example/pubspec.yaml index df4dcc5f33..75826df164 100644 --- a/packages/stream_chat_localizations/example/pubspec.yaml +++ b/packages/stream_chat_localizations/example/pubspec.yaml @@ -24,8 +24,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.3 - stream_chat_localizations: ^10.0.0-beta.3 + stream_chat_flutter: ^10.0.0-beta.4 + stream_chat_localizations: ^10.0.0-beta.4 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_localizations/pubspec.yaml b/packages/stream_chat_localizations/pubspec.yaml index a5d76a1201..5bf46e9cb3 100644 --- a/packages/stream_chat_localizations/pubspec.yaml +++ b/packages/stream_chat_localizations/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_chat_localizations description: The Official localizations for Stream Chat Flutter, a service for building chat applications -version: 10.0.0-beta.3 +version: 10.0.0-beta.4 homepage: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -26,7 +26,7 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.3 + stream_chat_flutter: ^10.0.0-beta.4 dev_dependencies: flutter_test: diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 11ccdd4da5..73d370206a 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,8 +1,10 @@ -## Upcoming Beta +## 10.0.0-beta.4 - Added support for `Location` entity in the database. - Added support for `emojiCode` and `updatedAt` fields in `Reaction` entity. +- Included the changes from version [`9.15.0`](https://pub.dev/packages/stream_chat_persistence/changelog). + ## 9.15.0 🐞 Fixed diff --git a/packages/stream_chat_persistence/example/pubspec.yaml b/packages/stream_chat_persistence/example/pubspec.yaml index d34f53885c..cb18723cb4 100644 --- a/packages/stream_chat_persistence/example/pubspec.yaml +++ b/packages/stream_chat_persistence/example/pubspec.yaml @@ -23,8 +23,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.3 - stream_chat_persistence: ^10.0.0-beta.3 + stream_chat: ^10.0.0-beta.4 + stream_chat_persistence: ^10.0.0-beta.4 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index 1ff8a0a8f8..de7cfc84f0 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_persistence homepage: https://github.com/GetStream/stream-chat-flutter description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.3 +version: 10.0.0-beta.4 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -30,7 +30,7 @@ dependencies: path: ^1.8.3 path_provider: ^2.1.3 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.3 + stream_chat: ^10.0.0-beta.4 dev_dependencies: build_runner: ^2.4.9 diff --git a/sample_app/pubspec.yaml b/sample_app/pubspec.yaml index 5ba315520a..869277a3bc 100644 --- a/sample_app/pubspec.yaml +++ b/sample_app/pubspec.yaml @@ -40,9 +40,9 @@ dependencies: provider: ^6.0.5 rxdart: ^0.28.0 sentry_flutter: ^8.3.0 - stream_chat_flutter: ^10.0.0-beta.3 - stream_chat_localizations: ^10.0.0-beta.3 - stream_chat_persistence: ^10.0.0-beta.3 + stream_chat_flutter: ^10.0.0-beta.4 + stream_chat_localizations: ^10.0.0-beta.4 + stream_chat_persistence: ^10.0.0-beta.4 streaming_shared_preferences: ^2.0.0 uuid: ^4.4.0 video_player: ^2.8.7 From ba38c8e4e2b72fba0aa2e16d92e8a16a52153d06 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 30 Jul 2025 14:32:45 +0200 Subject: [PATCH 25/34] chore: merge fixes --- .../src/fullscreen_media/full_screen_media_desktop.dart | 1 - .../lib/src/message_widget/message_widget.dart | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart b/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart index 5b3451d3d5..f4006ca33d 100644 --- a/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart +++ b/packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart @@ -4,7 +4,6 @@ import 'package:media_kit_video/media_kit_video.dart'; import 'package:photo_view/photo_view.dart'; import 'package:stream_chat_flutter/src/context_menu/context_menu.dart'; import 'package:stream_chat_flutter/src/context_menu/context_menu_region.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart'; import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart'; import 'package:stream_chat_flutter/src/fullscreen_media/gallery_navigation_item.dart'; import 'package:stream_chat_flutter/src/misc/empty_widget.dart'; diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index 95e5ccc19b..a1acc57dc3 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -1,15 +1,9 @@ -import 'dart:async'; - +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart'; import 'package:stream_chat_flutter/src/context_menu/context_menu.dart'; import 'package:stream_chat_flutter/src/context_menu/context_menu_region.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/context_menu_reaction_picker.dart'; -import 'package:stream_chat_flutter/src/context_menu_items/stream_chat_context_menu_item.dart'; -import 'package:stream_chat_flutter/src/dialogs/dialogs.dart'; -import 'package:stream_chat_flutter/src/message_actions_modal/message_actions_modal.dart'; -import 'package:stream_chat_flutter/src/message_actions_modal/moderated_message_actions_modal.dart'; import 'package:stream_chat_flutter/src/message_widget/message_widget_content.dart'; import 'package:stream_chat_flutter/src/misc/flexible_fractionally_sized_box.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; From 3ad5cab53f4356dfe02efd0d134effe9e5357c0d Mon Sep 17 00:00:00 2001 From: Shturma Vladislav Date: Wed, 30 Jul 2025 17:26:04 +0400 Subject: [PATCH 26/34] fix(llc): fixed skipPush and skipEnrichUrl not preserving during message send or update retry (#2330) Co-authored-by: Sahil Kumar --- packages/stream_chat/CHANGELOG.md | 6 + .../stream_chat/lib/src/client/channel.dart | 52 +- .../lib/src/client/retry_queue.dart | 9 +- .../lib/src/core/models/message_state.dart | 126 +- .../core/models/message_state.freezed.dart | 253 +++- .../lib/src/core/models/message_state.g.dart | 27 + .../test/src/client/channel_test.dart | 1211 ++++++++++++++++- .../test/src/client/retry_queue_test.dart | 10 +- .../src/core/models/message_state_test.dart | 24 +- 9 files changed, 1619 insertions(+), 99 deletions(-) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index ee4b1e1ceb..0e4dae96bc 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +🐞 Fixed + +- Fixed `skipPush` and `skipEnrichUrl` not preserving during message send or update retry + ## 10.0.0-beta.4 🛑️ Breaking diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index d0f8784325..b8bd7d8679 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -732,7 +732,10 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.sendingFailed, + state: MessageState.sendingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), ), ]); } @@ -815,14 +818,20 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.updatingFailed, + state: MessageState.updatingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), ), ]); } else { // Reset the message to original state if the update fails and is not // retriable. state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed, + state: MessageState.updatingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), )); } } @@ -885,15 +894,25 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.updatingFailed, + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), ), ]); } else { // Reset the message to original state if the update fails and is not // retriable. - state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed, - )); + state?.updateMessage( + originalMessage.copyWith( + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), + ), + ); } } @@ -997,8 +1016,23 @@ class Channel { return message.state.maybeWhen( failed: (state, _) => state.when( - sendingFailed: () => sendMessage(message), - updatingFailed: () => updateMessage(message), + sendingFailed: (skipPush, skipEnrichUrl) => sendMessage( + message, + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + updatingFailed: (skipPush, skipEnrichUrl) => updateMessage( + message, + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + partialUpdatingFailed: (set, unset, skipEnrichUrl) => + partialUpdateMessage( + message, + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), deletingFailed: (hard) => deleteMessage(message, hard: hard), ), orElse: () { diff --git a/packages/stream_chat/lib/src/client/retry_queue.dart b/packages/stream_chat/lib/src/client/retry_queue.dart index 8675ee68b7..c1f8841406 100644 --- a/packages/stream_chat/lib/src/client/retry_queue.dart +++ b/packages/stream_chat/lib/src/client/retry_queue.dart @@ -119,10 +119,11 @@ class RetryQueue { } static DateTime? _getMessageDate(Message message) { - return message.state.maybeWhen( - failed: (state, _) => state.when( - sendingFailed: () => message.createdAt, - updatingFailed: () => message.updatedAt, + return message.state.maybeMap( + failed: (it) => it.state.map( + sendingFailed: (_) => message.createdAt, + updatingFailed: (_) => message.updatedAt, + partialUpdatingFailed: (_) => message.updatedAt, deletingFailed: (_) => message.deletedAt, ), orElse: () => null, diff --git a/packages/stream_chat/lib/src/core/models/message_state.dart b/packages/stream_chat/lib/src/core/models/message_state.dart index 0cbefec15b..cf98096843 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.dart @@ -103,9 +103,11 @@ extension MessageStateX on MessageState { /// Returns true if the message is in failed updating state. bool get isUpdatingFailed { - final messageState = this; - if (messageState is! MessageFailed) return false; - return messageState.state is UpdatingFailed; + return switch (this) { + MessageFailed(state: UpdatingFailed()) => true, + MessageFailed(state: PartialUpdatingFailed()) => true, + _ => false, + }; } /// Returns true if the message is in failed deleting state. @@ -182,6 +184,46 @@ sealed class MessageState with _$MessageState { ); } + /// Sending failed state when the message fails to be sent. + factory MessageState.sendingFailed({ + required bool skipPush, + required bool skipEnrichUrl, + }) { + return MessageState.failed( + state: FailedState.sendingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + ); + } + + /// Updating failed state when the message fails to be updated. + factory MessageState.updatingFailed({ + required bool skipPush, + required bool skipEnrichUrl, + }) { + return MessageState.failed( + state: FailedState.updatingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + ); + } + + factory MessageState.partialUpdatingFailed({ + Map? set, + List? unset, + required bool skipEnrichUrl, + }) { + return MessageState.failed( + state: FailedState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), + ); + } + /// Sending state when the message is being sent. static const sending = MessageState.outgoing( state: OutgoingState.sending(), @@ -222,16 +264,6 @@ sealed class MessageState with _$MessageState { state: CompletedState.deleted(hard: true), ); - /// Sending failed state when the message fails to be sent. - static const sendingFailed = MessageState.failed( - state: FailedState.sendingFailed(), - ); - - /// Updating failed state when the message fails to be updated. - static const updatingFailed = MessageState.failed( - state: FailedState.updatingFailed(), - ); - /// Deleting failed state when the message fails to be soft deleted. static const softDeletingFailed = MessageState.failed( state: FailedState.deletingFailed(), @@ -285,10 +317,22 @@ sealed class CompletedState with _$CompletedState { @freezed sealed class FailedState with _$FailedState { /// Sending failed state when the message fails to be sent. - const factory FailedState.sendingFailed() = SendingFailed; + const factory FailedState.sendingFailed({ + @Default(false) bool skipPush, + @Default(false) bool skipEnrichUrl, + }) = SendingFailed; /// Updating failed state when the message fails to be updated. - const factory FailedState.updatingFailed() = UpdatingFailed; + const factory FailedState.updatingFailed({ + @Default(false) bool skipPush, + @Default(false) bool skipEnrichUrl, + }) = UpdatingFailed; + + const factory FailedState.partialUpdatingFailed({ + Map? set, + List? unset, + @Default(false) bool skipEnrichUrl, + }) = PartialUpdatingFailed; /// Deleting failed state when the message fails to be deleted. const factory FailedState.deletingFailed({ @@ -616,14 +660,21 @@ extension FailedStatePatternMatching on FailedState { /// @nodoc @optionalTypeArgs TResult when({ - required TResult Function() sendingFailed, - required TResult Function() updatingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) updatingFailed, + required TResult Function( + Map? set, List? unset, bool skipEnrichUrl) + partialUpdatingFailed, required TResult Function(bool hard) deletingFailed, }) { final failedState = this; return switch (failedState) { - SendingFailed() => sendingFailed(), - UpdatingFailed() => updatingFailed(), + SendingFailed() => + sendingFailed(failedState.skipPush, failedState.skipEnrichUrl), + UpdatingFailed() => + updatingFailed(failedState.skipPush, failedState.skipEnrichUrl), + PartialUpdatingFailed() => partialUpdatingFailed( + failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed(failedState.hard), }; } @@ -631,14 +682,21 @@ extension FailedStatePatternMatching on FailedState { /// @nodoc @optionalTypeArgs TResult? whenOrNull({ - TResult? Function()? sendingFailed, - TResult? Function()? updatingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, + required TResult Function( + Map? set, List? unset, bool skipEnrichUrl) + partialUpdatingFailed, TResult? Function(bool hard)? deletingFailed, }) { final failedState = this; return switch (failedState) { - SendingFailed() => sendingFailed?.call(), - UpdatingFailed() => updatingFailed?.call(), + SendingFailed() => + sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + UpdatingFailed() => + updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + PartialUpdatingFailed() => partialUpdatingFailed( + failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; } @@ -646,15 +704,22 @@ extension FailedStatePatternMatching on FailedState { /// @nodoc @optionalTypeArgs TResult maybeWhen({ - TResult Function()? sendingFailed, - TResult Function()? updatingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, + required TResult Function( + Map? set, List? unset, bool skipEnrichUrl) + partialUpdatingFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) { final failedState = this; final result = switch (failedState) { - SendingFailed() => sendingFailed?.call(), - UpdatingFailed() => updatingFailed?.call(), + SendingFailed() => + sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + UpdatingFailed() => + updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + PartialUpdatingFailed() => partialUpdatingFailed( + failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; @@ -666,12 +731,15 @@ extension FailedStatePatternMatching on FailedState { TResult map({ required TResult Function(SendingFailed value) sendingFailed, required TResult Function(UpdatingFailed value) updatingFailed, + required TResult Function(PartialUpdatingFailed value) + partialUpdatingFailed, required TResult Function(DeletingFailed value) deletingFailed, }) { final failedState = this; return switch (failedState) { SendingFailed() => sendingFailed(failedState), UpdatingFailed() => updatingFailed(failedState), + PartialUpdatingFailed() => partialUpdatingFailed(failedState), DeletingFailed() => deletingFailed(failedState), }; } @@ -681,12 +749,14 @@ extension FailedStatePatternMatching on FailedState { TResult? mapOrNull({ TResult? Function(SendingFailed value)? sendingFailed, TResult? Function(UpdatingFailed value)? updatingFailed, + TResult? Function(PartialUpdatingFailed value)? partialUpdatingFailed, TResult? Function(DeletingFailed value)? deletingFailed, }) { final failedState = this; return switch (failedState) { SendingFailed() => sendingFailed?.call(failedState), UpdatingFailed() => updatingFailed?.call(failedState), + PartialUpdatingFailed() => partialUpdatingFailed?.call(failedState), DeletingFailed() => deletingFailed?.call(failedState), }; } @@ -696,6 +766,7 @@ extension FailedStatePatternMatching on FailedState { TResult maybeMap({ TResult Function(SendingFailed value)? sendingFailed, TResult Function(UpdatingFailed value)? updatingFailed, + TResult Function(PartialUpdatingFailed value)? partialUpdatingFailed, TResult Function(DeletingFailed value)? deletingFailed, required TResult orElse(), }) { @@ -703,6 +774,7 @@ extension FailedStatePatternMatching on FailedState { final result = switch (failedState) { SendingFailed() => sendingFailed?.call(failedState), UpdatingFailed() => updatingFailed?.call(failedState), + PartialUpdatingFailed() => partialUpdatingFailed?.call(failedState), DeletingFailed() => deletingFailed?.call(failedState), }; diff --git a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart index 079d8b3696..06cb77449e 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart @@ -736,6 +736,8 @@ FailedState _$FailedStateFromJson(Map json) { return SendingFailed.fromJson(json); case 'updatingFailed': return UpdatingFailed.fromJson(json); + case 'partialUpdatingFailed': + return PartialUpdatingFailed.fromJson(json); case 'deletingFailed': return DeletingFailed.fromJson(json); @@ -774,13 +776,27 @@ class $FailedStateCopyWith<$Res> { /// @nodoc @JsonSerializable() class SendingFailed implements FailedState { - const SendingFailed({final String? $type}) : $type = $type ?? 'sendingFailed'; + const SendingFailed( + {this.skipPush = false, this.skipEnrichUrl = false, final String? $type}) + : $type = $type ?? 'sendingFailed'; factory SendingFailed.fromJson(Map json) => _$SendingFailedFromJson(json); + @JsonKey() + final bool skipPush; + @JsonKey() + final bool skipEnrichUrl; + @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $SendingFailedCopyWith get copyWith => + _$SendingFailedCopyWithImpl(this, _$identity); + @override Map toJson() { return _$SendingFailedToJson( @@ -791,30 +807,86 @@ class SendingFailed implements FailedState { @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is SendingFailed); + (other.runtimeType == runtimeType && + other is SendingFailed && + (identical(other.skipPush, skipPush) || + other.skipPush == skipPush) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => runtimeType.hashCode; + int get hashCode => Object.hash(runtimeType, skipPush, skipEnrichUrl); @override String toString() { - return 'FailedState.sendingFailed()'; + return 'FailedState.sendingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; + } +} + +/// @nodoc +abstract mixin class $SendingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $SendingFailedCopyWith( + SendingFailed value, $Res Function(SendingFailed) _then) = + _$SendingFailedCopyWithImpl; + @useResult + $Res call({bool skipPush, bool skipEnrichUrl}); +} + +/// @nodoc +class _$SendingFailedCopyWithImpl<$Res> + implements $SendingFailedCopyWith<$Res> { + _$SendingFailedCopyWithImpl(this._self, this._then); + + final SendingFailed _self; + final $Res Function(SendingFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + $Res call({ + Object? skipPush = null, + Object? skipEnrichUrl = null, + }) { + return _then(SendingFailed( + skipPush: null == skipPush + ? _self.skipPush + : skipPush // ignore: cast_nullable_to_non_nullable + as bool, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); } } /// @nodoc @JsonSerializable() class UpdatingFailed implements FailedState { - const UpdatingFailed({final String? $type}) + const UpdatingFailed( + {this.skipPush = false, this.skipEnrichUrl = false, final String? $type}) : $type = $type ?? 'updatingFailed'; factory UpdatingFailed.fromJson(Map json) => _$UpdatingFailedFromJson(json); + @JsonKey() + final bool skipPush; + @JsonKey() + final bool skipEnrichUrl; + @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $UpdatingFailedCopyWith get copyWith => + _$UpdatingFailedCopyWithImpl(this, _$identity); + @override Map toJson() { return _$UpdatingFailedToJson( @@ -825,16 +897,181 @@ class UpdatingFailed implements FailedState { @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is UpdatingFailed); + (other.runtimeType == runtimeType && + other is UpdatingFailed && + (identical(other.skipPush, skipPush) || + other.skipPush == skipPush) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => runtimeType.hashCode; + int get hashCode => Object.hash(runtimeType, skipPush, skipEnrichUrl); @override String toString() { - return 'FailedState.updatingFailed()'; + return 'FailedState.updatingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; + } +} + +/// @nodoc +abstract mixin class $UpdatingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $UpdatingFailedCopyWith( + UpdatingFailed value, $Res Function(UpdatingFailed) _then) = + _$UpdatingFailedCopyWithImpl; + @useResult + $Res call({bool skipPush, bool skipEnrichUrl}); +} + +/// @nodoc +class _$UpdatingFailedCopyWithImpl<$Res> + implements $UpdatingFailedCopyWith<$Res> { + _$UpdatingFailedCopyWithImpl(this._self, this._then); + + final UpdatingFailed _self; + final $Res Function(UpdatingFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + $Res call({ + Object? skipPush = null, + Object? skipEnrichUrl = null, + }) { + return _then(UpdatingFailed( + skipPush: null == skipPush + ? _self.skipPush + : skipPush // ignore: cast_nullable_to_non_nullable + as bool, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +@JsonSerializable() +class PartialUpdatingFailed implements FailedState { + const PartialUpdatingFailed( + {final Map? set, + final List? unset, + this.skipEnrichUrl = false, + final String? $type}) + : _set = set, + _unset = unset, + $type = $type ?? 'partialUpdatingFailed'; + factory PartialUpdatingFailed.fromJson(Map json) => + _$PartialUpdatingFailedFromJson(json); + + final Map? _set; + Map? get set { + final value = _set; + if (value == null) return null; + if (_set is EqualUnmodifiableMapView) return _set; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final List? _unset; + List? get unset { + final value = _unset; + if (value == null) return null; + if (_unset is EqualUnmodifiableListView) return _unset; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + @JsonKey() + final bool skipEnrichUrl; + + @JsonKey(name: 'runtimeType') + final String $type; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $PartialUpdatingFailedCopyWith get copyWith => + _$PartialUpdatingFailedCopyWithImpl( + this, _$identity); + + @override + Map toJson() { + return _$PartialUpdatingFailedToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is PartialUpdatingFailed && + const DeepCollectionEquality().equals(other._set, _set) && + const DeepCollectionEquality().equals(other._unset, _unset) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_set), + const DeepCollectionEquality().hash(_unset), + skipEnrichUrl); + + @override + String toString() { + return 'FailedState.partialUpdatingFailed(set: $set, unset: $unset, skipEnrichUrl: $skipEnrichUrl)'; + } +} + +/// @nodoc +abstract mixin class $PartialUpdatingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $PartialUpdatingFailedCopyWith(PartialUpdatingFailed value, + $Res Function(PartialUpdatingFailed) _then) = + _$PartialUpdatingFailedCopyWithImpl; + @useResult + $Res call( + {Map? set, List? unset, bool skipEnrichUrl}); +} + +/// @nodoc +class _$PartialUpdatingFailedCopyWithImpl<$Res> + implements $PartialUpdatingFailedCopyWith<$Res> { + _$PartialUpdatingFailedCopyWithImpl(this._self, this._then); + + final PartialUpdatingFailed _self; + final $Res Function(PartialUpdatingFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + $Res call({ + Object? set = freezed, + Object? unset = freezed, + Object? skipEnrichUrl = null, + }) { + return _then(PartialUpdatingFailed( + set: freezed == set + ? _self._set + : set // ignore: cast_nullable_to_non_nullable + as Map?, + unset: freezed == unset + ? _self._unset + : unset // ignore: cast_nullable_to_non_nullable + as List?, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); } } diff --git a/packages/stream_chat/lib/src/core/models/message_state.g.dart b/packages/stream_chat/lib/src/core/models/message_state.g.dart index e39b40667b..3161a4f8c2 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.g.dart @@ -108,21 +108,48 @@ Map _$DeletedToJson(Deleted instance) => { SendingFailed _$SendingFailedFromJson(Map json) => SendingFailed( + skipPush: json['skip_push'] as bool? ?? false, + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); Map _$SendingFailedToJson(SendingFailed instance) => { + 'skip_push': instance.skipPush, + 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; UpdatingFailed _$UpdatingFailedFromJson(Map json) => UpdatingFailed( + skipPush: json['skip_push'] as bool? ?? false, + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); Map _$UpdatingFailedToJson(UpdatingFailed instance) => { + 'skip_push': instance.skipPush, + 'skip_enrich_url': instance.skipEnrichUrl, + 'runtimeType': instance.$type, + }; + +PartialUpdatingFailed _$PartialUpdatingFailedFromJson( + Map json) => + PartialUpdatingFailed( + set: json['set'] as Map?, + unset: + (json['unset'] as List?)?.map((e) => e as String).toList(), + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, + $type: json['runtimeType'] as String?, + ); + +Map _$PartialUpdatingFailedToJson( + PartialUpdatingFailed instance) => + { + 'set': instance.set, + 'unset': instance.unset, + 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index f8bbb21e65..756f6f956a 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -215,6 +215,7 @@ void main() { tearDown(() { channel.dispose(); + clearInteractions(client); }); test('should throw if trying to set `extraData`', () { @@ -288,6 +289,269 @@ void main() { )).called(1); }); + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: true, skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: false, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + skipPush: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: true, skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-2', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + skipPush: true, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: false, skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-3', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: true, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: false, skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-4', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test('should not update message state when non-retriable error occurs', + () async { + final message = Message( + id: 'test-message-id', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.inputError.code, + message: 'Input error', + data: ErrorResponse() + ..code = ChatErrorCode.inputError.code + ..message = 'Input error' + ..statusCode = 400, + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage(message); + } catch (e) { + expect(e, isA()); + } + + final updatedMessage = + channel.state!.messages.firstWhere((m) => m.id == message.id); + expect(updatedMessage.state, isA()); + expect( + updatedMessage.state.maybeWhen( + failed: (state, _) => state.map( + sendingFailed: (_) => false, + updatingFailed: (_) => false, + partialUpdatingFailed: (_) => false, + deletingFailed: (_) => false, + ), + orElse: () => true, + ), + isTrue); + }); + test('with attachments should work just fine', () async { final attachments = List.generate( 3, @@ -990,64 +1254,626 @@ void main() { any(that: isSameMessageAs(message)), )).called(1); }); - }); - test('`.partialUpdateMessage`', () async { - final message = Message( - id: 'test-message-id', - state: MessageState.sent, - ); + test( + 'should not update message state when error is not StreamChatNetworkError', + () async { + final message = Message( + id: 'test-message-id-error-1', + state: MessageState.sent, + ); - const set = {'text': 'Update Message text'}; - const unset = ['pinExpires']; + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipEnrichUrl: true, + )).thenThrow(ArgumentError('Invalid argument')); - final updateMessageResponse = UpdateMessageResponse() - ..message = message.copyWith(text: set['text'], pinExpires: null); + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + ]), + ); - when( - () => client.partialUpdateMessage(message.id, set: set, unset: unset), - ).thenAnswer((_) async => updateMessageResponse); + try { + await channel.updateMessage(message, skipEnrichUrl: true); + } catch (e) { + expect(e, isA()); + } + }); - expectLater( - // skipping first seed message list -> [] messages - channel.state?.messagesStream.skip(1), - emitsInOrder([ - [ - isSameMessageAs( - message.copyWith( - state: MessageState.updating, - ), - matchText: true, - matchMessageState: true, - ), - ], - [ - isSameMessageAs( - updateMessageResponse.message.copyWith( - state: MessageState.updated, - ), - matchText: true, - matchMessageState: true, - ), + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipPush: false, skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-retry-1', + state: MessageState.sent, + ); + + // Create a retriable error (data == null) + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.requestTimeout.code, + message: 'Request timed out', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: true, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage(message, skipEnrichUrl: true); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.requestTimeout.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipPush: true, skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-retry-2', + state: MessageState.sent, + ); + + // Create a retriable error (data == null) + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipPush: true, + )).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.internalSystemError.code, + message: 'Internal system error', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed( + skipPush: true, + skipEnrichUrl: false, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage(message, skipPush: true); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, + equals(ChatErrorCode.internalSystemError.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipPush: true, skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-error-2', + state: MessageState.sent, + ); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipPush: true, + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage( + message, + skipPush: true, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipPush: false, skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-error-3', + state: MessageState.sent, + ); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage(message); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + }); + + test('`.partialUpdateMessage`', () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sent, + ); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(text: set['text'], pinExpires: null); + + when( + () => client.partialUpdateMessage(message.id, set: set, unset: unset), + ).thenAnswer((_) async => updateMessageResponse); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + updateMessageResponse.message.copyWith( + state: MessageState.updated, + ), + matchText: true, + matchMessageState: true, + ), ], ]), ); - final res = await channel.partialUpdateMessage( - message, - set: set, - unset: unset, - ); + final res = await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + + expect(res, isNotNull); + expect(res.message.id, message.id); + expect(res.message.id, message.id); + expect(res.message.text, set['text']); + expect(res.message.pinExpires, isNull); + + verify( + () => client.partialUpdateMessage(message.id, set: set, unset: unset), + ).called(1); + }); + + group('`.partialUpdateMessage` error handling', () { + test( + 'should not update message state when error is not StreamChatNetworkError', + () async { + final message = Message( + id: 'test-message-id-error-partial-1', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + ), + ).thenThrow(ArgumentError('Invalid argument')); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + } catch (e) { + expect(e, isA()); + } + }); + + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-retry-partial-1', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + // Create a retriable error (data == null) + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + skipEnrichUrl: true, + ), + ).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.requestTimeout.code, + message: 'Request timed out', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: true, + ), + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.requestTimeout.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-retry-partial-2', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + // Create a retriable error (data == null) + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + ), + ).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.internalSystemError.code, + message: 'Internal system error', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: false, + ), + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, + equals(ChatErrorCode.internalSystemError.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-error-partial-2', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + skipEnrichUrl: true, + ), + ).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: true, + ), + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-error-partial-3', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + ), + ).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: false, + ), + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); - expect(res, isNotNull); - expect(res.message.id, message.id); - expect(res.message.id, message.id); - expect(res.message.text, set['text']); - expect(res.message.pinExpires, isNull); + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + } catch (e) { + expect(e, isA()); - verify( - () => client.partialUpdateMessage(message.id, set: set, unset: unset), - ).called(1); + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); }); group('`.deleteMessage`', () { @@ -5562,4 +6388,295 @@ void main() { expect(channel.canUpdateChannel, false); }); }); + + group('Retry functionality with parameter preservation', () { + late final client = MockStreamChatClient(); + const channelId = 'test-channel-id'; + const channelType = 'test-channel-type'; + late Channel channel; + + setUpAll(() { + registerFallbackValue(FakeMessage()); + registerFallbackValue([]); + registerFallbackValue(FakeAttachmentFile()); + + when(() => client.detachedLogger(any())).thenAnswer((invocation) { + final name = invocation.positionalArguments.first; + return _createLogger(name); + }); + + when(() => client.logger).thenReturn(_createLogger('mock-client-logger')); + + final clientState = FakeClientState(); + when(() => client.state).thenReturn(clientState); + + final retryPolicy = RetryPolicy( + shouldRetry: (_, __, error) { + return error is StreamChatNetworkError && error.isRetriable; + }, + ); + when(() => client.retryPolicy).thenReturn(retryPolicy); + }); + + setUp(() { + final channelState = _generateChannelState(channelId, channelType); + channel = Channel.fromState(client, channelState); + }); + + tearDown(() { + channel.dispose(); + }); + + group('retryMessage method', () { + test( + 'should call sendMessage with preserved skipPush and skipEnrichUrl parameters', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + skipEnrichUrl: true, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + skipEnrichUrl: true, + )).called(1); + }); + + test('should call sendMessage with preserved skipPush parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: false, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + )).called(1); + }); + + test('should call sendMessage with preserved skipEnrichUrl parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: true, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipEnrichUrl: true, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipEnrichUrl: true, + )).called(1); + }); + + test( + 'should call sendMessage with preserved false skipPush and skipEnrichUrl parameters', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).called(1); + }); + + test( + 'should call updateMessage with preserved skipPush, skipEnrichUrl parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.updatingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ); + + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(state: MessageState.updated); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipPush: true, + skipEnrichUrl: true, + )).thenAnswer((_) async => updateMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipPush: true, + skipEnrichUrl: true, + )).called(1); + }); + + test( + 'should call updateMessage with preserved false skipPush, skipEnrichUrl parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ); + + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(state: MessageState.updated); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + )).thenAnswer((_) async => updateMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.updateMessage( + any(that: isSameMessageAs(message)), + )).called(1); + }); + + test('should call deleteMessage with preserved hard parameter', () async { + final message = Message( + id: 'test-message-id', + createdAt: DateTime.now(), + state: MessageState.deletingFailed(hard: true), + ); + + when(() => client.deleteMessage( + message.id, + hard: true, + )).thenAnswer((_) async => EmptyResponse()); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.deleteMessage( + message.id, + hard: true, + )).called(1); + }); + + test('should call deleteMessage with preserved false hard parameter', + () async { + final message = Message( + id: 'test-message-id', + createdAt: DateTime.now(), + state: MessageState.deletingFailed(hard: false), + ); + + when(() => client.deleteMessage( + message.id, + )).thenAnswer((_) async => EmptyResponse()); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.deleteMessage( + message.id, + )).called(1); + }); + + test('should throw AssertionError when message state is not failed', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sent, + ); + + expect(() => channel.retryMessage(message), + throwsA(isA())); + }); + }); + }); } diff --git a/packages/stream_chat/test/src/client/retry_queue_test.dart b/packages/stream_chat/test/src/client/retry_queue_test.dart index 1150c40b85..59e2e51f47 100644 --- a/packages/stream_chat/test/src/client/retry_queue_test.dart +++ b/packages/stream_chat/test/src/client/retry_queue_test.dart @@ -46,7 +46,10 @@ void main() { final message = Message( id: 'test-message-id', text: 'Sample message test', - state: MessageState.sendingFailed, + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), ); retryQueue.add([message]); expect(() => retryQueue.add([message]), returnsNormally); @@ -58,7 +61,10 @@ void main() { final message = Message( id: 'test-message-id', text: 'Sample message test', - state: MessageState.sendingFailed, + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), ); retryQueue.add([message]); expect(retryQueue.hasMessages, isTrue); diff --git a/packages/stream_chat/test/src/core/models/message_state_test.dart b/packages/stream_chat/test/src/core/models/message_state_test.dart index 9bdb250af9..4d5ac13a31 100644 --- a/packages/stream_chat/test/src/core/models/message_state_test.dart +++ b/packages/stream_chat/test/src/core/models/message_state_test.dart @@ -270,7 +270,10 @@ void main() { test( 'MessageState.sendingFailed should create a MessageFailed instance with SendingFailed state', () { - const messageState = MessageState.sendingFailed; + final messageState = MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ); expect(messageState, isA()); expect((messageState as MessageFailed).state, isA()); }, @@ -279,12 +282,29 @@ void main() { test( 'MessageState.updatingFailed should create a MessageFailed instance with UpdatingFailed state', () { - const messageState = MessageState.updatingFailed; + final messageState = MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: false, + ); expect(messageState, isA()); expect((messageState as MessageFailed).state, isA()); }, ); + test( + 'MessageState.partialUpdatingFailed should create a MessageFailed instance with UpdatingFailed state', + () { + final messageState = MessageState.partialUpdatingFailed( + skipEnrichUrl: false, + ); + expect(messageState, isA()); + expect( + (messageState as MessageFailed).state, + isA(), + ); + }, + ); + test( 'MessageState.softDeletingFailed should create a MessageFailed instance with DeletingFailed state and not hard deleting', () { From 8e06a3631a9216af763603c57c5885eb10d8490a Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 30 Jul 2025 16:55:43 +0200 Subject: [PATCH 27/34] fix(llc, ui): update message state on failure This commit addresses the following: - **LLC:** Ensures that the message state is correctly updated to `failed` before attempting to retry in `sendMessage`, `updateMessage`, `partialUpdateMessage`, and `deleteMessage`. Previously, the state was only updated after a successful retry or if the retry failed again. - **LLC:** `retryFailedMessages` now correctly handles the case where there are no failed messages. - **UI:** The `message_actions_builder` now correctly hides actions for messages that are in a `deleted` state, even if they also have a `failed` state. - **UI:** Fixes an issue where deleted messages with a failed state would have incorrect spacing. --- .../stream_chat/lib/src/client/channel.dart | 141 ++++++++---------- .../message_actions_builder.dart | 5 +- .../message_widget_content.dart | 18 ++- 3 files changed, 80 insertions(+), 84 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index b8bd7d8679..945c826500 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -665,7 +665,7 @@ class Channel { _checkInitialized(); // Clean up stale error messages before sending a new message. - state!.cleanUpStaleErrorMessages(); + state?.cleanUpStaleErrorMessages(); // Cancelling previous completer in case it's called again in the process // Eg. Updating the message while the previous call is in progress. @@ -690,7 +690,7 @@ class Channel { ).toList(), ); - state!.updateMessage(message); + state?.updateMessage(message); try { if (message.attachments.any((it) => !it.uploadState.isSuccess)) { @@ -724,20 +724,22 @@ class Channel { state: MessageState.sent, ); - state!.updateMessage(sentMessage); + state?.updateMessage(sentMessage); return response; } catch (e) { + final failedMessage = message.copyWith( + // Update the message state to failed. + state: MessageState.sendingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + ); + + state?.updateMessage(failedMessage); + // If the error is retriable, add it to the retry queue. if (e is StreamChatNetworkError && e.isRetriable) { - state!._retryQueue.add([ - message.copyWith( - // Update the message state to failed. - state: MessageState.sendingFailed( - skipPush: skipPush, - skipEnrichUrl: skipEnrichUrl, - ), - ), - ]); + state?._retryQueue.add([failedMessage]); } rethrow; @@ -756,7 +758,6 @@ class Channel { bool skipEnrichUrl = false, }) async { _checkInitialized(); - final originalMessage = message; // Cancelling previous completer in case it's called again in the process // Eg. Updating the message while the previous call is in progress. @@ -813,28 +814,20 @@ class Channel { return response; } catch (e) { - if (e is StreamChatNetworkError) { - if (e.isRetriable) { - state!._retryQueue.add([ - message.copyWith( - // Update the message state to failed. - state: MessageState.updatingFailed( - skipPush: skipPush, - skipEnrichUrl: skipEnrichUrl, - ), - ), - ]); - } else { - // Reset the message to original state if the update fails and is not - // retriable. - state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed( - skipPush: skipPush, - skipEnrichUrl: skipEnrichUrl, - ), - )); - } + final failedMessage = message.copyWith( + // Update the message state to failed. + state: MessageState.updatingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + ); + + state?.updateMessage(failedMessage); + // If the error is retriable, add it to the retry queue. + if (e is StreamChatNetworkError && e.isRetriable) { + state?._retryQueue.add([failedMessage]); } + rethrow; } } @@ -851,7 +844,6 @@ class Channel { bool skipEnrichUrl = false, }) async { _checkInitialized(); - final originalMessage = message; // Cancelling previous completer in case it's called again in the process // Eg. Updating the message while the previous call is in progress. @@ -889,31 +881,19 @@ class Channel { return response; } catch (e) { - if (e is StreamChatNetworkError) { - if (e.isRetriable) { - state!._retryQueue.add([ - message.copyWith( - // Update the message state to failed. - state: MessageState.partialUpdatingFailed( - set: set, - unset: unset, - skipEnrichUrl: skipEnrichUrl, - ), - ), - ]); - } else { - // Reset the message to original state if the update fails and is not - // retriable. - state?.updateMessage( - originalMessage.copyWith( - state: MessageState.partialUpdatingFailed( - set: set, - unset: unset, - skipEnrichUrl: skipEnrichUrl, - ), - ), - ); - } + final failedMessage = message.copyWith( + // Update the message state to failed. + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), + ); + + state?.updateMessage(failedMessage); + // If the error is retriable, add it to the retry queue. + if (e is StreamChatNetworkError && e.isRetriable) { + state?._retryQueue.add([failedMessage]); } rethrow; @@ -932,7 +912,7 @@ class Channel { // Directly deleting the local messages and bounced error messages as they // are not available on the server. if (message.remoteCreatedAt == null || message.isBouncedWithError) { - state!.deleteMessage( + state?.deleteMessage( message.copyWith( type: MessageType.deleted, localDeletedAt: DateTime.now(), @@ -987,14 +967,17 @@ class Channel { return response; } catch (e) { + final failedMessage = message.copyWith( + // Update the message state to failed. + state: MessageState.deletingFailed(hard: hard), + ); + + state?.deleteMessage(failedMessage, hardDelete: hard); + // If the error is retriable, add it to the retry queue. if (e is StreamChatNetworkError && e.isRetriable) { - state!._retryQueue.add([ - message.copyWith( - // Update the message state to failed. - state: MessageState.deletingFailed(hard: hard), - ), - ]); + state?._retryQueue.add([failedMessage]); } + rethrow; } } @@ -1005,6 +988,9 @@ class Channel { /// retry action: /// - For [MessageState.sendingFailed], it attempts to send the message. /// - For [MessageState.updatingFailed], it attempts to update the message. + /// - For [MessageState.partialUpdatingFailed], it attempts to partially + /// update the message with the same 'set' and 'unset' parameters that were + /// used in the original request. /// - For [MessageState.deletingFailed], it attempts to delete the message. /// with the same 'hard' parameter that was used in the original request /// - For messages with [isBouncedWithError], it attempts to send the message. @@ -1026,13 +1012,14 @@ class Channel { skipPush: skipPush, skipEnrichUrl: skipEnrichUrl, ), - partialUpdatingFailed: (set, unset, skipEnrichUrl) => - partialUpdateMessage( - message, - set: set, - unset: unset, - skipEnrichUrl: skipEnrichUrl, - ), + partialUpdatingFailed: (set, unset, skipEnrichUrl) { + return partialUpdateMessage( + message, + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ); + }, deletingFailed: (hard) => deleteMessage(message, hard: hard), ), orElse: () { @@ -2516,8 +2503,10 @@ class ChannelClientState { /// Retry failed message. Future retryFailedMessages() async { - final failedMessages = [...messages, ...threads.values.expand((v) => v)] - .where((it) => it.state.isFailed); + final allMessages = [...messages, ...threads.values.flattened]; + final failedMessages = allMessages.where((it) => it.state.isFailed); + + if (failedMessages.isEmpty) return; _retryQueue.add(failedMessages); } diff --git a/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart index d7bc0aafea..f9dbae07b4 100644 --- a/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart +++ b/packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart @@ -61,10 +61,11 @@ class StreamMessageActionsBuilder { OwnUser? currentUser, Iterable? customActions, }) { + final messageState = message.state; + // If the message is deleted, we don't show any actions. - if (message.isDeleted) return []; + if (messageState.isDeleted) return []; - final messageState = message.state; if (messageState.isFailed) { return [ if (messageState.isSendingFailed || messageState.isUpdatingFailed) ...[ diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart index 1bdd74812c..f56e636cdc 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart @@ -342,12 +342,18 @@ class MessageWidgetContent extends StatelessWidget { } Widget _buildMessageCard(BuildContext context) { - if (message.isDeleted && !isFailedState) { - return StreamDeletedMessage( - borderRadiusGeometry: borderRadiusGeometry, - borderSide: borderSide, - shape: shape, - messageTheme: messageTheme, + if (message.isDeleted) { + return Container( + margin: EdgeInsetsDirectional.only( + end: reverse && isFailedState ? 12.0 : 0.0, + start: !reverse && isFailedState ? 12.0 : 0.0, + ), + child: StreamDeletedMessage( + borderRadiusGeometry: borderRadiusGeometry, + borderSide: borderSide, + shape: shape, + messageTheme: messageTheme, + ), ); } From 4ca7fe91ee216d04ca0407f8d275bae7be2c9cff Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 7 Aug 2025 00:55:18 +0200 Subject: [PATCH 28/34] refactor(ui): introduce showStreamDialog and replace showStreamMessageModal (#2344) --- .../test/src/client/channel_test.dart | 56 ++++++--- .../message_modal/message_actions_modal.dart | 27 ++-- .../lib/src/message_modal/message_modal.dart | 118 ++++++------------ .../message_reactions_modal.dart | 29 +++-- .../src/message_widget/message_widget.dart | 34 +++-- .../lib/src/misc/simple_safe_area.dart | 83 ++++++++++-- .../lib/src/misc/stream_modal.dart | 61 +++++++++ .../lib/stream_chat_flutter.dart | 1 + .../message_actions_builder_test.dart | 11 +- 9 files changed, 279 insertions(+), 141 deletions(-) create mode 100644 packages/stream_chat_flutter/lib/src/misc/stream_modal.dart diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index 756f6f956a..a70bf66454 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -497,7 +497,7 @@ void main() { } }); - test('should not update message state when non-retriable error occurs', + test('should update message state even when non-retriable error occurs', () async { final message = Message( id: 'test-message-id', @@ -527,6 +527,17 @@ void main() { matchMessageState: true, ), ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ), + matchMessageState: true, + ), + ] ]), ); @@ -535,21 +546,6 @@ void main() { } catch (e) { expect(e, isA()); } - - final updatedMessage = - channel.state!.messages.firstWhere((m) => m.id == message.id); - expect(updatedMessage.state, isA()); - expect( - updatedMessage.state.maybeWhen( - failed: (state, _) => state.map( - sendingFailed: (_) => false, - updatingFailed: (_) => false, - partialUpdatingFailed: (_) => false, - deletingFailed: (_) => false, - ), - orElse: () => true, - ), - isTrue); }); test('with attachments should work just fine', () async { @@ -1256,7 +1252,7 @@ void main() { }); test( - 'should not update message state when error is not StreamChatNetworkError', + 'should update message state even when error is not StreamChatNetworkError', () async { final message = Message( id: 'test-message-id-error-1', @@ -1278,6 +1274,17 @@ void main() { matchMessageState: true, ), ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: true, + ), + ), + matchMessageState: true, + ), + ] ]), ); @@ -1552,7 +1559,7 @@ void main() { group('`.partialUpdateMessage` error handling', () { test( - 'should not update message state when error is not StreamChatNetworkError', + 'should update message state even when error is not StreamChatNetworkError', () async { final message = Message( id: 'test-message-id-error-partial-1', @@ -1586,6 +1593,19 @@ void main() { matchMessageState: true, ), ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.partialUpdatingFailed( + set: set, + unset: unset, + skipEnrichUrl: false, + ), + ), + matchText: true, + matchMessageState: true, + ), + ] ]), ); diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart index e98c74fd25..02e929b26f 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart @@ -83,18 +83,25 @@ class StreamMessageActionsModal extends StatelessWidget { ), }; - return StreamMessageModal( + return StreamMessageDialog( spacing: 4, alignment: alignment, - headerBuilder: (context) => ReactionPickerBubbleOverlay( - message: message, - reverse: reverse, - visible: showReactionPicker, - anchorOffset: const Offset(0, -8), - onReactionPicked: onReactionPicked, - reactionPickerBuilder: reactionPickerBuilder, - child: IgnorePointer(child: messageWidget), - ), + headerBuilder: (context) { + final safeArea = MediaQuery.paddingOf(context); + + return Padding( + padding: EdgeInsets.only(top: safeArea.top), + child: ReactionPickerBubbleOverlay( + message: message, + reverse: reverse, + visible: showReactionPicker, + anchorOffset: const Offset(0, -8), + onReactionPicked: onReactionPicked, + reactionPickerBuilder: reactionPickerBuilder, + child: IgnorePointer(child: messageWidget), + ), + ); + }, contentBuilder: (context) { final actions = Column( mainAxisSize: MainAxisSize.min, diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart index 57035fee32..ec80700364 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart @@ -1,91 +1,28 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; -import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/utils/extensions.dart'; -/// Shows a modal dialog with customized transitions and backdrop effects. -/// -/// This function is a wrapper around [showGeneralDialog] that provides -/// a consistent look and feel for message-related modals in Stream Chat. -/// -/// Returns a [Future] that resolves to the value passed to [Navigator.pop] -/// when the dialog is closed. -Future showStreamMessageModal({ - required BuildContext context, - required WidgetBuilder builder, - bool useSafeArea = true, - bool barrierDismissible = true, - String? barrierLabel, - Color? barrierColor, - Duration transitionDuration = const Duration(milliseconds: 335), - RouteTransitionsBuilder? transitionBuilder, - bool useRootNavigator = true, - RouteSettings? routeSettings, - Offset? anchorPoint, -}) { - assert(debugCheckHasMaterialLocalizations(context), ''); - final localizations = MaterialLocalizations.of(context); - - final theme = StreamChatTheme.of(context); - final colorTheme = theme.colorTheme; - - final capturedThemes = InheritedTheme.capture( - from: context, - to: Navigator.of(context, rootNavigator: useRootNavigator).context, - ); - - return showGeneralDialog( - context: context, - useRootNavigator: useRootNavigator, - anchorPoint: anchorPoint, - routeSettings: routeSettings, - transitionDuration: transitionDuration, - barrierDismissible: barrierDismissible, - barrierColor: barrierColor ?? colorTheme.overlay, - barrierLabel: barrierLabel ?? localizations.modalBarrierDismissLabel, - transitionBuilder: (context, animation, secondaryAnimation, child) { - final sigma = 10 * animation.value; - final scaleAnimation = Tween(begin: 0, end: 1).animate( - CurvedAnimation(parent: animation, curve: Curves.easeOutBack), - ); - - return BackdropFilter( - filter: ImageFilter.blur(sigmaX: sigma, sigmaY: sigma), - child: ScaleTransition(scale: scaleAnimation, child: child), - ); - }, - pageBuilder: (context, animation, secondaryAnimation) { - final pageChild = Builder(builder: builder); - - var dialog = capturedThemes.wrap(pageChild); - if (useSafeArea) dialog = SafeArea(child: dialog); - return dialog; - }, - ); -} - -/// {@template streamMessageModal} -/// A customizable modal widget for displaying message-related content. +/// {@template streamMessageDialog} +/// A customizable modal dialog for displaying message-related content. /// /// This widget provides a consistent container for message actions and other -/// message-related modal content. It handles layout, animation, and keyboard +/// message-related dialog content. It handles layout, animation, and keyboard /// adjustments automatically. /// -/// The modal can contain a header (optional) and content section (required), +/// The dialog can contain a header (optional) and content section (required), /// and will adjust its position when the keyboard appears. /// {@endtemplate} -class StreamMessageModal extends StatelessWidget { - /// Creates a Stream message modal. +class StreamMessageDialog extends StatelessWidget { + /// Creates a Stream message dialog. /// /// The [contentBuilder] parameter is required to build the main content - /// of the modal. The [headerBuilder] is optional and can be used to add + /// of the dialog. The [headerBuilder] is optional and can be used to add /// a header above the main content. - const StreamMessageModal({ + const StreamMessageDialog({ super.key, this.spacing = 8.0, this.headerBuilder, required this.contentBuilder, + this.useSafeArea = true, this.insetAnimationDuration = const Duration(milliseconds: 100), this.insetAnimationCurve = Curves.decelerate, this.insetPadding = const EdgeInsets.all(8), @@ -95,32 +32,37 @@ class StreamMessageModal extends StatelessWidget { /// Vertical spacing between header and content sections. final double spacing; - /// Optional builder for the header section of the modal. + /// Optional builder for the header section of the dialog. final WidgetBuilder? headerBuilder; - /// Required builder for the main content of the modal. + /// Required builder for the main content of the dialog. final WidgetBuilder contentBuilder; + /// Whether to use a [SafeArea] to avoid system UI intrusions. + /// + /// Defaults to `true`. + final bool useSafeArea; + /// The duration of the animation to show when the system keyboard intrudes - /// into the space that the modal is placed in. + /// into the space that the dialog is placed in. /// /// Defaults to 100 milliseconds. final Duration insetAnimationDuration; /// The curve to use for the animation shown when the system keyboard intrudes - /// into the space that the modal is placed in. + /// into the space that the dialog is placed in. /// /// Defaults to [Curves.decelerate]. final Curve insetAnimationCurve; /// The amount of padding added to [MediaQueryData.viewInsets] on the outside - /// of the modal. This defines the minimum space between the screen's edges - /// and the modal. + /// of the dialog. This defines the minimum space between the screen's edges + /// and the dialog. /// /// Defaults to `EdgeInsets.zero`. final EdgeInsets insetPadding; - /// How to align the [StreamMessageModal]. + /// How to align the [StreamMessageDialog]. /// /// Defaults to [Alignment.center]. final AlignmentGeometry alignment; @@ -129,7 +71,7 @@ class StreamMessageModal extends StatelessWidget { Widget build(BuildContext context) { final effectivePadding = MediaQuery.viewInsetsOf(context) + insetPadding; - final child = Align( + final dialogChild = Align( alignment: alignment, child: ConstrainedBox( constraints: const BoxConstraints(minWidth: 280), @@ -148,7 +90,7 @@ class StreamMessageModal extends StatelessWidget { ), ); - return AnimatedPadding( + Widget dialog = AnimatedPadding( padding: effectivePadding, duration: insetAnimationDuration, curve: insetAnimationCurve, @@ -158,8 +100,20 @@ class StreamMessageModal extends StatelessWidget { removeRight: true, removeBottom: true, context: context, - child: child, + child: dialogChild, ), ); + + if (useSafeArea) { + dialog = Align( + alignment: alignment, + child: SingleChildScrollView( + hitTestBehavior: HitTestBehavior.translucent, + child: SafeArea(child: dialog), + ), + ); + } + + return dialog; } } diff --git a/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart index 8cdb697282..96920b3e9c 100644 --- a/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart @@ -11,7 +11,7 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// 2. The original message widget /// 3. A display of all current reactions with user avatars /// -/// The modal uses [StreamMessageModal] as its base layout and customizes +/// The modal uses [StreamMessageDialog] as its base layout and customizes /// both the header and content sections to display reaction-specific /// information. /// {@endtemplate} @@ -78,18 +78,25 @@ class StreamMessageReactionsModal extends StatelessWidget { }, }; - return StreamMessageModal( + return StreamMessageDialog( spacing: 4, alignment: alignment, - headerBuilder: (context) => ReactionPickerBubbleOverlay( - message: message, - reverse: reverse, - visible: showReactionPicker, - anchorOffset: const Offset(0, -8), - onReactionPicked: onReactionPicked, - reactionPickerBuilder: reactionPickerBuilder, - child: IgnorePointer(child: messageWidget), - ), + headerBuilder: (context) { + final safeArea = MediaQuery.paddingOf(context); + + return Padding( + padding: EdgeInsets.only(top: safeArea.top), + child: ReactionPickerBubbleOverlay( + message: message, + reverse: reverse, + visible: showReactionPicker, + anchorOffset: const Offset(0, -8), + onReactionPicked: onReactionPicked, + reactionPickerBuilder: reactionPickerBuilder, + child: IgnorePointer(child: messageWidget), + ), + ); + }, contentBuilder: (context) { final reactions = message.latestReactions; final hasReactions = reactions != null && reactions.isNotEmpty; diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index a1acc57dc3..111d479f2c 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -897,7 +897,7 @@ class _StreamMessageWidgetState extends State if (popped) return _onActionTap(context, channel, action).ignore(); } - return showStreamMessageModal( + return showStreamDialog( context: context, useRootNavigator: false, builder: (_) => StreamChatConfiguration( @@ -972,7 +972,7 @@ class _StreamMessageWidgetState extends State if (popped) return _onActionTap(context, channel, action).ignore(); } - return showStreamMessageModal( + return showStreamDialog( context: context, useRootNavigator: false, builder: (_) => ModeratedMessageActionsModal( @@ -1015,7 +1015,7 @@ class _StreamMessageWidgetState extends State if (popped) return _onActionTap(context, channel, action).ignore(); } - return showStreamMessageModal( + return showStreamDialog( context: context, useRootNavigator: false, builder: (_) => StreamChatConfiguration( @@ -1094,7 +1094,7 @@ class _StreamMessageWidgetState extends State Message message, Channel channel, ) async { - final confirmDelete = await showStreamMessageModal( + final confirmDelete = await showStreamDialog( context: context, builder: (context) => StreamMessageActionConfirmationModal( title: Text(context.translations.deleteMessageLabel), @@ -1128,7 +1128,7 @@ class _StreamMessageWidgetState extends State Message message, Channel channel, ) async { - final confirmFlag = await showStreamMessageModal( + final confirmFlag = await showStreamDialog( context: context, builder: (context) => StreamMessageActionConfirmationModal( title: Text(context.translations.flagMessageLabel), @@ -1171,11 +1171,27 @@ class _StreamMessageWidgetState extends State extension on Message { Message get trimmed { - if (text case final messageText? when messageText.length > 200) { - return copyWith(text: '${messageText.substring(0, 200)}...'); - } + final trimmedText = switch (text) { + final text? when text.length > 100 => '${text.substring(0, 100)}...', + _ => text, + }; + + return copyWith( + text: trimmedText, + poll: poll?.trimmed, + quotedMessage: quotedMessage?.trimmed, + ); + } +} + +extension on Poll { + Poll get trimmed { + final trimmedName = switch (name) { + final name when name.length > 100 => '${name.substring(0, 100)}...', + _ => name, + }; - return this; + return copyWith(name: trimmedName); } } diff --git a/packages/stream_chat_flutter/lib/src/misc/simple_safe_area.dart b/packages/stream_chat_flutter/lib/src/misc/simple_safe_area.dart index a691b568ee..7aeeb8615c 100644 --- a/packages/stream_chat_flutter/lib/src/misc/simple_safe_area.dart +++ b/packages/stream_chat_flutter/lib/src/misc/simple_safe_area.dart @@ -1,27 +1,90 @@ import 'package:flutter/material.dart'; -/// A [SafeArea] with an enabled toggle +/// A simple wrapper around Flutter's [SafeArea] widget. +/// +/// [SimpleSafeArea] provides a convenient way to avoid system intrusions +/// (such as notches, status, and navigation bars) on all or specific sides. +/// +/// By default, all sides are enabled. Use [SimpleSafeArea.only] to specify +/// specific sides to avoid. +/// +/// See also: +/// - [SafeArea], which this widget wraps. +/// class SimpleSafeArea extends StatelessWidget { - /// Constructor for [SimpleSafeArea] + /// Creates a [SimpleSafeArea] that avoids system intrusions either on all + /// sides or none. const SimpleSafeArea({ super.key, - this.enabled = true, + bool? enabled, + this.minimum = EdgeInsets.zero, + this.maintainBottomViewPadding = false, + required this.child, + }) : left = enabled ?? true, + top = enabled ?? true, + right = enabled ?? true, + bottom = enabled ?? true; + + /// Creates a [SimpleSafeArea] that avoids system intrusions only on the + /// specified sides. + const SimpleSafeArea.only({ + super.key, + this.left = false, + this.top = false, + this.right = false, + this.bottom = false, + this.minimum = EdgeInsets.zero, + this.maintainBottomViewPadding = false, required this.child, }); - /// Wrap [child] with [SafeArea] - final bool? enabled; + /// Whether to avoid system intrusions on the left. + final bool left; + + /// Whether to avoid system intrusions at the top of the screen, typically the + /// system status bar. + final bool top; + + /// Whether to avoid system intrusions on the right. + final bool right; + + /// Whether to avoid system intrusions on the bottom side of the screen. + final bool bottom; + + /// This minimum padding to apply. + /// + /// The greater of the minimum insets and the media padding will be applied. + final EdgeInsets minimum; + + /// Specifies whether the [SafeArea] should maintain the bottom + /// [MediaQueryData.viewPadding] instead of the bottom + /// [MediaQueryData.padding], defaults to false. + /// + /// For example, if there is an onscreen keyboard displayed above the + /// SafeArea, the padding can be maintained below the obstruction rather than + /// being consumed. This can be helpful in cases where your layout contains + /// flexible widgets, which could visibly move when opening a software + /// keyboard due to the change in the padding value. Setting this to true will + /// avoid the UI shift. + final bool maintainBottomViewPadding; - /// Child widget to wrap + /// The widget below this widget in the tree. + /// + /// The padding on the [MediaQuery] for the [child] will be suitably adjusted + /// to zero out any sides that were avoided by this widget. + /// + /// {@macro flutter.widgets.ProxyWidget.child} final Widget child; @override Widget build(BuildContext context) { return SafeArea( - left: enabled ?? true, - top: enabled ?? true, - right: enabled ?? true, - bottom: enabled ?? true, + left: left, + top: top, + right: right, + bottom: bottom, + minimum: minimum, + maintainBottomViewPadding: maintainBottomViewPadding, child: child, ); } diff --git a/packages/stream_chat_flutter/lib/src/misc/stream_modal.dart b/packages/stream_chat_flutter/lib/src/misc/stream_modal.dart new file mode 100644 index 0000000000..19269ebd9c --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/misc/stream_modal.dart @@ -0,0 +1,61 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart'; + +/// Shows a modal dialog with customized transitions and backdrop effects. +/// +/// This function is a wrapper around [showGeneralDialog] that provides +/// a consistent look and feel for modals in Stream Chat. +/// +/// Returns a [Future] that resolves to the value passed to [Navigator.pop] +/// when the dialog is closed. +Future showStreamDialog({ + required BuildContext context, + required WidgetBuilder builder, + bool barrierDismissible = true, + String? barrierLabel, + Color? barrierColor, + Duration transitionDuration = const Duration(milliseconds: 335), + RouteTransitionsBuilder? transitionBuilder, + bool useRootNavigator = true, + RouteSettings? routeSettings, + Offset? anchorPoint, +}) { + assert(debugCheckHasMaterialLocalizations(context), ''); + final localizations = MaterialLocalizations.of(context); + + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + + final capturedThemes = InheritedTheme.capture( + from: context, + to: Navigator.of(context, rootNavigator: useRootNavigator).context, + ); + + return showGeneralDialog( + context: context, + useRootNavigator: useRootNavigator, + anchorPoint: anchorPoint, + routeSettings: routeSettings, + transitionDuration: transitionDuration, + barrierDismissible: barrierDismissible, + barrierColor: barrierColor ?? colorTheme.overlay, + barrierLabel: barrierLabel ?? localizations.modalBarrierDismissLabel, + transitionBuilder: (context, animation, secondaryAnimation, child) { + final sigma = 10 * animation.value; + final scaleAnimation = Tween(begin: 0, end: 1).animate( + CurvedAnimation(parent: animation, curve: Curves.easeOutBack), + ); + + return BackdropFilter( + filter: ImageFilter.blur(sigmaX: sigma, sigmaY: sigma), + child: ScaleTransition(scale: scaleAnimation, child: child), + ); + }, + pageBuilder: (context, animation, secondaryAnimation) { + final pageChild = Builder(builder: builder); + return capturedThemes.wrap(pageChild); + }, + ); +} diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 7aeeffb15d..47ede68d4e 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -90,6 +90,7 @@ export 'src/misc/info_tile.dart'; export 'src/misc/markdown_message.dart'; export 'src/misc/option_list_tile.dart'; export 'src/misc/reaction_icon.dart'; +export 'src/misc/stream_modal.dart'; export 'src/misc/stream_neumorphic_button.dart'; export 'src/misc/swipeable.dart'; export 'src/misc/thread_header.dart'; diff --git a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart index 75d0a92c71..e6960c0712 100644 --- a/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart +++ b/packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart @@ -18,7 +18,7 @@ Message createTestMessage({ MessageType type = MessageType.regular, int? replyCount, }) { - return Message( + final message = Message( id: id, text: text, user: User(id: userId), @@ -36,6 +36,15 @@ Message createTestMessage({ _ => null, }, ); + + var state = MessageState.sent; + if (message.deletedAt != null) { + state = MessageState.softDeleted; + } else if (message.updatedAt.isAfter(message.createdAt)) { + state = MessageState.updated; + } + + return message.copyWith(state: state); } const allChannelCapabilities = [ From dfa6170f80830b59acdfc1071963e975bd35e231 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 7 Aug 2025 01:01:24 +0200 Subject: [PATCH 29/34] chore: fix lints --- .../test/src/client/channel_test.dart | 244 +++++++++--------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index 906d46de33..9fd0662e36 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -6612,19 +6612,19 @@ void main() { group('retryMessage method', () { test( 'should call sendMessage with preserved skipPush and skipEnrichUrl parameters', - () async { - final message = Message( - id: 'test-message-id', - state: MessageState.sendingFailed( - skipPush: true, - skipEnrichUrl: true, - ), - ); + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ); - final sendMessageResponse = SendMessageResponse() - ..message = message.copyWith(state: MessageState.sent); + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); - when(() => client.sendMessage( + when(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, @@ -6632,177 +6632,177 @@ void main() { skipEnrichUrl: true, )).thenAnswer((_) async => sendMessageResponse); - final result = await channel.retryMessage(message); + final result = await channel.retryMessage(message); - expect(result, isNotNull); - expect(result, isA()); + expect(result, isNotNull); + expect(result, isA()); - verify(() => client.sendMessage( + verify(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, skipPush: true, skipEnrichUrl: true, )).called(1); - }); + }); test('should call sendMessage with preserved skipPush parameter', - () async { - final message = Message( - id: 'test-message-id', - state: MessageState.sendingFailed( - skipPush: true, - skipEnrichUrl: false, - ), - ); + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: false, + ), + ); - final sendMessageResponse = SendMessageResponse() - ..message = message.copyWith(state: MessageState.sent); + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); - when(() => client.sendMessage( + when(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, skipPush: true, )).thenAnswer((_) async => sendMessageResponse); - final result = await channel.retryMessage(message); + final result = await channel.retryMessage(message); - expect(result, isNotNull); - expect(result, isA()); + expect(result, isNotNull); + expect(result, isA()); - verify(() => client.sendMessage( + verify(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, skipPush: true, )).called(1); - }); + }); test('should call sendMessage with preserved skipEnrichUrl parameter', - () async { - final message = Message( - id: 'test-message-id', - state: MessageState.sendingFailed( - skipPush: false, - skipEnrichUrl: true, - ), - ); + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: true, + ), + ); - final sendMessageResponse = SendMessageResponse() - ..message = message.copyWith(state: MessageState.sent); + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); - when(() => client.sendMessage( + when(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, skipEnrichUrl: true, )).thenAnswer((_) async => sendMessageResponse); - final result = await channel.retryMessage(message); + final result = await channel.retryMessage(message); - expect(result, isNotNull); - expect(result, isA()); + expect(result, isNotNull); + expect(result, isA()); - verify(() => client.sendMessage( + verify(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, skipEnrichUrl: true, )).called(1); - }); + }); test( 'should call sendMessage with preserved false skipPush and skipEnrichUrl parameters', - () async { - final message = Message( - id: 'test-message-id', - state: MessageState.sendingFailed( - skipPush: false, - skipEnrichUrl: false, - ), - ); + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ); - final sendMessageResponse = SendMessageResponse() - ..message = message.copyWith(state: MessageState.sent); + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); - when(() => client.sendMessage( + when(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, )).thenAnswer((_) async => sendMessageResponse); - final result = await channel.retryMessage(message); + final result = await channel.retryMessage(message); - expect(result, isNotNull); - expect(result, isA()); + expect(result, isNotNull); + expect(result, isA()); - verify(() => client.sendMessage( + verify(() => client.sendMessage( any(that: isSameMessageAs(message)), channelId, channelType, )).called(1); - }); + }); test( 'should call updateMessage with preserved skipPush, skipEnrichUrl parameter', - () async { - final message = Message( - id: 'test-message-id', - state: MessageState.updatingFailed( - skipPush: true, - skipEnrichUrl: true, - ), - ); + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.updatingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ); - final updateMessageResponse = UpdateMessageResponse() - ..message = message.copyWith(state: MessageState.updated); + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(state: MessageState.updated); - when(() => client.updateMessage( + when(() => client.updateMessage( any(that: isSameMessageAs(message)), skipPush: true, skipEnrichUrl: true, )).thenAnswer((_) async => updateMessageResponse); - final result = await channel.retryMessage(message); + final result = await channel.retryMessage(message); - expect(result, isNotNull); - expect(result, isA()); + expect(result, isNotNull); + expect(result, isA()); - verify(() => client.updateMessage( + verify(() => client.updateMessage( any(that: isSameMessageAs(message)), skipPush: true, skipEnrichUrl: true, )).called(1); - }); + }); test( 'should call updateMessage with preserved false skipPush, skipEnrichUrl parameter', - () async { - final message = Message( - id: 'test-message-id', - state: MessageState.updatingFailed( - skipPush: false, - skipEnrichUrl: false, - ), - ); + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ); - final updateMessageResponse = UpdateMessageResponse() - ..message = message.copyWith(state: MessageState.updated); + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(state: MessageState.updated); - when(() => client.updateMessage( + when(() => client.updateMessage( any(that: isSameMessageAs(message)), )).thenAnswer((_) async => updateMessageResponse); - final result = await channel.retryMessage(message); + final result = await channel.retryMessage(message); - expect(result, isNotNull); - expect(result, isA()); + expect(result, isNotNull); + expect(result, isA()); - verify(() => client.updateMessage( + verify(() => client.updateMessage( any(that: isSameMessageAs(message)), )).called(1); - }); + }); test('should call deleteMessage with preserved hard parameter', () async { final message = Message( @@ -6812,9 +6812,9 @@ void main() { ); when(() => client.deleteMessage( - message.id, - hard: true, - )).thenAnswer((_) async => EmptyResponse()); + message.id, + hard: true, + )).thenAnswer((_) async => EmptyResponse()); final result = await channel.retryMessage(message); @@ -6822,43 +6822,43 @@ void main() { expect(result, isA()); verify(() => client.deleteMessage( - message.id, - hard: true, - )).called(1); + message.id, + hard: true, + )).called(1); }); test('should call deleteMessage with preserved false hard parameter', - () async { - final message = Message( - id: 'test-message-id', - createdAt: DateTime.now(), - state: MessageState.deletingFailed(hard: false), - ); + () async { + final message = Message( + id: 'test-message-id', + createdAt: DateTime.now(), + state: MessageState.deletingFailed(hard: false), + ); - when(() => client.deleteMessage( + when(() => client.deleteMessage( message.id, )).thenAnswer((_) async => EmptyResponse()); - final result = await channel.retryMessage(message); + final result = await channel.retryMessage(message); - expect(result, isNotNull); - expect(result, isA()); + expect(result, isNotNull); + expect(result, isA()); - verify(() => client.deleteMessage( + verify(() => client.deleteMessage( message.id, )).called(1); - }); + }); test('should throw AssertionError when message state is not failed', - () async { - final message = Message( - id: 'test-message-id', - state: MessageState.sent, - ); + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sent, + ); - expect(() => channel.retryMessage(message), - throwsA(isA())); - }); + expect(() => channel.retryMessage(message), + throwsA(isA())); + }); }); }); } From 8376c94fcd2442a6f90d86a7fbbc6d723bf76288 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 13 Aug 2025 14:29:37 +0200 Subject: [PATCH 30/34] chore: merge fixes --- packages/stream_chat/example/pubspec.yaml | 2 +- packages/stream_chat/lib/src/core/api/responses.g.dart | 2 +- .../stream_chat/lib/src/core/models/channel_state.g.dart | 8 ++++---- packages/stream_chat_flutter/CHANGELOG.md | 4 ++++ packages/stream_chat_flutter/pubspec.yaml | 4 ++-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/stream_chat/example/pubspec.yaml b/packages/stream_chat/example/pubspec.yaml index 12656250cd..96f41d89a7 100644 --- a/packages/stream_chat/example/pubspec.yaml +++ b/packages/stream_chat/example/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.4 + stream_chat: ^10.0.0-beta.5 flutter: uses-material-design: true diff --git a/packages/stream_chat/lib/src/core/api/responses.g.dart b/packages/stream_chat/lib/src/core/api/responses.g.dart index 3ec82dafd8..adfa731942 100644 --- a/packages/stream_chat/lib/src/core/api/responses.g.dart +++ b/packages/stream_chat/lib/src/core/api/responses.g.dart @@ -500,7 +500,7 @@ UpsertPushPreferencesResponse _$UpsertPushPreferencesResponseFromJson( {}; GetActiveLiveLocationsResponse _$GetActiveLiveLocationsResponseFromJson( - Map json) => + Map json) => GetActiveLiveLocationsResponse() ..duration = json['duration'] as String? ..activeLiveLocations = (json['active_live_locations'] as List) diff --git a/packages/stream_chat/lib/src/core/models/channel_state.g.dart b/packages/stream_chat/lib/src/core/models/channel_state.g.dart index b92467577a..3f1efb4d1b 100644 --- a/packages/stream_chat/lib/src/core/models/channel_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/channel_state.g.dart @@ -36,9 +36,9 @@ ChannelState _$ChannelStateFromJson(Map json) => ChannelState( ? null : ChannelPushPreference.fromJson( json['push_preferences'] as Map), - activeLiveLocations: (json['active_live_locations'] as List?) - ?.map((e) => Location.fromJson(e as Map)) - .toList(), + activeLiveLocations: (json['active_live_locations'] as List?) + ?.map((e) => Location.fromJson(e as Map)) + .toList(), ); Map _$ChannelStateToJson(ChannelState instance) => @@ -55,5 +55,5 @@ Map _$ChannelStateToJson(ChannelState instance) => 'draft': instance.draft?.toJson(), 'push_preferences': instance.pushPreferences?.toJson(), 'active_live_locations': - instance.activeLiveLocations?.map((e) => e.toJson()).toList(), + instance.activeLiveLocations?.map((e) => e.toJson()).toList(), }; diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index b2ea45e736..c6daa911fb 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.5 + +- Included the changes from version [`9.16.0`](https://pub.dev/packages/stream_chat_flutter/changelog). + ## 9.16.0 🐞 Fixed diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 3082b7d5b3..b0ce12f458 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.4 +version: 10.0.0-beta.5 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -55,7 +55,7 @@ dependencies: rxdart: ^0.28.0 share_plus: ^11.0.0 shimmer: ^3.0.0 - stream_chat_flutter_core: ^10.0.0-beta.4 + stream_chat_flutter_core: ^10.0.0-beta.5 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 thumblr: ^0.0.4 From b138da2d0767d4765a7ebe9dc8eaadfedfff67dd Mon Sep 17 00:00:00 2001 From: xsahil03x <25670178+xsahil03x@users.noreply.github.com> Date: Wed, 13 Aug 2025 12:43:45 +0000 Subject: [PATCH 31/34] chore: Update Goldens --- .../ci/stream_poll_creator_dialog_dark.png | Bin 18784 -> 18825 bytes .../ci/stream_poll_creator_dialog_light.png | Bin 17817 -> 18318 bytes ...m_poll_creator_full_screen_dialog_dark.png | Bin 13761 -> 13929 bytes ..._poll_creator_full_screen_dialog_light.png | Bin 13647 -> 13825 bytes .../ci/stream_poll_creator_dialog_dark.png | Bin 18784 -> 18825 bytes .../ci/stream_poll_creator_dialog_light.png | Bin 17817 -> 18318 bytes ...m_poll_creator_full_screen_dialog_dark.png | Bin 13761 -> 13929 bytes ..._poll_creator_full_screen_dialog_light.png | Bin 13647 -> 13825 bytes 8 files changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.png index d35fd3f84e347101d3a817ebf992a1f9b07b2b64..e2c8fddfcf0c927e659c8997c836e806fc236b8d 100644 GIT binary patch literal 18825 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 literal 18784 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 K)r?bSzy2@P1IiQt diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_light.png index 21658c02925a16099056f76f114d789711b7498f..4b88ae986c303d28ad5399e0211afec800ca0946 100644 GIT binary patch literal 18318 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 z%0DROAC&SBO8Ez+{Ff*t!^=7Y2x1a||1SXg4|@4OmR|k`g699X#jsKfL46HnROxHt zdIM$DjXGm$mp|&7YsI;Ihp(J3!$Fcyg(DbteaFPA^WWa_kbVL|^}a|Y z(~E4-lZVzrBYJ;RrQSXcR(+v63xS@?8?V1CLPh{Gki7ysN;zqSi{tN%s=B^-HuOLF)P!-_>r7ny`4f=O^h7 z=yiM>EnL;2lKJu9uS>vU`0cKSQEmB+L5c(@0Xq6IApAs>nvm=DHYcf`LO`qrRZtZE zjI~)MpcV}Ua2juPt`4G{&eMu&O%w+?#mgjKE$v0efUjE3XO+9pQLC`z_CJ}h(m@~Y zk1iN)cAM}9mG|NA+e5nWf;^V&&LQZrxJSLc#idJM5k;NK(IRg5gzY}QcMtx8&` zw}7s0Cla+$wsx7{g>H3U+-xJUp_33uonP&5>AD#SH&CnrBcJI;iBfP>1#TgH>opu* z!6Y~|#G1Jv70XuMiC50?x>c1<%fg2U70G*Jc>+r_utDV>%cWcj;+u4a;9CQa&5lN~b&nIhXGqX@$M>+LaqB>6c9Z{J#LEM1bu8 literal 17817 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 J&N-{!{s&_xP|N@T diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png index 174d489c6322cae82a170bad1190c484addf1d86..60157c6ef97f662ac0ed6ad53c6d3602341b117c 100644 GIT binary patch literal 13929 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 literal 13761 zcmeHNc|4SB`@cmbQKxjs+FN7`9eX2@qK2|ejD0Ihp_1Li5K&|aNn*&>V2myMuELRJ z>_*lSLzao`2JbWaectn)_jk^FdVlZd^ZRS&AMWS5pZmG)>-v7L`+Hya6Re|kk##TE zUH||q{L%#k0CWie&_CV72wiy=7U%>0p>si8R0TP0JX27E!9^9Ww+H%p@3DRaz)=9d za8A!NVRmTXj)@(byuF`;LnP{$pfQul?K7u;Jw$0(wq$hEZH%M%UkeH4Rh+$Y-DdD| zR9Fg;xZS|GT))M%+|bZaE&M7vbpPE~Sb?)?HSQm7CiJTCQgnoz6W+NWG%2_qmm)HM z)cG#n$4czL8HB2r5+wvNoXc(Y#Je|@yE^~pq^0b46XGMm48ZUzy>15mUe}2>UZ28t z!zEJE7jj>?sX6wbi0q-@oR(iC?%;(0cp}QIEi^tY6cDiPyDo*>qEz%`opAVulCu}# zU7GM>sH5}a(}jD&iteYLcLFaTmWFD*YD}U2+gKXXcAxJt8@0#hV=xZXNf-kYKy|Bs zzf>Igz1OX$lLvT!A(Nb{>mD|ceP~*V+O0QoiHFyp9!$5O!l)y--B410I0|ZEMZ?s` zEO|||JN~8s^4jpR)W?aS_q;2mlzy;szAQe@yO~n5y*#p{yhYkJp1ui)D$pdb$1DhJ zY#JVgUxXf3o8UE~*gh}7GM{pVC-J;L!Ui0VR(ZdojvQdbg(2IZgs4`?y{w;{5xd

W)+1_f`Pz6+-DJs_7%Ust#a?D<1(s z^-;Xdme&2Fn$kq8vD=cEj_PZ=x&mg7-3GGA!Hu0^oo3xL+!dd`K$vx!L}Klj7}?b# zr&^Ou5%hj{;)=>oKb3}NIT{7mZn8$ew}(g4u-2VjWy0NcPbG8pI;}VBBy%y5x%Qvp z2^Lf1s=!KkjkZ_Pu4!l%le!yIMpRQ~+Pa z4X&gwPCM2l9`XD-;tC69i|q!ZCZZw7dZt;j^ttUz&SOHO!uf9HQO0GdQvhu1$g_I_!E$`D1a25YJ zB{WrN8}Q6_U{>E}>oHPu>cQgnE672k+%kuleImaWO4_=XrZIxaOM}f0C%FJ{O?&ax zwLw$qtLiRjqLYRRRCv{9ow-4sgk=w(02LQsRgm1&5PMqUf+2K*cbzw>w~rQUQ4s;O zysuK5wQ;#rr~`!}#7?tpeCMv&U0+wCI2UNwe_U}{NZ={Lj>_`@KW1p) zQ|F*zPEf~y2nL=XRRG`+^j=H;@&RcC;Jux z_`?JdzT^lj>EY=cPbJwgVI%>Cen<1T z%QcUa0Z>Yl?8`eW(h1^tvcybMWXRvM9R$Plbz63v+tI+ zgVJuWid-GpCXpOa-fjQK$p0=BKZGGDUcznQZR-BAcvkSzZm8N#sh4#6FG9!r$c-uN z^DzZ0&W1z=@UkS(YCnU}4cY73yFmMZF+PxZ{T*AIYAV-`Q+hK9jeN)5onEvC9h1P( z)dn37N{+@EY5mOFLTD}LWCZO26LW*^QsL2~GV!buc)D7~?i+fC8E&I-9>ph7=$w{a zyP)iC+`3zz^uDd(@usK$#`rqZ)7HbLY|P*kGPf-giBsV1@^TVrTImwq$JYFp?1h-F!pSO;F*nRDWgXRH(Od`h(a~4+Wq?e#9Oa`C(Rtg~d&%Imw{22Vzy; zBM0*zCE0)O>K}^7?>jx<_wW-A8Ei>=xU{l@L*npDGQiSoY~PP$f&bRP3#y31-e@Qx zdnZ84*S}9V@=Pn0X$70R)4Pnk%s&m^QU-qJ2h<|p$2ZO=cG-jzMU%7 z3XnGBiAmC^;9>)LLH0c%&;xd3r%hzqErbtpL*Q`Ur2o?V8DjbGC@o+iEE+TCBK0hK z)Y_S1OAolOs>WR&Zn~5oFt$;BCSt$~Sf*;M*nIYCB96V2P&*-iUCis>wl-@3kFH6{lVJ{ zN!wk<+H?T6P_s=ST!}D{7@GOATAwU##=DLFOXvQ#ar|xZV20}^&;?!Ocb4Y{Dui;M zX;e1BCFoBVny+Cg!l6ox(AwjjdTQqWXz6n**NXyl+2k<2M&`RQw%KqUf-dCyuwbbbN@w%^g|CM%?{ zzIYp1acN)BZNvVa(q?#P5*(5YJ_uvj-?2xE>d7b z8+S_KBw?%?0SvXF6qDsLCy^@N6Ek}9z4bQ@tn|X>(}NHqAp}<)4LKHQWn!hMbD*%> zULvE%c=E%1ITsHAKi_R-`S;7}*NW4g$3BV-#p=Q^`kgD|UU0#KgA`^^WjWtK_zmK2 z$3i&m!k6F*OQqBvNQUGrB&}KrG2Nz< zA6pgsMYw=mxN%Vm>Q-C7XWP%Li#E>hphf73>9*gx6cz2vTB1EzZ>#8?)#{(2UEsy> z7Sfkms&S$5?Ta%?3Up2+2PEM2O0ZavVZGLwNccX6oJ7$QDk< zUfW68P)pHJrj|7kc*(NAX;*pR zoqK<-NPZZ@*IJVvzWsIvj1Js~wC*1%oJYI~)Qrdg+Fz##Z-snXt+O(c29BP|0pxXJ z9kV}j1`avHL~+lxh@TV{@V%7^ z6||nI8IZ_%##BTKhv;D>6^}H-oj%Og_CJ8&lM1syayBSeL^g9Pb8yM_IJo3M+{w;| zViu_0+V9B>*UAk{-;jFG5%lzufGHabICW4hazac{h-LRPXFeYILS@=Ii&}cuk-qcv zpgg1BF#|@Lllp)#V{S{)%hE=R;`KzuC8wIdMJ233G%*?%b{e`qB1?~=bNA|?JI0J$M5eH&`&q$cihFw}#T0(-fCB%3my>fD9i#*$9x?zC8H2fue+96 zh=bVckkMnRGu{^ZdOks%Yf_Rum=)TsWx6IU1g1cj7=+?m#iFM?eqo1ppNlr@F|Fg6 z&~X8UIG&n*P^%u(RK6Atp?U;j?qD0V4#beW7I?E^;btM1Zy#M2fTG)4ACnEGc5O0m=}Vb8r&PUpSMVV7?sG3~UuU`x%$~KWPSS&6 zkWy1(h&0V4)6RIT7ECEfGv9-Ylh5bZAxL-fav$OA_(&3BFMgXdqt+X&CkjcC_Q*qx zZWXQrQ^b-xW)VwXknH~@9U)TXx~jHh=WH(*AC-1%pm-|sA%AZ#-Xx~kCWb(YxqJe{ zS2A?l0gW~~;8Z&!}?(TM8q>%*>ns5Dn{zko+JH_b!KQ+D!|`jjooxboF> zL?p@ULy-$M(eqkFLI2E)7OXLTYOu^@-N_kY#VKm>>$If#W|?jCIPrS!#%PPTmv}FU z&QkDre2JSI1v4^`yy?3dn$`0n=;1@xueEfCAI~lGJx(>1n4XOma@%l+Z*FeFHusY! z-#(7cZwTe)K|(uCdZJXh(FWREUT&ZyVmdH5I59X(;P7L$s#Cut&o}a2Ei&$@=2uP? zkC)G#N}!sHfMI%@ANsyB#=pAA@1w`GpXUjAWjMuRWMyg4g-Q18*&OIjtna#XdY3~9 zP8li-=%dE#WA!riWTehy(-Y<_rl-79H#g8JA3y$0U-WR*!Y54!xrkv+DX^HAFMeG^ z=&F6m0L=62G{N!qU}sq8l&mE&{{FsyH_c-(Yya_V0x9Jp0=Z&?ZBImT+XI!b@# z%9YHH8yOupZrIyva7cK+Janfr`L*51RnDLj-}tz=I&;hvd+du`SJ#-MuMbCz0+oj$ z0RdTk(;C>TC};Ap&4{$Lbn5Yo5nm{4-$GJiIOs0wrui!Snm2~mLcNCV&wzjvo7vx${CO`F=tDC^t)z%|eIIa>54rzbLJ#t(Dv?see zd6bY$B}!(drAzoICvDu_m+vcAaBZ$k%%MnMsDf#-{mmPH0g)tv_ctKEO%2S;AqMdpo66|atfc$YbZ~Y&`qtl*fy8xkVZx}h)M>BYU?;>|pvz{a6+PxWUp~x+ z_%{2YNP3w9%U4)Ij!q;y;-H=P%kxR*Rn9A9Y;3GgmEp-R!Akd#N^`?i+S#R7!X0AC zt(%|HBQA%Ruv6{aoS3N*j=Thg`U|dAfn0KLg>3KYS~&L0#f$2TZ}};;A5R*{DJtSJ zr*3*BVtpyC%5gj{B2-gFW1HVwONXRf+IF8CEFi-L4!%%WtVG{gnaf2!z%N!0Rd_gD z`_$f7O-O%D-oy!rM7Meuy&FJ~b3fAi@h#wLHXW2o$bM(nK3|Q|NVoCey>uday(1#A zdv&$+grruMUO9Q5AztogBU?q|p~>OITd|TBNU6B)`5Ks&`(Qeiac?;Kav^DhOdW2I zlO|8LCzA|J=Vj%J>t#g6nEh3-gv#Uag{Z_=udsdAeAHT${(AHA+$*)wmul8x3i`8iOv_SAhEXQx4rDJCqBSAn zRLGBX#)ug_Z606zl7Bp_MZeeaEEHP4T9So#jz!G|L6m)Ox%YTTcnw;0yr30*10x*U z40ETrnN^|m169unZEqFc9yZ?E`kNRtJYTN+$p7S7O#d0FEQ75@L5Td2v&|Ge>kH@CUke}5^oFL1YUiI-e%V;FQCj%`dvs5?qZ~$g zv1P?4z3Zl6G+a#=T13#<^4e9ii=0$;`URKPS;cUHm-O@e#Ge%va?qi>z+w(nmNSTN zkgm}K$0Fl-`HfKCgg|xKofQqQn-rm>K11D9tC=F{{aD5Jofk5Aop6%tc~ZRFFZ;kt zrq-ddS!*7lx|?#`rp8c@jE)S^J%bb^+0kf`Vj8!b0p#5;e8G~{RyKe?x*V3Y(!8`^ zI9{xj=OD1mHpg7WPb}*)wgnuAS0^E@oD35iebPZ*;sdLUGQ|>%nYu}qSe?<+rimCW zyU!aUf>4PEswiC5u-U{iefBhFbp7AMZOrI~<#W+tp*&nHpDo_zI!j;d7d@ zpeYNQvY;sonzEoN3!1W^DT_Z+7JiL&`~V!bpneNLQyH}S1+9KTt6$LS7qt4tPMw%m zzo6AG{^fXtR==Q~jL=R-XeT4IlM&j<2<>Eqb~5tEU&j3S2g1<#(_eo@OzZSxUt81s lMDx=Rewa^#%Ksx&R%<@BJm;0^?`H?l53Z(lAxG8H|L^S@BW?fy diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_light.png index 374dd587d2121a09f14a9adab6e827facdea9f57..8930fb31b02459d6d85a16411e31dd9a2c8d9134 100644 GIT binary patch literal 13825 zcmeHtcT`i^+WtXQM!di%ienHM6+w|QDowgn=}1SKqVy`g2Sr3gKtVt{i1ZRM6d{m+ zh=@pUQWH9%B=k=5+lQICZQU~WuJ4a;{np2FfjMVqpMCaz%kw<%8>Xe9#6XXrhaiYS z`KG)!1kofz5bdiU4udOk5g`HK4~?6)k}Oo*dWHx-9CVXa*8Kte`2TSKDFpotDa+r` z^-f+GHgz$XPQh=Pl$obkdA}Y!bnESBP8n77T;BH+c?i^{XUk^u3fi$> z6{gOGH74lt^yk;y6c!gxy^k)7Ezq5``y3~4f6?#0akqk<?=cb2$V>0NxF zN2E#b=KS-|=zhHbYHlrc-5$^viM{jO_112(u|fhtx_lfl3{yr zI)#rGud5?w3huJNcgK0e!f;eS59t+$VfpKV`R#v}XP<(Hdw-EA>^Lh5E&k~HQzjTsIJ@>v0Zdsd zH-GmTBY0ToQ2lXuJ_f?wry3V$Sfyj~K4AJKWGQ>N9qF}Tj@@^?T~PZSsTyBB>Yh0@ zfub5D5{msmwGG&jrbyqec#zpu8Ilrt80=dF#*=7F9i{e4?*%*0u%@IGP$+pxBJRs$ zhicY>k;Rpo(jHtmFr*=Z;@UX`*c!sDT-=`Yx>i7eY#0gJ_!R(eK;ieS{ zA25Ue3ReSVtZmI4PxUiRPQ2Y?nBz3EIgbonZ0lQ1hIimF3w_8dHBRu4Q`uP9xwn^u z;;H-`Di$S)*GbK%I(q73$@VtB zzIx;Ql3iPA)Ou=GWYHjYRU8}#;`{fOBm~CCt-mcgNf=rFf`HpIu$@>=%+#U8OLtdL z#+1wvZ2WmNwdcPz%$B85_WZWV)aB5sm88k~@~7aO&hrls7d28F(q=U&1g2hp&79~N z7i9*B{npEy^5*@e%H|6s{i`qAbD|csIcH|e=uFJU{{-ydO5S~K40c^eQv8>6Q}dmH zY1M4gLNmYi1o)MeQlf9aGpY|&aT(>v~VKv4QQHscDSIC6`lulhw00fKl~IN|&6cgShW)}QHLA5+#@F>wGOZX#X&3*#58yCAQcyN$gvqET# zI1QwScCXh2*K_k5W*&c?yb8Xd+cWX~C-C?C9k7VngW!L!e+CmUgSqcK0?SZ?zkdXL z=a(Dc>0H2c|Jk50n|2!6j2B4>f*>%sd!BgO1BcN|L^DgLl52`bc{hvrqaao z8Z#s#2V2O$T>KBaXIg__sa&wUn(DgsNF_^Ki0KeynCT)~nC-3B(xMzv-y_a+B(`92 zBAa|lNCatsHFuW;@AB+T$J5@jw;~z0|_cBo2n(n%N!s_NoR5q>+C;)?F-ng>X~5ZbL|19Hrf~)eZ&m(1*&|IXd3@ z)?rzim47^0AvIoyKP{fT^N9|c)fGLX&3XLRo4lr`<>^>mA>e1c7UqaQ=wJWCC-6^> z=^Vm6NbBN+6_*EZOw+|!l^$ONw5auOJ?g)V8Grju@`5waq-%eR8h~68*Zxi1Ik)I0 z%B0N``>M(N>*P@$uu_Q=(4ANifj*AD1Adw~c11|2;Us-XzE`#D$<(3My*E=+w6Au&)#b@>`M!7Pm+88u`;s6UG@qq`o`5NO%LEJZE|EM<;{V2_5(WBR`$FCpJ=rw*(@s40|5!hBjQrpEe0nyXVzxi|Q^bGG` zxpSq-NE6xrcV~`28fe7l;^MmHPf&)S*+E(UP0O;{y3vR$3XNJatn>IC8vqyIQDKT_J8BCFSkQWH;-sS6z3wJx6Mtn#oGx^8%J(QmwpF_QD7zd0Jc!V{a!!~o^K z0Xc&hXQhz8_}o(O5&FxD>(|MZ<$$zJNCrGs76hJW@*kfmWIk)Wr&lAS-2;;9yQcxR z|0bE{I|b_V$Hz8L#x|dt*ind8xv=z|3F;1Qpp(x0i*f6bJ+A5bETVOJF2$I(f0T`^ z1wc5o9rtCvLd8c^zSZB;NjR+)cw89jAM%)e`nlSt@fc^(^GOZ(Cn8Xf5k2TI(Re3eMs~_K)C{`nds!&x=XPtUniF}xB$SA zt~4>r(!R7P3XZ9{@_Nq!s9WF^ZtY<(`o*{_0umJ4|1iGOPz#^12>8Uv!mt>`4GCfi z@UZ$P2Vmph?L`|4{zJr}yB3iayV*Y{U9ff{D74p$8c*)^rI%^=pFtb4ldhF#?gtrH z6z9H zE{KNHA2Q#Py%F*VWl{20JMU8hFuX9Wi*Erwy2)8+D46dpq2FVDxd3qnf>=t9A^zb3 z{bAhrUxb!_6@QKuO%VWGN_d`Qf=$=X(`^AJ+k5d0W5FeM9XB`aQJ1w=Irwn@xteoqHU;rQ*^ zy1b8WnGm4PV-=}2-5_-2SH&YBiTq;I%4{Z-NmqA@_;U3jpVS z+H7nKzVl0s-7DTvUH3km@XmSon?T1vDKDQ)oZ;n4u);{;Ly;fwWY=ccI7ZwzUptX>HLny{RK+ zY!cowP50k(t$<&MGiSOdUmgSVIu4fWwIRtq+}7eu0WQLx9tXFjpu&kRW3PNM%6#{8 zGrzT0R@T-%9UaA)N|CumMMe3Ih27u2Jr7)JHlJ-xxl~qOHoF;i?{)=NsQvYg;Cdb* z$S^oLzDv`5i?yY-H9yBX$4urHu9F){av%KEa@)_Aeq6z77>OjBlN<|-GGY|GRwr1Ie)u_;T56b^rb46U0=QBs@V zreZXudcJ&lnw^~^B(&DQM_OO^EUQ5Ekx=B`Y;{)ksWTCZYeS>;+XXmENh=e!02>gX z!pY3lNU8C8&2bE3w{WIzKljHQnB$r498D=){w0Rpm0pL11O-<^`0jpgY!s4`Djpqe z9>6)LZSOGgoGGR>WP^t+^mi42%VH~Y=c2xdwb24 zmWheCfx9tjGh+?mOhd>*6aKl64dK39u?9lduNyTOQCnq@I6$eN2rv}PV20PykAv;t zalg0vnUterC__3r;&Gs+}NlNN0y^e{Asq$Tu3q_k4T}{x{)Qo!8@W$!+h~V`p zZTO3Vz5!~{tFbLfaeMw2W6Y*!5VzMpoC(E#U_%}>Wv^aaLUm6WWRA{Q&J)Km&k zjCqd%$w^B%DV8&R6N`XkFv!9 zreiGh9imWzFFVDI56sk5I+OeFx>jca3)Qumi!7oKkwtKDQ2np9?kwPOnkgxHy({or;<8!gEgr#8|x0NY;1a9NbNORt47mjK=$Ez z+m}_gkynGL5`Ej1gYOI%U^iddN>Wb}PE@qKfF;khbU7HRs9Vp>_t$1V zYj3Tr9Mu__*_pB z+p6N?;yS??T9#8`K*#8x$)&lhs?8PCLm;H{M?KHg<*{v!oK;=Yc|99-~+~@uMM+-uD;2H`0XT$W~I) z_Dp6}mfsGR&DTmMU}rm-Eee=e$``%~_bGDg>~dD~pM!cTmRoR94L7F#Am<)4Fm|~< zlv!VFvw@(bBww5Hi)o+B*xoxuz;};_J&taA+Y6%3IL0f_+5lt>Ua&O~*Q3LsdUik& z`aAAjFe(Qi59^DrbK{>r=^&}G6tcxBW&Pt(Eil)b+`ulxiRa#*}cMEW9d;4&UNd8Pdy;uV8a&@xnR<%E# zTME+3`8fIlIKXjrb&WV_)Z2VOpY9yn>HIfZgWm8i*!@c}ORt(w>GH(p`&@)-5h3+= zg&OYJIceyx@wEcv-L(;(n1s8G7pP)KKw1hNHu7_~JD(|@Z*BBsPgd*I;To?za~!(E z8>@10c-|?;rjoIB^;znsxeX1LYS4`-uyK0LDbx2mU5K{?AsQndfwwrr* z0m)AMc9uPg7>4EUrv7GZULNIi+frbw>7E=8btlb>f1Q*vZs`GXucL8=-O5x8z&*f4 zpUDq7JvHKG@z@}lTB1|AxITM~PpJp&E`8v<^zx<+A!%=5XVuKQ@jM8va$6>5(tZom z+cOm$m(DQSYdWJC*(K8NUp0!^0>2m-8E2QjJO%TXI}YYg<2I^e&?%u(qO2IP0|6Y6 z{xY#hT#pUuX{U&)@l`>i(X%r)eI4hOx_f)|d+zDmSy?IKHYWuW zK!H2un~%Dh{~HE2HnHWQ(c7BSs%(_j3K;5yg&i>!^~$hX$;ENf%CN0mO@)B~K;@ZA z9R5}-P26dA_wUQ=baf>rZqEmL`T1c62K($c`n>GBvLm?MA{8@zNsD*)dd#VY({y+} zJXY#L^pTi*)DekqQ9pp=tUv}RV#x(4@{zJ~ek3y%fVv^^U<3lO{W0#B@$qqxWcn5t zEf??=ntOY6Cm9W>7CPV|>+{4Oa5-gb&1kP<)LC!u^~QKK0@D4`wu8V576MlOkV3Jf zTDiJvOH-OO-IvB1=t$Cl+IozRDb(zKEl5mGE*vXFTBqY++*%+1L~nJNiueeol^3gT*ZoMd!pbZg4a` ziKvm{Qr`YLrQRGUb!91xpOK-+cPLy=&dU0FxElv%!?^@V^69cM70#*~q)^`J;L99^ zwyadw%EAo+Q+f%UN+C{UqX8Ly0iFy1TV=qeZ?CU34cbeqCZwjCt#}z^ZjB6`qVmPT zdH7;di%N7SarJ$g=Aoyb?MOQZOMX&qgH5)A#mmo(SR=glVX$@&$Qvz@>hOcZ#bvAw zM8&@Y2$9&xxIElrD4}Xhe1As>#v|?1@tLGO8$9ZojNl`GFQKam&*9Z#Jv;+gLNuL+ z!9qqxhV6ZuZu7EqrApR3oHht+sPyviNIc`b|Mmmedl*jQ_F9Lfw6nc^R~;>#zN8b9 zT6eOd>4D?w$WX<`{4c+Q4Ub0s5ZSX4QBg?j>FK?7GCrrZ^=liun21CB2zQ#hXmhN( zrl!5Wg)HEm#$NtC6R%bGF%vI)7ik1l0FYoxU7aPB>jXXVQ+VUrDrJw!tjN~~UW-X4Yuyk?l_O7F^rI%#Um8aSsG zueoDkBvF)?cge%U!;a8DkUR_*rDhw(uCVzL4`p@PMnpsqBSZqv;y3Iiiv$(}%%!P= zB7(xgKo({JLteir88H10Al19WEyP!mNa~@o@^U+O2Q^f+ulBWT!aEsy79gw$;Fj~9 zhCXC~Km$<5l?yseiLIA(&6>>yREMf+b~|Mt?-LW%$r>sCFi`-C(LmQ=0WBT&Rt)#n zg-bC_b}lYj@k)vy3zb?nvjl8}NbBpkZk_sEq-Zd`jIzu<0f*TU%wlRQHbCR((WB9C zNhBwjMkR?j>hr`Fehp3uk-gFHpx)7z6Teb4jR_W4 zu@x_CkF8G2--EiXCY~ALoo&99{h_Pm2qV;;F=v39`#O0UIAYv1-6o`ZrSym?uGx>u*n^$4|a z7^r=3gQvZLmd_q_=}dY5ZC2=xz!^sI%EZZu!{4gnO2hAha!GDcPm6PP4B^xG75*X` z8Cn&tzDk_x($x&eq`b%7^fM^Yhgz7pCQCp?shb3oSz;*LT~3qF>7%5+~?v=Mv*FcZ)vrtgU}X>iQ}EV2)R;#4lY za`LRuDK(+9_O;Roc|^7og=82S#;=r>l>_;qzoBYti?;;Sexut?0ihZIj2OcGnnONE zt7$>eHsUXW#NtOG$i~n}VER6Q3rl6ZDvllyJV0I-O_eju|!(MChG+ zsRfvxk`jj9Z}-ZY#K`#SPyB~QYze&!m%PxROm7I1>-^xf;4bAIAT;VzKSnjK%Hx@5 zk-r%pW?z6KKtZ%}!E$0=>ui&*X+=|@#@Jh4WL)O6Vg)20;I0bioJ2nHvV>RpZ4~dL zR^P|#g*4+YD2cv!m?M&=onT1XM;MZX~ zIuD=w@?hSt$(yx&Muf2$lva)c?{Lo5??d26*d1<2~+LYaMLl3D%zMjq~^uts2K zZ(lHb<+9MVYnkS|%kfoi)+$AgMPh+tuX~G}83e7`3GY-Gpx&RSCs(@+D2gx)A@=9R zYb56;eZQ$~Y@7t730ZNk`S$s5g&Nr1MAyjjT%*e{H~{YNK09%#rKQDoXMI7;cjD=r zj&0*rR-g^+t|*ncO>2N#0B`i!SDic!h>)Hba;ln(ORD2ZBqN&-$)zY~C5sU`JqW{| zPoEz1Cu6kGKHcWgH0hB(r!`?v0BB%GCX*C;Ya&Kd=<3xsc|==v^#D&Crl!VpVPURp zXAVO6j{5pw|WNGUfM7#ITXs=i)YdH@oRz4zw(b@E^iptkg(1;~;-@DRWCRXcFGb$7dv zGP78bANXwt=6*aA(*X?T2z?+@$snokk=L$Y&*Pv@a94RRjnQs!fX;;~m!&r_PgB>> z(0|a2yVj0}G3=;nJD#s1qn;!8}U-S@U< z-ltWRl@SRKX$#mZa8$yx!HEyTzRsjUKhM{{1COeE1)#tH^d@Qi^OeAz4YH24^`tdZ z3ahXUIYv_~dGc#^PL7b&m5iI5Z;HgRcCO#{b&QKFQMO*>K0W^UwN?V*J(8I|#C@z` z+}D>%p)3C3Xo&0p4vEu9_U>?){GNcG=2Win>-8iG=>>AyuqTSUy+(3SQAz1!n7rWPx1jz9upsh| zp6Fq_5MYOT!p}%tC04ACg*O`bQ>*}T&c0<7M&9vVSv8J+n*(~KcpP!E>L%K>K|SKD zp|k_*&1u>eDB9P?iD<7o3L80&RbWB;G^ZE0jWIFKPG90_}k)z;J%SkWhz^0d*&W- z1nV4{dRhxGi(ly)x9idCDO(tHl|S+Q??JsZhkS%Vq6_7%GerCjDAH{ET0x)3? zGMiUeCVWPop@a+z{>(qu7UtGANv5;?Js@Mi$TKMHS2|WJPar(57d#3fQec7n{3pB3 zACEz`iV`eGB@_t+PUgBk&?zx%+*#))0hEiV#uJQ#4n+*myHkvzDJCthuC!LBssjzb z08zcWcXmo-MA>C*>8JQ!P-?lr9Cp$i_wIIU-0QMZL39uVA#Q?B0#)FAqX(oneQ=nB z!uS1$;^jb51?29Yd2cV<>AIJ1ACc`nJVcAqgg}mo zlmLDs4AfHcTtwdj2awl^iJ5G>oM#7A7Q;_iL4cINj{LL66?r`oX|VfW?@LTBABt7U zvSX)*-YJf{7^*M5PE3l?3kY}9W8eMTD)%ixL5+p0dk*tD~{@ ziB)b&sTDuBt?2Sr4U<4ohUewYi-73?DLqP(^4gc3{J{55@dwC)zm=D3<#?wj-Pae~ z5P?WTpwx1?J#D<_`-XgEP5L)uGfi1|h}Cp~Y9D6QolOzniFB=O(|7am^0FW7EgGoy zL2Ku|1ulB-SOu#EOSr;tji13jT7EG6!AFM!DZ#I-!g(CAX@y&ts_E-r0-?2AODevv z&1|PqYI{NHH_#qT#{`zydtWL+O+Pp|xJu&c8!#_`;0%!x2txQL0Q=Kvr8WJlsm2VGjf z|8i3f;`Hf`?$y%lY$*(Wcx0q_eSK|UZ*6#>)HbszIkO`-RoveYxz;D$yH)4aQ-RV9 zyZ>?GJ5GdY<@^EAzqw$Z_L96aJLe}`RMd=rEWi>jw$YmYI(*qWFhC#azGK!V85vF2fS1M-FeDsTn}?y6idvqa)8P=JZ(NaAWV0nt<@L=hFG z9F2YN(*+a)AnyPrqJVv4to=p5QR~=HBWdr~LPYz-!eD33&e`TI!dE)`fzLR=uJ=^q z4}c269JwW6>9@KE0JhPuRI)&EWEqsxv_VGg+a2z)!Tz;kfsTIbE><%?twZysBymUT z2Jh$271(5p8irF1d{OF>Bw-hv)pToboKsBG6h^y@E8_O5E4(%m&EB(wH5dK@j`5A?15wrl1gjv7$_W|He$}LQEgN1I{&TTE&A<AL?o_Dz_NuY(Qp5OVDI^-8<*wYqPa6R>KHGfC zojN<~JhA2G8C-Br>@3@MJ&oh{_Kd-pnC+gV9DB(W0T@Zx+u5mr-9vbn3tNl8=)||g zTdmQ|_Xg4Z_Pu-ee8(fqzijN?)|@-)kMC=vt}_6UA}=dTq0vk%+osU-R5>{4!W(X4 zS>t%*4N$Z|u(5VsMx}Otd)^Xg6Z;y3m1b0RKC6gRE(kP@IHX#W?)z*v`q;kr@$1Jc zoCI)!KSJz>K!F&PHesRwSnB%f`fTk(=k5vRK;^H0Q>*QNuYeC2jp})2LJ4_L(9u)5 zYk!&t2sE`1H~6dfOUxfXKH|*VFC07eOsT_#Aez$SjBXv~!%$*sG?My6PIqu+!2K-b3O!>L4r>PsYd2SAHFX106gs$938 z0Y8}ZIl3(2+|Y+8)cc)tc5kn*`TB40ug%Xs@O=)W&06_iDcGHJaHmG%At<61Zl646 zA>{w`2k6du_V7dO=UrT)!wB{m8fcA=NVuL_3l}TsLmkU|4@2LN{()A)PtQ>1hJ4nl z-)`SdG?D@RY@F;-d0D{uTpn`lR^x}&^!w)@!QEz`LGHHmtj3i7f7eO)pLGwzdhfq& wG5)_nf26*T0FW$!%te~{QtlK=n! literal 13647 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 Lq*b7C;l{rJIi#iO diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.png index d35fd3f84e347101d3a817ebf992a1f9b07b2b64..e2c8fddfcf0c927e659c8997c836e806fc236b8d 100644 GIT binary patch literal 18825 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 literal 18784 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 K)r?bSzy2@P1IiQt diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_light.png index 21658c02925a16099056f76f114d789711b7498f..4b88ae986c303d28ad5399e0211afec800ca0946 100644 GIT binary patch literal 18318 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 z%0DROAC&SBO8Ez+{Ff*t!^=7Y2x1a||1SXg4|@4OmR|k`g699X#jsKfL46HnROxHt zdIM$DjXGm$mp|&7YsI;Ihp(J3!$Fcyg(DbteaFPA^WWa_kbVL|^}a|Y z(~E4-lZVzrBYJ;RrQSXcR(+v63xS@?8?V1CLPh{Gki7ysN;zqSi{tN%s=B^-HuOLF)P!-_>r7ny`4f=O^h7 z=yiM>EnL;2lKJu9uS>vU`0cKSQEmB+L5c(@0Xq6IApAs>nvm=DHYcf`LO`qrRZtZE zjI~)MpcV}Ua2juPt`4G{&eMu&O%w+?#mgjKE$v0efUjE3XO+9pQLC`z_CJ}h(m@~Y zk1iN)cAM}9mG|NA+e5nWf;^V&&LQZrxJSLc#idJM5k;NK(IRg5gzY}QcMtx8&` zw}7s0Cla+$wsx7{g>H3U+-xJUp_33uonP&5>AD#SH&CnrBcJI;iBfP>1#TgH>opu* z!6Y~|#G1Jv70XuMiC50?x>c1<%fg2U70G*Jc>+r_utDV>%cWcj;+u4a;9CQa&5lN~b&nIhXGqX@$M>+LaqB>6c9Z{J#LEM1bu8 literal 17817 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 J&N-{!{s&_xP|N@T diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png index 174d489c6322cae82a170bad1190c484addf1d86..60157c6ef97f662ac0ed6ad53c6d3602341b117c 100644 GIT binary patch literal 13929 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 literal 13761 zcmeHNc|4SB`@cmbQKxjs+FN7`9eX2@qK2|ejD0Ihp_1Li5K&|aNn*&>V2myMuELRJ z>_*lSLzao`2JbWaectn)_jk^FdVlZd^ZRS&AMWS5pZmG)>-v7L`+Hya6Re|kk##TE zUH||q{L%#k0CWie&_CV72wiy=7U%>0p>si8R0TP0JX27E!9^9Ww+H%p@3DRaz)=9d za8A!NVRmTXj)@(byuF`;LnP{$pfQul?K7u;Jw$0(wq$hEZH%M%UkeH4Rh+$Y-DdD| zR9Fg;xZS|GT))M%+|bZaE&M7vbpPE~Sb?)?HSQm7CiJTCQgnoz6W+NWG%2_qmm)HM z)cG#n$4czL8HB2r5+wvNoXc(Y#Je|@yE^~pq^0b46XGMm48ZUzy>15mUe}2>UZ28t z!zEJE7jj>?sX6wbi0q-@oR(iC?%;(0cp}QIEi^tY6cDiPyDo*>qEz%`opAVulCu}# zU7GM>sH5}a(}jD&iteYLcLFaTmWFD*YD}U2+gKXXcAxJt8@0#hV=xZXNf-kYKy|Bs zzf>Igz1OX$lLvT!A(Nb{>mD|ceP~*V+O0QoiHFyp9!$5O!l)y--B410I0|ZEMZ?s` zEO|||JN~8s^4jpR)W?aS_q;2mlzy;szAQe@yO~n5y*#p{yhYkJp1ui)D$pdb$1DhJ zY#JVgUxXf3o8UE~*gh}7GM{pVC-J;L!Ui0VR(ZdojvQdbg(2IZgs4`?y{w;{5xd

W)+1_f`Pz6+-DJs_7%Ust#a?D<1(s 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 diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_light.png index 374dd587d2121a09f14a9adab6e827facdea9f57..8930fb31b02459d6d85a16411e31dd9a2c8d9134 100644 GIT binary patch literal 13825 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 wG5)_nf26*T0FW$!%te~{QtlK=n! literal 13647 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 Lq*b7C;l{rJIi#iO From 2b8a21eb49899aa88e1ac62f0737933d94be7f9b Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 13 Aug 2025 15:12:34 +0200 Subject: [PATCH 32/34] chore(repo): release v10.0.0-beta.5 (#2354) --- melos.yaml | 10 +++++----- packages/stream_chat/CHANGELOG.md | 4 ++++ packages/stream_chat/lib/version.dart | 2 +- packages/stream_chat/pubspec.yaml | 2 +- packages/stream_chat_flutter/example/pubspec.yaml | 6 +++--- packages/stream_chat_flutter_core/CHANGELOG.md | 4 ++++ packages/stream_chat_flutter_core/example/pubspec.yaml | 2 +- packages/stream_chat_flutter_core/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/CHANGELOG.md | 4 ++++ .../stream_chat_localizations/example/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/CHANGELOG.md | 4 ++++ packages/stream_chat_persistence/example/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/pubspec.yaml | 4 ++-- sample_app/pubspec.yaml | 6 +++--- 15 files changed, 40 insertions(+), 24 deletions(-) diff --git a/melos.yaml b/melos.yaml index 1df75c7ab8..3eec77ef35 100644 --- a/melos.yaml +++ b/melos.yaml @@ -84,11 +84,11 @@ command: share_plus: ^11.0.0 shimmer: ^3.0.0 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.4 - stream_chat_flutter: ^10.0.0-beta.4 - stream_chat_flutter_core: ^10.0.0-beta.4 - stream_chat_localizations: ^10.0.0-beta.4 - stream_chat_persistence: ^10.0.0-beta.4 + stream_chat: ^10.0.0-beta.5 + stream_chat_flutter: ^10.0.0-beta.5 + stream_chat_flutter_core: ^10.0.0-beta.5 + stream_chat_localizations: ^10.0.0-beta.5 + stream_chat_persistence: ^10.0.0-beta.5 streaming_shared_preferences: ^2.0.0 svg_icon_widget: ^0.0.1 synchronized: ^3.1.0+1 diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index ea25732639..3349d4521d 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.5 + +- Included the changes from version [`9.16.0`](https://pub.dev/packages/stream_chat/changelog). + ## 9.16.0 🐞 Fixed diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index 875d1b58ae..615f2e53f5 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -9,4 +9,4 @@ /// Current package version /// Used in [SystemEnvironmentManager] to build the `x-stream-client` header -const PACKAGE_VERSION = '10.0.0-beta.4'; +const PACKAGE_VERSION = '10.0.0-beta.5'; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index e984cf3c77..adfaed364b 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat homepage: https://getstream.io/ description: The official Dart client for Stream Chat, a service for building chat applications. -version: 10.0.0-beta.4 +version: 10.0.0-beta.5 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues diff --git a/packages/stream_chat_flutter/example/pubspec.yaml b/packages/stream_chat_flutter/example/pubspec.yaml index 0be2b29afe..77cb9f91f0 100644 --- a/packages/stream_chat_flutter/example/pubspec.yaml +++ b/packages/stream_chat_flutter/example/pubspec.yaml @@ -25,9 +25,9 @@ dependencies: flutter: sdk: flutter responsive_builder: ^0.7.0 - stream_chat_flutter: ^10.0.0-beta.4 - stream_chat_localizations: ^10.0.0-beta.4 - stream_chat_persistence: ^10.0.0-beta.4 + stream_chat_flutter: ^10.0.0-beta.5 + stream_chat_localizations: ^10.0.0-beta.5 + stream_chat_persistence: ^10.0.0-beta.5 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 3c3aaea4e6..f404e4b18e 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.5 + +- Included the changes from version [`9.16.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog). + ## 9.16.0 🐞 Fixed diff --git a/packages/stream_chat_flutter_core/example/pubspec.yaml b/packages/stream_chat_flutter_core/example/pubspec.yaml index 564a8c0985..895edf7f5e 100644 --- a/packages/stream_chat_flutter_core/example/pubspec.yaml +++ b/packages/stream_chat_flutter_core/example/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter_core: ^10.0.0-beta.4 + stream_chat_flutter_core: ^10.0.0-beta.5 flutter: uses-material-design: true diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index 43e96aa062..d7b0a6c56c 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter_core homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.4 +version: 10.0.0-beta.5 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -31,7 +31,7 @@ dependencies: meta: ^1.9.1 package_info_plus: ^8.3.0 rxdart: ^0.28.0 - stream_chat: ^10.0.0-beta.4 + stream_chat: ^10.0.0-beta.5 dev_dependencies: build_runner: ^2.4.9 diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 6f9d49fd05..e50ce703b1 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.5 + +- Included the changes from version [`9.16.0`](https://pub.dev/packages/stream_chat_localizations/changelog). + ## 9.16.0 - Updated `stream_chat_flutter` dependency to [`9.16.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_localizations/example/pubspec.yaml b/packages/stream_chat_localizations/example/pubspec.yaml index 75826df164..9186fcfbfc 100644 --- a/packages/stream_chat_localizations/example/pubspec.yaml +++ b/packages/stream_chat_localizations/example/pubspec.yaml @@ -24,8 +24,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.4 - stream_chat_localizations: ^10.0.0-beta.4 + stream_chat_flutter: ^10.0.0-beta.5 + stream_chat_localizations: ^10.0.0-beta.5 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_localizations/pubspec.yaml b/packages/stream_chat_localizations/pubspec.yaml index 5bf46e9cb3..85bd34ec7f 100644 --- a/packages/stream_chat_localizations/pubspec.yaml +++ b/packages/stream_chat_localizations/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_chat_localizations description: The Official localizations for Stream Chat Flutter, a service for building chat applications -version: 10.0.0-beta.4 +version: 10.0.0-beta.5 homepage: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -26,7 +26,7 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - stream_chat_flutter: ^10.0.0-beta.4 + stream_chat_flutter: ^10.0.0-beta.5 dev_dependencies: flutter_test: diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 3bd09b9b1a..d502d510a3 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.0.0-beta.5 + +- Included the changes from version [`9.16.0`](https://pub.dev/packages/stream_chat_persistence/changelog). + ## 9.16.0 - Updated `stream_chat` dependency to [`9.16.0`](https://pub.dev/packages/stream_chat/changelog). diff --git a/packages/stream_chat_persistence/example/pubspec.yaml b/packages/stream_chat_persistence/example/pubspec.yaml index cb18723cb4..8f7b003b2c 100644 --- a/packages/stream_chat_persistence/example/pubspec.yaml +++ b/packages/stream_chat_persistence/example/pubspec.yaml @@ -23,8 +23,8 @@ dependencies: cupertino_icons: ^1.0.3 flutter: sdk: flutter - stream_chat: ^10.0.0-beta.4 - stream_chat_persistence: ^10.0.0-beta.4 + stream_chat: ^10.0.0-beta.5 + stream_chat_persistence: ^10.0.0-beta.5 flutter: uses-material-design: true \ No newline at end of file diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index de7cfc84f0..1a98c140b6 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_persistence homepage: https://github.com/GetStream/stream-chat-flutter description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. -version: 10.0.0-beta.4 +version: 10.0.0-beta.5 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -30,7 +30,7 @@ dependencies: path: ^1.8.3 path_provider: ^2.1.3 sqlite3_flutter_libs: ^0.5.26 - stream_chat: ^10.0.0-beta.4 + stream_chat: ^10.0.0-beta.5 dev_dependencies: build_runner: ^2.4.9 diff --git a/sample_app/pubspec.yaml b/sample_app/pubspec.yaml index 869277a3bc..72ab324fca 100644 --- a/sample_app/pubspec.yaml +++ b/sample_app/pubspec.yaml @@ -40,9 +40,9 @@ dependencies: provider: ^6.0.5 rxdart: ^0.28.0 sentry_flutter: ^8.3.0 - stream_chat_flutter: ^10.0.0-beta.4 - stream_chat_localizations: ^10.0.0-beta.4 - stream_chat_persistence: ^10.0.0-beta.4 + stream_chat_flutter: ^10.0.0-beta.5 + stream_chat_localizations: ^10.0.0-beta.5 + stream_chat_persistence: ^10.0.0-beta.5 streaming_shared_preferences: ^2.0.0 uuid: ^4.4.0 video_player: ^2.8.7 From 0f8a4f51be72face15bcd7748849c9c46f61f1c5 Mon Sep 17 00:00:00 2001 From: xsahil03x <25670178+xsahil03x@users.noreply.github.com> Date: Fri, 19 Sep 2025 01:01:01 +0000 Subject: [PATCH 33/34] chore: Update Goldens --- ...poll_option_reorderable_list_view_dark.png | Bin 5514 -> 5583 bytes ...ption_reorderable_list_view_error_dark.png | Bin 5691 -> 5779 bytes ...tion_reorderable_list_view_error_light.png | Bin 5614 -> 5906 bytes ...oll_option_reorderable_list_view_light.png | Bin 5440 -> 5710 bytes .../ci/poll_question_text_field_dark.png | Bin 1778 -> 1787 bytes .../poll_question_text_field_error_dark.png | Bin 1875 -> 1903 bytes .../poll_question_text_field_error_light.png | Bin 1953 -> 2009 bytes .../ci/poll_question_text_field_light.png | Bin 1811 -> 1874 bytes .../ci/stream_poll_creator_dialog_dark.png | Bin 18782 -> 18824 bytes .../ci/stream_poll_creator_dialog_light.png | Bin 17814 -> 18314 bytes ...m_poll_creator_full_screen_dialog_dark.png | Bin 13765 -> 13933 bytes ..._poll_creator_full_screen_dialog_light.png | Bin 13649 -> 13827 bytes ...poll_option_reorderable_list_view_dark.png | Bin 5514 -> 5583 bytes ...oll_option_reorderable_list_view_error.png | Bin 5614 -> 5906 bytes ...oll_option_reorderable_list_view_light.png | Bin 5440 -> 5710 bytes .../ci/poll_question_text_field_dark.png | Bin 1778 -> 1787 bytes .../ci/poll_question_text_field_error.png | Bin 1953 -> 2009 bytes .../ci/poll_question_text_field_light.png | Bin 1811 -> 1874 bytes .../ci/stream_poll_creator_dialog_dark.png | Bin 18782 -> 18824 bytes .../ci/stream_poll_creator_dialog_light.png | Bin 17814 -> 18314 bytes ...m_poll_creator_full_screen_dialog_dark.png | Bin 13765 -> 13933 bytes ..._poll_creator_full_screen_dialog_light.png | Bin 13649 -> 13827 bytes .../ci/poll_add_comment_dialog_dark.png | Bin 3501 -> 3516 bytes .../ci/poll_add_comment_dialog_light.png | Bin 3457 -> 3528 bytes ...comment_dialog_with_initial_value_dark.png | Bin 4021 -> 4033 bytes ...omment_dialog_with_initial_value_light.png | Bin 3993 -> 4065 bytes .../ci/poll_suggest_option_dialog_dark.png | Bin 3342 -> 3524 bytes .../ci/poll_suggest_option_dialog_light.png | Bin 3272 -> 3431 bytes ...option_dialog_with_initial_option_dark.png | Bin 3908 -> 4068 bytes ...ption_dialog_with_initial_option_light.png | Bin 3887 -> 4018 bytes 30 files changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_dark.png index fc34df7e1c54179c9350bdf963ad5cb39270786a..673a09909d5818fd9da218b9d1ab2d273584ec90 100644 GIT binary patch literal 5583 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 d+G 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 diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_error_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_error_light.png index 920189780fb81bf41ca5703a1656574c0f266785..019061a34f782ef583eca3aa2fb348cc04ddb359 100644 GIT binary patch literal 5906 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 NC(LY2amUfu{|WS}Ay5DS literal 5614 zcmds5X;@QNx88sPRS|6wY@krFDwE>C6qHcCMjRlKAs7%ORg_tfFeo4a5p2PT6hQ?7 z6og1ZLdqaAr+P((5{5_snJZHmL=0nOxI6Kw{n}5zulIYN`{$lN=h^41z1Kc#uXnxg zIzODmn8~d{tN{SX9Xop13IItw020%(((p@AoylFDu6Uv}@9*{Qkq0=T; z0s{R_8)s8##%1rgIb7;nKV$kAfE~3s+8xLxEpqGmy`i%O)4V)V_kwT|wcsqgk=&SF z^{zR#rS@*6-!@`-?l0PT=$O|gwU%=0U?j@!lpVT{gV@iR<2Rea~P-+e#sxbc3> z4|e`c2M~75AoEu#0#<<#VJEp3w7XrssRLIZFRw%=vL!*#PgwDCJtHSX=IN(|8$@O! z6vtSR*>uY;GqIV+De*ol9>u&j?<^8~In$mczW1~zydQT&z8`l4h`sB2?Gt-1ezZyK z-6Jk;W}b_s#+#{ml^=m09;~aCf2;S(4wF#9g>#}QeP16wY-^HM94&IMa??V*%k_2J z)kR^F8K#N1A;bU9*<|*08J}djY@{dh;KO2eKaQ&m5Oho@I4!F$&3T8$qf#*Y9aqre z4MzmL9m(W-7^YdoF1@|WCtZ8L-sC{D8TX6EYP4-C#$_gn6C)A zY1wHjv&EFWmDlmu?5dR^!_|s_?Seimipe}_m$KcngkRTy^ye2tmd5zrD+^97rl>gw z;g~L|L@)#6*hh5OF4`Vj32!LAujc(A`mm;S57EblDVBx%C_pQS0;p=Q^C4SfY_-z!2u9aKFc+KKFRbMT~SIah-cDX{7b_~sYr^xNIg z(*|=GxA%{tETlr;M5uXQ*nWEYZM`nF*|l)O4S?W`DV5w;uQD4NE}TFKM~e9a1J0dX z0A{bBy8iKnKCJ5xXOk5 zHmJ)#j>Bb@GOZo=&q#ogyD7vvGzPt^h2XO=LoJe`GsgU zYf)6N#%SBIyEpwEsRhJKFhLXZb+{c1xm=Wh7w!-3X`i10?EV~@76t3VcwW3F_eT9W z0B+E9=!JNuJ=tp$o~Zm%0s}fV6n?rSRJeD zZ&H>O^4kx3?`8#^snWo+!M*7C)Be6Ed&uE9N8ia-zOre_i<$AnXWU*`8&nDn-nA$@ zZ8XmM3iMffy?nTbHC_dC)F#=Wbg^xn1eo6k)A8$jqHNjD0^ph`T?ij}MDA5z1==6I z%c}~=nyd1E7uoawJ*LL2a`^uJ5{?VnPhv^)OZ3oH$~I0_l@pqP%_)1! zwqI^FWC}L|u>YC%p^tm{;P}y$_r{*GxzTL3l6}z*50oamx@Yx3n06wSYj?FdOeQTQ z67^>4`Niu!d06R)gF!11^2H`{us$U>9`MhaBMBJA`^lsMAwQBd7ro){e4xm6d$nnT z6liK?oGvaliNu6xxkQ9$$$;4i>>vQ1|2{~+Z-3Z8 zM=QE(^QoK()!eCvQx@ug-Q!XA=7kpP)~)S~fM2D+IKAKJ_K~LnF&IXmV_K?;;{^-= z6*vX7F)FE0t#`1x4HL_7hDGxHZjBaxttC}@)bHZAmI{1fQM|1wb`=;Yo4R}lgDutF zt*^>`gHEi+B{eAJFxyI10Kr90CPMH2&9*Z(_WM~Vj}nKhe3}&wcWo_Le-eWnOtGpf zX+1VvwtYComy@FrecRA~%dqavBTx0BA8!O~Ro4AApN_qvulax3g$79{5+QF@)*`76 z12zLY(;{$f{`NYFZqV0p8^{D1HApgCP&JmfEKMAa?;0z`2%hcTsaRj6DhryFUQKCO z@MIYnZ9D{@fUlEqzSTbz2A}}1V{K>4AGqA2nQvd^oI7Srp~Pr|KGvP{_ch4KrCv`Th2e*d=X!<2`c##7m z#cMTq^W20_$8{Jnr%qk>y679nH4F{O8SB_N_yzVsM{!y&Ojd%2Egkp%EZ60Z{urEx z>7B35V!9OTq%Oni+?QU|akpnax=C{afHZgR5pwwXl}&(6eOcH%Sam@bu+uhvqF{fh zbmAKBv8cEOupf1kmWs41Rv4YS*L$!q_4ZFLFSX@OFE@t|ekhjXbxs>Y7oSc#&1`K? z7Yb**uo57kCqahyHm~whYb*fmnrAjjewrynj#*?<%$uHyQ-(`56w3kiip#^VA5kTM z!_NmOoY5HR1M>qq)8VnE0b8d-ukPKvuH~It$YV$+-%fUg4CTNLCVN+OyDe^Q!|E=U z{V#~bU^zzxgfTC6msU(@`u%2&R35NK0+yNxpMj>xBoPGlv69IoC2ahe{HfhOpO zj+bae+u(37Qd%fwx{=*<@910?iS$Y7h@q8XvRZIzqY|WnBOGX7jJXxt;$!sK$Nbzi zi|wy!kPxl5mIKv~k9*A#$Yx~k&n3X@na)V6ZMeUmo?Fp5RX}i(yAh#>cy!v&y<$u_ zJutGDC<#Uw85%89%@3C5cNta&1bJ>-3yd@(4#r`yw~X~qQi)R08AsdlD22i+>fqa6 z^7Bl;pq8uQIaBwdbn_jUEuNJ}{VRB|9PRfo+Wer_xqLRGNZHUK!qbk|70`n7&cqmj4VIe{dkGBq?oo11N6N-KXkJ)qtAwIjY-JQuaQT{{d^dSZcvqlE-{sd_j{8YPp@<^lqk>u>0sF z=}o@~7!^dpeJXQ$*}HNkfI1cHU|R8J^525&FADANr}tkbMkR;#!Nm3w#_i9n2~q^S zOJlqVFYHh8AHeEKEP(PT+>DuaW1&G`6QBX<<6z_toVxzjqRqM#K+RjvdO*D#ppMG4BT^l6Q$ zGjK0z&^JM(GAC4YfYD+3#$SRir`q%mq*(9r)q0!Q_zR7uW#J;QNo>v9Apuz0(J5S4 zJ@Z#nt`qq2kRQufFq@xUK5#r<{}7#vz(e{O57AzKgT7lRR?Y5$xPY2x@KX>4}wPjmHL{`iw# z1nU2Y8UAB%h$gc7v(+Gjok$KH;ArHht`76>D)kTUv>y2eCX_HkLLPaxaN~N(R7ega_J@%(j)2L%jRY@5de^vlWy>OVRTkc<#2-xNS}*(Iwaq(C(U!- zdn-vEe4Dokjd`jVgJtxrkj<1=oFR>K+&-f1cAk;X-c_Z3zyw+PtLQ-K8qt0sdTyqb z_2fK?>gigT9d(4054iD}7`Yexby1LDW;}K2z_m%L6lhz zq=*)bHS-`vltAWyB5vXAeZ`nTdwHl#W1uqK?s46gx+%Am31N{~mp^K33Tus>PGXJ@ z-Ou*`U%`&yw3p{k;c%X90zUY+Qr#6R z0aR%Dxh-c)-1Q&f2n}AYGT^9SA*1ziHQSzP%XtLbqgScZtu#*+2pX@8lE6p9mOj*W z9ipTo7}CfNuh}d^nZ&jT07xy_WQ0`xvNj0A7P)2ClNvUFFw?F7+(;RekIHnxegg9jgCE?Ez22%|8eE|(&p%4ovSpTD> zyf;b!RYaj{<`5fkX5qU@Snr#&$@Z&wUvG+RgZ~H6aa&(DfYoTJ r%vun3;S@Ara#kre+wC(e?7&{U|G;0?k5MgSZ`V-7P95w86YWos7z diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_light.png index 6b5c2b860c1adafbf600c3cb6333de67766114d4..d21b97c0d751b05657975014002a92347022d7ae 100644 GIT binary patch literal 5710 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 F{sy_&jF$ia literal 5440 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 diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_dark.png index ac6b9d2ddf76773648be9663fb4e7b52eef0e1ec..854ea3f5dfcd66044b5b2b85f26874354d37bdeb 100644 GIT binary patch literal 1787 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 MaU?l#?1R4e3t_d^761SM diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_dark.png index 796c0d06e10360c1f443bd2429347f1fc2b44bf6..ba49c0fa2b7f663a68f26a70814af66d43ffc716 100644 GIT binary patch delta 1599 zcmXYxdpy%?9LFEaC0&%;+;W?WOhj@S&M3kuYL2n7SZZUNwo@HFv6tp0B4z zVCt>u4_#Lc@OrdiE}^DjI?kni`x!((&z&B6L+E2xRH;&z^&SvB5=~F$*|7Bbo?K{J+cRj!1iufFpwh<6hZWWSN&;5`WZfw+Y&thaC@!_kr zcpZk*9c zS-$@zE|w{`un#dXgXF#%NJa|wK(c=96}c?<@q0I?_se(r!1wMDKd4&}q6u|#`UG;h zDJUx7w5k;#M%(Y=^XX31l!+3TW%1;sg^_D2Z^{zxSpbM74vq97I2Pj~O+Zupff+^*#!!ngO1oA@boO z8JFZ1tQS-}u%1wTLGp&`tA@7ahi6?7o1GwNb!?bM2bx-2X8<;Rs> z!XntAUr(h-2K}5vk%oqbv1y8+OkvPV6nq!6N_#hrFW zC;}YjO~M`7t#D5%kfG>Hl`Ie{06H^=^2be608Md_I&(rc2RrAi`M)U!aT|3W$Jxxq z8R0*^RtHhn`Bo7RaV;6Pc}t(Ve$9-2KUHarqm;G|PljySre@ZS917k9UT*3fM^v!5 zBX7o5aMstOr7ayh+roZlTeh5G_iTlbP&};9}tVJ;Pa_-i)f72R|H$6IfXA0 zb{&hqf&@hKq=v_JOQYRnv=J7`Q&Vg0k+{GWL2@uP9(_sWZb&q81G1B^%jB|d$S}TX z>5F?^&%jdkaM{fsW0X>|HK2()=3T!nTrLz_h7+sNx`e1}=-l^G7$OYrwL1IdbnhuZ z=wBmlkBnqZ-2ZD!Wtb$QJ50KEoT#9_9%iiw=V>oXr5y(fy)PQJW&^PP6N_mHLo!?! zVm$yY1y$ldp8Z+-Yv7afI(q<^{kC;8iL$1c{`Ny@fvL)l0*SJrS(42PtnvJ}MZS%K zph=vw?Jg{);K;Vh_%mFa6%7EGBlPVBv&tritfg)^W7N``5F4&R+cX;O=->v6(autG zmw`6xs$iK--4>Fw5C!WgMvl7LVg+71F&g7GxBhEDVT@%?RYum^rTh zHAgU7vvb1U>h+%Z>87-y=4OjD>Ep@dhJ00PP)6#|EvE}3)aM6^o!mGJw=Yci%6?K{ h_4Yfz{{h*;S8Uq7w=BW;`Ktig=j-L~dH*2s!he))(~bZD literal 1875 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 qWALJZCjAG5Eju5Kr5UYxuHHxi1 zoQp8_SWX~7gg4^N|E3cUXn3xAxn0ePVd2Tr4!yTz(dBIV`#ZATL)m_wrObYN{9x3$ z13mll!~naee}^&{PWs4?wS(kxk=iuxw)IGE^sH$IB<(Jlo1bkkz|+NC8|mCgVzuB5 zmlMEW_`zPU1k6$;Oy*o`)SDN{vqNc``1!4SKlYYbE$16RnE3>B)#4ytG}`6mcKV{^ ztoz zl|W=!g@X2k^hzQ4vCJQ#7wCM^MraS1buI`zp4q!1JlzukhS*67EhS;a5gzSak(zajP)NFihv>pK0QT2K%V_lyI8NFB z;_S__oPIvkpqqA%O3K6Ut|a;TnjWh;v-8N~HJqoAJdv_X1w07Myz#y?#u~)wez1?V zrGKCF6|MK$`|FTHc+rnV>u(>E@lR#cMX_jR`ttxUV|+Dis_N7_czIo%S$({_mM;)`H-+IQ6BmC*I_FY(&bD z$+z!&y|U~Hdl7lMLr|N43D$R0xYy|uw6LaMOZ27}pG3A8B6+KYjf}R;bux#xrm*ih zQ;Yzieaek=WFe@2LE1k(=w@*E*7A6+UH($|SoL-?0J1|4EpXmI)BP7jYgnxqVj=;5 zH!4n6tSedjkf3cEw;~3B;DIiJEBMp&22NVgnH5lXE8-lthRelG8UYYlFm?Pcg;VQ~ zng0Sn$dp`4Ta?5#|6r^E1x4W;HIxo$RMlW0h0P0pddPm3<(ld76@XRt_0vaT2hi4P z1B$zHs8#Ehju~TyA;XEI1SIJ}l#}IVeiUq<_%rR`z|dfxeI=tPi4LtvXfluRhI4ko zwiR_z7}VOeluVBc%+~nB+OAU)bmuqCZFQRg;phckE;(;gjX>`6<~hvF9i(2{clo_U z33Pit#V2(dr=2Kk%P=ha7a|IZj73eUkClN=Td)-aZO6-y=45HGVaDhaWY;TiqN=NZ zheLx;pcubV1(1FI_TISERN4LEP(1gvvmGEzi6um)o*p^j)7xGW0L%TXy_i%%s-A4! z@thRQNih@ei8BcPD<;X{d9fo@ zq%v-w@xxuQQ&^|_H7X#c;(#7g-Au*-V6Sg6vsi|620)(13P;--?a-I1%a_WsG-Wyj zb?t$#>@0Bpq=rM~ilK$^<3q|Iu;P;IN){Ep$uW_xAzXj-sl3&DNGr}_XF$ESm=-N; zixV_o;SY!kl=9^hj_>rS^ov_QOF;G@+F%iD>)D_9ZlhfTZFre)sLI-mvSdMM9E74I zTM$Q9)cBP*&)By!3`Ot8uq_oRf^IonkQmq3>^G9{6~rH;hQE#D^XYI;OnOk@pnux{ z)ofRk2F7xCQ)U*=q(>FLgU6Qa*Q{?7?}*sfTb{9-;LqyD8wAE3 zTRI|}Q1Fao26eXjby91$rIscd?STs6QHwBuA8jj@{B|E!Jlcu1h_cX;?K%}whO@hA Ro(|y8-PO~j!YS~N{{U`t{FVR! diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_light.png index aa3e29e06d893364fa5a606934c6477cffbe8450..bcb1962bd66ca93eb9a9e07895e889f0a1bb3f57 100644 GIT binary patch literal 1874 zcmb`IdpuNW7{^~iA`u$pHk&A`vB))(NbZ*@WT?qycWl_tt>EYrJfNU`IOjT5X?y@@57SJMd)Zg71)IQZ6g$%i)&Yt@ep({l(A{zjO1y7e< z`x48A{5{dSBYK?4fjm4l!aL5WFA7IV6*1+En(|{5-<@;TUY$w3571?50c~Qhkj_P8n{y29mVs)lObDpa{=H?&cN@egX^iS$ET3sydy}~c$_ly{Frvy{jv{J{G z{eGIR0IdG4cxIxVRvSVt8y~M<{NN{)PE-cIuhklaR_K3sbZ0Jp4jxOQr#F=mLO_5O@$Z*?m7B1*C#BykmLjkTwYyli@g(qx+Yvl9Vmfg2Z z5w}t-QjO(CK&mjGXCdx!tL1DjUnHA_4?wb+yvNIKYb4toby0IajH=_CgD_DxyTD9s zPiv5HV$=nMsowf}M`!M3<2489Yy&(V|EK8vlPmfwzhe zcC2muW-{Yxkq?Bj?HaXsNGm#eEjmRFJ#a^3#>R#uT>AXrRQys?Qtvtp$QZ%Vu*L7Z zV6_r=<@TL{cm~sTZQyd8r6VOU0vI52k#*&IL-@T@PBRPuOlmY>eEQ|KYJE4kb+$zpf=Yxt={hPGf6H?_&#qQ_H&( zs1rNay?7B|fwesPp+{$S10$|cYtLb(pdn0_<3{`hv}ka<046P>8%wv`h=}R zTl$^}rxong0NvES;upI+=3!VCNgm(Wm*36Y^0sw12=|ZJk0LuB%*I`loDZa+6DGux z`ue%xgEBy)+Bo;ss}x;+C|gwNmDxKnLnKa(Kk8BdTvAzCm^(Ynw82E4cV4I$R0}e4 zpnhZG9ht1#R&^3-nn38_ZJ`C6ZU{dL1DkULwSxx)f~yx-0lN5jCAHBnD%>IYHjShY zGI+_igZkYlacgD4CuV3a;k16-N-&F~*ocTd09aFu;NjJLy>*TatsXv*ScaRS@hofg zV^-=Q&2j!oU7;M<{HD5>rXs$3X(g|sXVG4;NhV{Jt$>q2Rs&yIz+#vDLxEM$CV31` z{X1yZ|2YiCY3-%0nfCx0mzIy>ryh5mM`a3tE+1#@NlzJc7|y7&Tuo`reh_4@?{ zd?d-FcLxAWTS{>l%_QVV%pv<_+cKGP%r`1rk5=YutqPpRE9`a#HD9%=6YVIx^SX4O zr3_&44z?=qq39=s1>3DX5xVH41vpKeQyA26VGw~J-d&7JKU`7@zyT&sIdBbQM-MS- zGNL+2Lk6_DQopZfC2kWb#j7qx?t#A1{8KhIX!piGW{V1-2ijNQFs7A^d+~HmZuTpF zA6d8s`wSg}1y02G`%zQM?Zo4U>a?T^YZzJ%d_Ec4qS7=oN$LZ6!1At)EE)-THtJ(E tH+|X=8VKj71=Pm>N%=1%{P%Md44lqlnKwGywn6_z;OUBUsdWxN`4^j|0}%iK literal 1811 zcmbtVeKb^Q7=Ic0%D0;G5p4>~C@BU-?JP4*#GW$PgsJ1B8cGKdLfeOrv&a^UgR!h? z$BYk#o-1|Py`~05g_x$er+?)4Z z08U@mTo(YKk3Zyd6ae*5XkDtU3EkB#7Is4qwZx-13~1z7zJm;nL<~Mi8@e*IqjCYz z?8N(g6O>vh85tm1ip*HD*q9xD^tYJW3d`d+1DUS(Y>xyLUq$>fH~wvnWJEL>#8YN3 z4PJe>Yv10Sp*gbsTfU#TJ2@{fK&RVo%0#>8t1~tdho557?bVN+mGr-VKHWbpN;DB~ zne@mkPg$s{9kbR$03yaaUAlEez7QtMNnaGy;fl;7S9$e*vRj)X^R1bS5tUh!<$KCy zj5PE){?Y^^2Y^X7Po9=B+a4ki*pZ*!jm$J7PfJ`Mt&k%#j9*TlLtR!Dy=qHyMTP`( z;sjmlR71ZA2%&Y^<<&S-|Jk*tS zz@Kn9YFaCK z#l!siZ@c-ZIK^-naQL1x6)>lAS6Z)weEG5T*LCRgqj7tCQ9M5XN78WPk#s#k^e20z z8d)=!gO#$;&L#2lx}M>#i|>vqm;NYelQ%@Nv%DidjnImV3Du_pKsG0J`r}0E1iGt$%#>m>W(3_m!&y@4N#&=NA$6&HK)9GP{gh44 z8Wqb8t-O^p*5{dTbdZ46Otn*G8rLyX$plu|XJFZs)^}k!r5l7;m7MO6-Qj)gX>(P0 z%?(@FJWH{F%`2X;X>Ja8L)5eL<@OeNborZ%^xJv4PmoJ?^N1t>sYtLv9}}sh$P~214<@{Ij9m z38&e{KwMgDUyJG!mqep>R(luqWNI}~C}P6}D8_T%2!QyZsgh=T$A)N+(U?df%On`E zIyR#j=CnqN!^K6pKo^v)$KePcruAzn6|I317KP%#T3R`++yXu7)#7DatI(`2#RL492`EdvWq=C1 z_Ic=MvVD<@ejPt1t*6ZdLR^3;VNP-N4SxN~{LIKRsFOjpv9_i(!D_s*`hPd0Dv$6j zaJ4}+pj@FLYOcjv6r5;o8|t9Nc}8SQ8Kz=F_52goedu#1T|SRLGZ(k2`BBBH0P< z+z9|^$x7x+LD_*hi+xSiNeKy?afFQog3eA*lbBzdOSi8Zc4QY)?CLAKn%dfo<}(@E qz**7Z|BqMrMWX-fIQ;)y^i>c(a9fY2S;&WeYyj^Y;M0g9{_r<>U-jDn diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.png index d7adf538b5b232bdecd46d03b0f576c62e04448d..2ef28f8495324966cb8c9f82b43e53047f06505b 100644 GIT binary patch literal 18824 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 X^_EKbo%~ps0_42fW!20xrhoe%Z9Y^* diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png index d4b88c28616c068185cb8557ec1caa7bc0f6715f..544f872966ca22634c0e717581ae0b70bf1cc348 100644 GIT binary patch literal 13933 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 F-vBw;Ut$0N literal 13765 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 YmiIj2In9y72H;0s6{(Vc-YWP%0FzcV%>V!Z diff --git a/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_light.png index 2446626db85d7d5db67db1a6f36bf6adc18e0170..ccc1748279f4537b925286ed2e90ddacb93ef3ae 100644 GIT binary patch literal 13827 zcmeHucT`i`y6-|1Y`_swwn*732%>-@y{n+ok=~<%w9uqO2&imCKtMr^Ktd5Ip^Eet zKmM<=u1MKKJZf2%>*=kO7=|9TAKKzv$d`Z(WD-+Bj#x!G8Das`>}PkN-jIXAtx= zq^f*P-v_-gWZ`N)g&}OgYTj0M{;c!}QawI-`qG#E2kyLU>2HOM zKuTN>Pho`U3Ho|67U1eh+SM^Znb4YDgs0-F*r?f%&9QKSU9OrOSJvZ+*T zf~3dF=z(fdP+(rUwxXwuB<)=`_8y6g)5fHY>=S$Mw!0#;YfZFVFsljZCgk6weSlad zc$|GZ3z!90Zx@TbVW2mwL1su$Qv=P}Y2VZ_@@;6y^BC<3QIGtdX?bW8_Ca!NUXBCl ztqBs%t8%{J3I40+8>pl0Bp6{AVS$b}?KaME9^RY}3|MOKT|?7GfZ^of;8z;F;2*E5 znS@JE&tkq{d1J_pAmtEs2WaUTw!1zB{R2{>zldrv{XC&i`L5*sQsu7jB>~E}-Kwbre~t&7Xc zUQV`vk^86A(=Bo=5gl=~Prjvm3sIRkJJ(hFn0|ZqwNRMyS=eSm!}Lyb9o^L4(AK`~ z%*0hZ2xsP!%gor`#&-@=(+GWKa1^yJimDsv=Bk7|u|uI4?!^#8NpU54LpZ@8%W6)7 z62wDEqc+q^VpRCYAFNIoMD2%scn7yyH8IpKo@qr4(u|nzMif`w9xhpsp^jT3=R^XO zT_K3YYig1SL;aD&5DEGS`CnkSrA4&P%jC{`oe-3KmdmVkMmBJZr?=|GqY(%aJjqMD z{$3CsL2IAWZ%SJb5d1?wE%0mObI;Q*|Lt}f?SmfG3Wm~JNi9F19YVI;Y_zy>bx5N% ze&pVw64EM52N@K4)N6zDnOP0fzkHbx1$XFokAMFO{QiCybfR`Y_}`nK!2^ziXWxAS zx}ib4{}8z6@-^`G^B{EpS))+94!Y|pFB0O!$_Ui;(%HquJdzlcY$H|w-+$&`dhuSP zV@xti<>p>jk3&i~Xc6+CcK+ZFXIs!KHNFR;iEdj@)Y5dtSq?zPsjgBv={_2*t*XKG z-Lfo)VzZaV(~0cjl7U7zn1?+0maw;-&w7gAort)Jj#`kDip$B+Xmpq6g=&ojV|6N| zCpf#dP^ioDDIhY}x8_PZ#PPsyDjqY9r&H)PQj!^RB@zn#Z?Y8KMDPAcPmutfx zpM-~Q)l|mzdv*Kv|{gQd*E6UT>b!L zcW`$$WH+ZrZ&My5g8#yd|Ml7Vlh{ddD>r8rt<4?KTeJZYX=Z_0c#La5_0Qw$*J+lL z`f<5+-=mvTqooQ<2MdhF_69(RJNy9mIak-{(Dd3E2*Q_Ii*C|}<8%-{ z!&Pd2+~IZ1>C1Db--MrnGbts8k~Pa(PmV`5l@&2SOagJY1vot2^N0Ib3tzvsIr%q` z6hoV=9PCx4Pm3(g9a{93j4_a?9C5o1Jt~--d>5~$nqeiw63KhQA68hnDj17qVS+N> zx=Ow4={ecJX>rpmOR&yl+*f*H#diy*?GGhu1=pWZIeUyRJ|2B3&{EYPh#smvyPo#{ zVtxF{4E&QN{`MNM--ulu2n zj(?dq_9=#}{tQ+|-17``Tr%is>kT@{@B-W63!KasIU+JIaO>&mnWyMv`ZZlN`q8XO z5OHv(=K0r5``JNCvA4<0xl4rLnqdavv0X-k9a0_b=Qf5@SZJs}J}dIU@XY zAB2BdzV&=%>q$((;C_DEy1(Na+2*#7v1udxk}ty}hSx0rvU(>v=nm$hG&PPUp6RY6klG1h3Sx&vSJ+ z)bYslo4sv#JzD4r+}_@Xjt&xg;o+_psyx`|^BAV>T2mR9^P%qm>c&3kXz=wjxn?NC zn4sW&HIjLABe!+yHpFFR^L3lII-o~_4q;8Nob3(Y9d0)^Ve3_;=FQ4IeoNl)5NxS5ojTbBD@!@=~i`m9kDFc!xC zOIQCxbdxM4^@f~&AgzP7Ira7Z&U|B z#$bqljqbq(Hlg0SW^1_z9}@qM=st49_aCBr{K$dUR)XghHYhprYpd<6cJ{r&Oq|Ml z1ZHGZTBhX?Ct4T#&Rm#iEeg)Wv`iQX#_o%v)hTp>o)Dx&aa%Uyk&-$hEu2B8lCqs=flA_54);ERGZGn4!IGy z<(!)V=|8{v=ZoXN25Zjh3!_@DF_d{Cz6?2n3Z0!@DBrOm{pVOFw6^Y0@Sw(iNT=pH zbHF@3BR}UP?;(f-6HeH!J*S-7`D;+forFS zky(qE^`Yo7FdhyLVHa7kK?td6e6&`9DHFt@Be2%zQgsB>t59Wpw6oXVL=?U2YBM}1 zYu1InErykj^$_QTk{iFZUf^SWXghWwK)#ORR$etZdDTts5>$IzfbCm_r~Op;M>OND z=&-ct#WvelE$rrdWeXsmnb$TdSxY*B22Tnzb(Ug9*z^T91y8CA#;T#WASDc_3Wr1L z!<0XUsicNASs5TpK4byBc=y=p6uLi~p#KS&{2%3?P6uX7!Pr;LK3^t|fX;Wzu|anu zKK^(gKYB%6lK%v=5mAnpHobX_B+A>#N#d7{@VpQPNdJx)M`y+BA^`GM3owlQF(mK^ z;gJ2%PwHu`YLXe~$Qd!IuB+~XZ2m?d4jcryqp-Qf4Shas!aV@fg))Hz;*U$-+In8N zjNZ>bC-m9O*mZA~e2z#zD0Fs?DLbU~`a7hQ`o&M0e{4Ts2=y^13urjbhIA z6rC7pfR*GsH-6bpnlY-nu;?+L*S4-i;Fp3%YCA?=v|*69$_H(;%PT4?i=E~SorbGS zu==_)9;Pp!4KQ5^Z+N>nT%GOM)Ai|7ne$*3HcF8j#mmQfh{?YYhDaKooA&`V-a#O# zWzIIAV$MTZKNnnoZ((MkyDo?kbQ3O`q;WpGuI`!z_o+Kr{cj~sW~7~sL~pl})ec5m zE2CSbZpI&5PuMDvk?9w|awX-+lrY|rn}o84 zGOa8dySD1QPaF>RSep)NcU0IK*Nb@m+|I$zR8KEyi0JI%VuT?3El{_eo%)M9t=l^7 z^xL@)4vzQmV4@qfpYuByQ8C05I?5>wP)=s(|FR z1St3-7Hltcb#=k1iwua)jI3U$i)xa~>eH6Wcp( z_-dX7vM0l{n=goYH_yks1ii(Vw&k_IU7E=?YY7-0s6=Rrn1nan?=Q@dT-p&VklM)0 z(~21r+WYzeZ$}ibMU6tm{FIZElZ?+uZC29)QL$`PLOL&EIDx#L$aTKS3`D3>aLMBL zEC4ZM2t{c|3;Mw*14)jD3W*h5&1*-CSgTJg55wS|7t2 ztonz@p0Oc0A^$kPrI?wt*W|pksxC3H*kb!g z7PWVYPKir;ZT<}MvYSe8o<%PnkN;4~tbFzumyB34M%LS5Jm{FF=Fo=U6VhBUqI78P zkcUfqNoVIBzUmga_Lqg)yW<*xdjDRs+Su@#>oM>8KeU^;@ngq`DtTgBmUdBw^kxtdSZr^ zN6f%P_asYWzAY1Ll6!g#BO)VaVvV#NY#MD8i`2e?v@&62*&T6O5)Ts17(p@JTF|6R zI`|8`PaP3zR*Hgg9E75tpiy1en0)yC``3TC8YBD=o+GuA4lBGhybnZ8n3$PoS3W;e zON%aX?0ZYZEj2l)3GaR^>zLqT~z^#0f%SbV8?2;jcg9!s3szfo@qGdMjo z4^ln9Q6YNpkx6f~*OjACGIMcp#a4tjE80h{F-;t@Q)*Ve-_R?P^SY4FMo6gj($CN% z2G*!1{I^kO?Xp^yfMKHZ`D{n8x``JMWCipYaoJ&ueqUE!>C9lH3!HWS(915Rk=cWI|pEp0b9h) zqCCD_JF!uJ$0-1=<$=c3a)u6S)W!btt##2W?DgD;M*CN+&XNTaBb1rqBbQ#%bJBK9 zy3$xuF^NwC>QDl_adPS^P>op8Ii)|lJoX0bJaze`+ZUUm!SfG~b6S=GvEt&~1o}CE z);O4T^HoUfy)KrQz!K2H>*^|1N%yD`)ykkq!{g=(JbQ#`638X4u0Hn!ATb5@8WN3A zUcS>^jfY0=crJVqNBT^}r!Nk^oD%xHDt98>xs)7sGgXb3RqcGt?6h64Rg_|SViN+* zU7uDf%QRRaKjAC^H1`%?X$+E#eoEjm1T4Fmb9DJl;xytq<+ot-GO|S^6OVI3u6ONR zZ%?)1Qq30&yUmA&hWbl9vn5=H0q((qC3^eQ!qYbm_wRTUhYcj=?C;+hWWkQWs|ehCoW`r7*JNF6=srg)t8`IzpJk!0bh z=b8F~_5&rkepE!etn`5IbWmYI_PLG?y1RTy!xehn%eEOdYyH_7VzRQ?k&#|p@@~o? z%Noerq}kZmtcAmJaG6QM1L~? zb>iQ==?HdbcaVtMRu_fvS475U01!AFd|k$GtcXh%A+G>bDb}vJ=aiV&>_AQAkmq0ZSI7g*m;mahIjniLLcJ&%ksd$i24XWZd?4 zq7Hm+Me+v#b#2vGGgDGhL>v!YRZz%VUVg~L0_&k7$#_Db&JS0Th(vK|DZD+=l6E={ zmekF|MK$b>@>K+qzf$l{RsIk4dcYJorirk1m-GDmq_LzOWp)uu{}HMcptkJ7miU(Z zs;uVbX2G^?Z-#9$z^&r`_QooNg*?VsK-hFrPNzx&sNUVR3X;6I5LwbFKOl2vCN8WA zjYi|Uvw39D6JMg6-}(9Z>0dhOX|xHjoW@f|#y~X2+t;l7<{ZLvR{?M1hdjX>*Lf+DUWS29E)Bam{ z!5S@OJ>d^ar(%cUdQp{3gCcB)yXU{tUR+d0@8K0(7{qj1BFA_BXM#mULt#;@@Dan~ zG(3U~ke(fmTBpd+E1&!9ZFDZC`8K#|*37oo_Ri*7PwoRn;=)jMIx45({*{HkuG2mN zvBqeGkx@qT^6R}0FUXdtN9VzKEY?>`N+h`CT<>;|t#9y{KTP24y$QOFXlMQ%Y?ygF z8USLrxw$!&@Nn2=mx`R7&)Jzzaj$1sK(45U6q@&~tra!$pJxkIF7j+L(u^!;qxG?2 z^vc2_r2-(q;ZvOE>n;E@XjS=`YZD2(wI}YS=-ei65PL(9i^S)0%DS(kd9mK@{lb(3 z2D|W0pdfJit-nzCsr)UxH;;x5`z#pGzI?{a#nI7*kriL5dzPNQh>)+_CiPbjERyzD zl-dqVPiKNA42h>M%P!K&lHr+Z;oNHNh3<}qGZ+QRYfJy-&9HWYBS6byf)|&OFqgyt z_2@M`u39Z^!6-8nxLxo4La44vrzJe5*T>%lkS1qLwWri+NFqKyUKflWLt<`gUjz-E zSYG1pDnME4$Y6TDe}6OVGseDxtm*06-bdIVt=1rKSXlvG*uJv>6?uUpdni~4OfrQvu`#vu6@bo7r$y%$YaV!ODiiE^Jg0)PCGa`buSZn^h9HGX3*Csis#d+ zKjjXzh%oJcbn9AM%M8A`mqrwTVkBQ(E#o?JTHH4p7A+c=!@$Vs>1(YFPO2Xt%O1REgs~hp@EHsj;r*5O-$`kv{_~6GZ|L{y$w+!7Jnr5^)>mF$F|!i zT*73z5@?=oMF6QH&m8v_AWPrjCvxp(%f$@vKR9PG4q44js8*M+^h0x7(a`4QV|x?~ zdUKEy?fS;%H}S{k7h@)#v-_a$&zkN7b&nHmeRi|o8E7BsGCq;O`~c9&(Vr^y4V zE?!5DTh9z04&(=moP?xy*3*#P&s+Z2R##5}fN@Bx$LvLEtt?8_IU91BFUDahah$AVS z;J2quE+!5aBbI4m5i9E%)Ndxu-PSVTrPk;ni?9@AIp!3 zC)}d&oq}fHpq4!VC;&n?m;Cm~)dX#YE&X%n&c(+k_Tcfh8C5Y;j}vjq}<{A)@AkRb4DYZ?t!T0q{I?PlR> zb9>Nitt&4tFL*M%;)-9__#1UFj+q_Pq${f5j3iu4*H?kO`e#UCn__6kykZGrA*N2KOn|tgXA zlC*~{$tGXc*4E-{DmhyJqhjG`82w5s14Z!{R1!0EC-6UOF!rN`Y(;U|z^WRt7~3?& zu*iNm*ul$@_F~gPI+@CkeRWTnPWQ-p0nMRt)TCbxbs&2Wn<&(9dJ=Du12A-NkBwJm zzihVV1vim$3+D<2{Qc&7J|u0dFIsk~_uMadvpzq=Bv+$$sjWIYyKCI%*RNma8sJmy z&5sf$`17zO z-cf!pXkB6JUA;-3qo1GY*zx0FQ$~NqSoZlQ^F1Bo{_-2IjQ|UP3W-OVg~^ftKk!@1 zv9BX6(ba!@hBkDq&T91cT%8KdwH_OqUg$WeHzS`8ErzSjR$LBz? z*OB7vNgTH1l3I$0munVLjngm;3JR)_6MYNZ8X>ci=}M8Eg81l`n#<1O6*8zmp&K-T zMrvs|c*A3T!QIr@_yw=0w>KP6s{ShbLS3x20r&hRw!>d+3cuLM)AGoqi}P%1l)~%9 z1+v$4935a5?t662^K9vhuDBZ6>=u;pA4wgto!C)(l@cb|fQi%u#faIW#?Qh?7}g0; zrku;Q#Hrj()1cx%_@^lWXBkBtPD``^6{7$kPkbfv)}DR{Li}+3-rRkOU-B;4%VBX8Y(BW* zlZWWDFZ=i9u7!H<%jF-++3kB>5Ati`oL28yz2I4Vs!F*_cDR z*`l!J(k9)dQbrSX+J9$rpHN9XmJ3$}%B&R6fUm2liFVxcsl5#h`hqDQg_W4M6Egor zPh*4&>`k+)3Pyi0kt|gm+#kZ8N2gT(-?20}Eq^-vtHlSb3`j%YQ$!r{(YL5{)8w%% zPX~2#-1o?eoOZ+8fdw4cum!{b!1REWPWnC;g`HaF&S-MIu%t!*o4qXe2^3UYf%+=3HU-A`p-S&PwERimJh5Wc3`J;N8o|n~I!~@Z>8& z3?T-9%`ixdWF+BMBx%q?yIrf=V^n$Q)6HmLhpYi8!j~|1<@vW)U=%bM5*A^cd5CAkVk{h`c*UF#dpY`%3 zkb<@04zq>ip@oG72NziW5R8zknIIAWRhlDWw!A)sWE4oT!tnSTA<5gXZlBkPq##x= zE1reqJ`Gbzr?znUI2=E|zhXyo6M#B*;!y`XyXhllAD>4>!GWn!UymvdBq)$Jc=V;r zDdC#nB|uR(0;fGEdu>U#LTU_1R>M(%`{|rfB*K9^0ayhP8c>vkW*{PO@+)>WgtPOM z?HZSx_XLNtlK@Y1aC7?*R!GG>rUn4q$^_#u?DVdjyT%8GLw~w)nh9v;q&0t#O&?KiwL7ZW6f$Xh_( zsgM#Yntdq3%oK;2xYUN6AO6jV&>Y4I4OQ}dK(plezfX7CX#woI#^VCbA)pQqvhV)t zdk7?ucvZ3b4!|67$){X;0Mw6Gpdd{CN5w+oqN-X(7w|kz{LGPEPCWkU{v~-@$PSqf zF8HQx^y9~z={Jr9Ul*69iNc4479otqkNLaxPnqD{vOsgNTE66z*7Br#&p}CoMOJL2 zB5T^9&VwsM-Jh*RX|~CBPanyI4Y+dfzIFt{JAZ}`USO<&SYKmEgz=r68t(44cdPpK z>&cM|(eLJZZ=onvxw)E*ES$!qG75#!Xz+YfaVNr^FkD#wJJ{&qG6Sxdn1TXz%LctM zP!pIWBYRO1F+KSH8Y0R6+mA~|67ur7%b|yWpWrmKZ1B5fRN$jgiKxi~NYI;s5zH^Z z497*dd%MURimocgK;Z!1i0A01aGQ%wZD@IZ)!CuK67|4q-MbtLQ0BRiMEQ3tH}j_Z zi{}6|H1+Cze4F>}jSz++_bIIi|I2T&ShA(|`+#aMVhKY2@!~?Cgp5oUX!6*W;cH|i zO%O4-ov#ij>LJ8E9^TH-u1RBu$>By;MyrOGuC6z##Tq@dO1P zuvECVOFlE_=1tASan!rN^J-rUnXL`6Q;jv7CtyF7a#&zmYF?+%1R72s;ztC{Vivk| z>2~yQ3COW8EB^yl_fL;u`5(?2+8 zF337f-bCH@JWw%=0onw}VUL1A=Yh%2nQj7gOq+wv7u;tI>qEfKeTmTmTW(YBlAluKi6nkv<0|G(Qx2om2v+bz6ju>AE+iT{4mf424d--G$rwy6Jm joc=vdfBM%9n>-&&!u-El=z^_&5TvT2rJQ&D?vwuoh%pYb literal 13649 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 diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_dark.png index fc34df7e1c54179c9350bdf963ad5cb39270786a..673a09909d5818fd9da218b9d1ab2d273584ec90 100644 GIT binary patch literal 5583 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 NC(LY2amUfu{|WS}Ay5DS literal 5614 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 diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_light.png index 6b5c2b860c1adafbf600c3cb6333de67766114d4..d21b97c0d751b05657975014002a92347022d7ae 100644 GIT binary patch literal 5710 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 F{sy_&jF$ia literal 5440 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 diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_dark.png index ac6b9d2ddf76773648be9663fb4e7b52eef0e1ec..854ea3f5dfcd66044b5b2b85f26874354d37bdeb 100644 GIT binary patch literal 1787 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 MaU?l#?1R4e3t_d^761SM diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_error.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_error.png index 59583a9b1827fb69eefdaa8f15f8c6ce3dffa34b..648e9a0bad2c0725daffaccf8b1bffda9e67591b 100644 GIT binary patch delta 1703 zcmX9-4LH+z9RD%1F3QVk+tH2`ie)RR%S%)w66bBUxVXH;c~ZLb{xZ^=ZITwvVZu3j z%u8|&+2*NO=OtV>VWxFBx@=+=(d_nL|L6HXpa1Xo|NOq6@Avcl{wnpx^ll#|=X$yw z4NNJMh&a^kvzV^MH~q|CI#7SMzbbt-J?-UwlJdxacn}@>+igq^^|p&^R3vtnRYM^B zN`m;d;DL|X);3Sd)z-gMHZI~9Vzlg!K6s)O)>L8$0kQFv4x*UdT%P3Jby`{oO|z$@RezGx>*lEL*gY z0PnxYygr7_w^lDM(~%@i9e~!M8>!KRZm32Zy1p76PZwZw;DAsCnFb*KFvDBKYGbRI;v_xjo#qUGC3AsRXRgz>DJ7m*(qsY>hqaL+z9 zKV?cS&)77jmS>=+3`rzXaTE`}W^*nv@qiE0>F|I1KsJTjk>$LRCJhbkxNOll(Girc zbo99OeDG|l#pK#t^=R_yC5ZwCv*~LYH+6{hDRQMZ1enlpdd?eFBN>(H`a8zb6h}9IR3h&mth4O)c(xQ)> zR8Ia=Lt*jC4hN_U#c%U>8!>G<+wdiAW5;cfTMTPQ12sAbF>3VkHGjXnI7R+bZCb#4 zD1qnWXUdLbIc0TrhNdfJYMTNsD0{uih#}NRO`Kw^x-asNO|0ia6wZ>$D!EW%2=4y~ zZG^>wxso>21Uh0+ak~9Wmy732Z-}vIL_T^AE-|$UX-b0suDh6Lh`XW zWYvdmh`KW$wm&-o5#}NoP(uLhZ`FS|`2J}53**(QVcG0pZCOJhAvoB>Srg#3nQny6 z_4qgU3ZtV)#g0cXz%@7XXIb>;2fmSq&9y*X>`+3bDjND2PaW-e+F7W**?Ut6k*O~* zz$~ZMGy_E>1CZyG$J&)6kR(+LZK`%tcI$Aof&HoC^M$ji{jE!kl5bXj9pY}tx>3&% z1V5wUtcg7N%M;6#bEk3vpiv1-{ybB(&xLKZl+nf)#6g_JI#Hg_dFL`)O+dHqYheiO zOk^_o@p?k|Hg|&+sS9mjK#Koa6WG6OB>!Ny_>|jyrZDJmGo^~=n7rWLH2a-CVAwVg zY>K&T+>%p$E7zY=6!p!D)LB0mbOrt=PfJ+X$n7og2-?izm&-@z9gte!_t*bMA95(q z_liSk6G+9w@yY)Ea4-~8FkWCI>NZ9b-BrEGx#S0i@=6O&Td>n#~{LeV+Bcjw%^Ek-W6G{XSCruQa#xxY zL9vp)2)CqvfLp2Ft>n5LeJwe0(b~2#e^d$I*ZjI?QaRIfCld)`ryEARb$bw_}BqjxrxaxD3Go{=t$Hl|z*YMhJ?bnHn)vr+ED)GGZ@;QDAf6`49oDJdb`VOwq9rMd@T qWALJZCjAG5Eju5Kr5UYxuHHxi1 zoQp8_SWX~7gg4^N|E3cUXn3xAxn0ePVd2Tr4!yTz(dBIV`#ZATL)m_wrObYN{9x3$ z13mll!~naee}^&{PWs4?wS(kxk=iuxw)IGE^sH$IB<(Jlo1bkkz|+NC8|mCgVzuB5 zmlMEW_`zPU1k6$;Oy*o`)SDN{vqNc``1!4SKlYYbE$16RnE3>B)#4ytG}`6mcKV{^ ztoz zl|W=!g@X2k^hzQ4vCJQ#7wCM^MraS1buI`zp4q!1JlzukhS*67EhS;a5gzSak(zajP)NFihv>pK0QT2K%V_lyI8NFB z;_S__oPIvkpqqA%O3K6Ut|a;TnjWh;v-8N~HJqoAJdv_X1w07Myz#y?#u~)wez1?V zrGKCF6|MK$`|FTHc+rnV>u(>E@lR#cMX_jR`ttxUV|+Dis_N7_czIo%S$({_mM;)`H-+IQ6BmC*I_FY(&bD z$+z!&y|U~Hdl7lMLr|N43D$R0xYy|uw6LaMOZ27}pG3A8B6+KYjf}R;bux#xrm*ih zQ;Yzieaek=WFe@2LE1k(=w@*E*7A6+UH($|SoL-?0J1|4EpXmI)BP7jYgnxqVj=;5 zH!4n6tSedjkf3cEw;~3B;DIiJEBMp&22NVgnH5lXE8-lthRelG8UYYlFm?Pcg;VQ~ zng0Sn$dp`4Ta?5#|6r^E1x4W;HIxo$RMlW0h0P0pddPm3<(ld76@XRt_0vaT2hi4P z1B$zHs8#Ehju~TyA;XEI1SIJ}l#}IVeiUq<_%rR`z|dfxeI=tPi4LtvXfluRhI4ko zwiR_z7}VOeluVBc%+~nB+OAU)bmuqCZFQRg;phckE;(;gjX>`6<~hvF9i(2{clo_U z33Pit#V2(dr=2Kk%P=ha7a|IZj73eUkClN=Td)-aZO6-y=45HGVaDhaWY;TiqN=NZ zheLx;pcubV1(1FI_TISERN4LEP(1gvvmGEzi6um)o*p^j)7xGW0L%TXy_i%%s-A4! z@thRQNih@ei8BcPD<;X{d9fo@ zq%v-w@xxuQQ&^|_H7X#c;(#7g-Au*-V6Sg6vsi|620)(13P;--?a-I1%a_WsG-Wyj zb?t$#>@0Bpq=rM~ilK$^<3q|Iu;P;IN){Ep$uW_xAzXj-sl3&DNGr}_XF$ESm=-N; zixV_o;SY!kl=9^hj_>rS^ov_QOF;G@+F%iD>)D_9ZlhfTZFre)sLI-mvSdMM9E74I zTM$Q9)cBP*&)By!3`Ot8uq_oRf^IonkQmq3>^G9{6~rH;hQE#D^XYI;OnOk@pnux{ z)ofRk2F7xCQ)U*=q(>FLgU6Qa*Q{?7?}*sfTb{9-;LqyD8wAE3 zTRI|}Q1Fao26eXjby91$rIscd?STs6QHwBuA8jj@{B|E!Jlcu1h_cX;?K%}whO@hA Ro(|y8-PO~j!YS~N{{U`t{FVR! diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_light.png index aa3e29e06d893364fa5a606934c6477cffbe8450..bcb1962bd66ca93eb9a9e07895e889f0a1bb3f57 100644 GIT binary patch literal 1874 zcmb`IdpuNW7{^~iA`u$pHk&A`vB))(NbZ*@WT?qycWl_tt>EYrJfNU`IOjT5X?y@@57SJMd)Zg71)IQZ6g$%i)&Yt@ep({l(A{zjO1y7e< z`x48A{5{dSBYK?4fjm4l!aL5WFA7IV6*1+En(|{5-<@;TUY$w3571?50c~Qhkj_P8n{y29mVs)lObDpa{=H?&cN@egX^iS$ET3sydy}~c$_ly{Frvy{jv{J{G z{eGIR0IdG4cxIxVRvSVt8y~M<{NN{)PE-cIuhklaR_K3sbZ0Jp4jxOQr#F=mLO_5O@$Z*?m7B1*C#BykmLjkTwYyli@g(qx+Yvl9Vmfg2Z z5w}t-QjO(CK&mjGXCdx!tL1DjUnHA_4?wb+yvNIKYb4toby0IajH=_CgD_DxyTD9s zPiv5HV$=nMsowf}M`!M3<2489Yy&(V|EK8vlPmfwzhe zcC2muW-{Yxkq?Bj?HaXsNGm#eEjmRFJ#a^3#>R#uT>AXrRQys?Qtvtp$QZ%Vu*L7Z zV6_r=<@TL{cm~sTZQyd8r6VOU0vI52k#*&IL-@T@PBRPuOlmY>eEQ|KYJE4kb+$zpf=Yxt={hPGf6H?_&#qQ_H&( zs1rNay?7B|fwesPp+{$S10$|cYtLb(pdn0_<3{`hv}ka<046P>8%wv`h=}R zTl$^}rxong0NvES;upI+=3!VCNgm(Wm*36Y^0sw12=|ZJk0LuB%*I`loDZa+6DGux z`ue%xgEBy)+Bo;ss}x;+C|gwNmDxKnLnKa(Kk8BdTvAzCm^(Ynw82E4cV4I$R0}e4 zpnhZG9ht1#R&^3-nn38_ZJ`C6ZU{dL1DkULwSxx)f~yx-0lN5jCAHBnD%>IYHjShY zGI+_igZkYlacgD4CuV3a;k16-N-&F~*ocTd09aFu;NjJLy>*TatsXv*ScaRS@hofg zV^-=Q&2j!oU7;M<{HD5>rXs$3X(g|sXVG4;NhV{Jt$>q2Rs&yIz+#vDLxEM$CV31` z{X1yZ|2YiCY3-%0nfCx0mzIy>ryh5mM`a3tE+1#@NlzJc7|y7&Tuo`reh_4@?{ zd?d-FcLxAWTS{>l%_QVV%pv<_+cKGP%r`1rk5=YutqPpRE9`a#HD9%=6YVIx^SX4O zr3_&44z?=qq39=s1>3DX5xVH41vpKeQyA26VGw~J-d&7JKU`7@zyT&sIdBbQM-MS- zGNL+2Lk6_DQopZfC2kWb#j7qx?t#A1{8KhIX!piGW{V1-2ijNQFs7A^d+~HmZuTpF zA6d8s`wSg}1y02G`%zQM?Zo4U>a?T^YZzJ%d_Ec4qS7=oN$LZ6!1At)EE)-THtJ(E tH+|X=8VKj71=Pm>N%=1%{P%Md44lqlnKwGywn6_z;OUBUsdWxN`4^j|0}%iK literal 1811 zcmbtVeKb^Q7=Ic0%D0;G5p4>~C@BU-?JP4*#GW$PgsJ1B8cGKdLfeOrv&a^UgR!h? z$BYk#o-1|Py`~05g_x$er+?)4Z z08U@mTo(YKk3Zyd6ae*5XkDtU3EkB#7Is4qwZx-13~1z7zJm;nL<~Mi8@e*IqjCYz z?8N(g6O>vh85tm1ip*HD*q9xD^tYJW3d`d+1DUS(Y>xyLUq$>fH~wvnWJEL>#8YN3 z4PJe>Yv10Sp*gbsTfU#TJ2@{fK&RVo%0#>8t1~tdho557?bVN+mGr-VKHWbpN;DB~ zne@mkPg$s{9kbR$03yaaUAlEez7QtMNnaGy;fl;7S9$e*vRj)X^R1bS5tUh!<$KCy zj5PE){?Y^^2Y^X7Po9=B+a4ki*pZ*!jm$J7PfJ`Mt&k%#j9*TlLtR!Dy=qHyMTP`( z;sjmlR71ZA2%&Y^<<&S-|Jk*tS zz@Kn9YFaCK z#l!siZ@c-ZIK^-naQL1x6)>lAS6Z)weEG5T*LCRgqj7tCQ9M5XN78WPk#s#k^e20z z8d)=!gO#$;&L#2lx}M>#i|>vqm;NYelQ%@Nv%DidjnImV3Du_pKsG0J`r}0E1iGt$%#>m>W(3_m!&y@4N#&=NA$6&HK)9GP{gh44 z8Wqb8t-O^p*5{dTbdZ46Otn*G8rLyX$plu|XJFZs)^}k!r5l7;m7MO6-Qj)gX>(P0 z%?(@FJWH{F%`2X;X>Ja8L)5eL<@OeNborZ%^xJv4PmoJ?^N1t>sYtLv9}}sh$P~214<@{Ij9m z38&e{KwMgDUyJG!mqep>R(luqWNI}~C}P6}D8_T%2!QyZsgh=T$A)N+(U?df%On`E zIyR#j=CnqN!^K6pKo^v)$KePcruAzn6|I317KP%#T3R`++yXu7)#7DatI(`2#RL492`EdvWq=C1 z_Ic=MvVD<@ejPt1t*6ZdLR^3;VNP-N4SxN~{LIKRsFOjpv9_i(!D_s*`hPd0Dv$6j zaJ4}+pj@FLYOcjv6r5;o8|t9Nc}8SQ8Kz=F_52goedu#1T|SRLGZ(k2`BBBH0P< z+z9|^$x7x+LD_*hi+xSiNeKy?afFQog3eA*lbBzdOSi8Zc4QY)?CLAKn%dfo<}(@E qz**7Z|BqMrMWX-fIQ;)y^i>c(a9fY2S;&WeYyj^Y;M0g9{_r<>U-jDn diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.png index d7adf538b5b232bdecd46d03b0f576c62e04448d..2ef28f8495324966cb8c9f82b43e53047f06505b 100644 GIT binary patch literal 18824 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 X^_EKbo%~ps0_42fW!20xrhoe%Z9Y^* diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_dark.png index d4b88c28616c068185cb8557ec1caa7bc0f6715f..544f872966ca22634c0e717581ae0b70bf1cc348 100644 GIT binary patch literal 13933 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 F-vBw;Ut$0N literal 13765 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 YmiIj2In9y72H;0s6{(Vc-YWP%0FzcV%>V!Z diff --git a/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_light.png index 2446626db85d7d5db67db1a6f36bf6adc18e0170..ccc1748279f4537b925286ed2e90ddacb93ef3ae 100644 GIT binary patch literal 13827 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 literal 13649 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 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_dark.png index 76846390777ea0d7bf90f32a88b986d90b795801..5cb8ad9f3e1133a8c3441fee453c58d1f307efc5 100644 GIT binary patch literal 3516 zcmd5000WkPWB!EAdUq9F{q3bXwgFS=YtoqC=W+F;K_g{2fUGtvUB#50e=ZH0U01E z(AoZsS6uNYR)5Y#!Np$Q5-DnKAPeD!FNV9BXQB>gypyZH2fLxCD8FxytN~J{gQ~0y zy@#bs&ne=%r5+ItoSazN=Z`H*6g6j4E9UJw+r$2R zH+io3dfU2S<5}8 zYZ#(*Z7hVyNbLaoF@9W}uV}Rr>~Lg02;2LhMd^aLJOGbexB7zGP7Y}MN2BVShKOGr zM2N@2Li$=NnS@hv{_VSf4{L0z>YX+ap-U9X6}y{gD!k#}6a1X-2#cZ_*U9+~pTx<% zA`AqCJB($I6*bJd>up_!Ab`z{Ns+J1K5~?R!w&dyj%%IDknR8`U z&o-BCrET*&Ud|UMysvlWxG%f+bSC-jbiA4E<0QvClxw_FX{F&v*&sCvc+**rD!mDN zx3b<=8}cR;V>7Ae2ILkR`n?~9mD7d`Zr-&L%kx4}!a?xSKHzSfYa(NYe)shadn#DrE z2|TpaIu(fzSxPjMI%%9o7OP|6*mjTG1l7Z4wmA2xQL|kSg80zUyZR%k3~I&q$wtqg zko6G~!S}1Hf_@mkWQ0hQK;zs;*7BAdZpO333w7`;T{(Rh&@`48i*f^eUeeQtC+}xd zV=PRTIJ|N+sqbg;k=Oo7?E*q*YTL@io2tzl84PA`ApGBT-0rJH_xjHU~7E!?3Vezq=r@k&Z`<)zrut`5a`0;pAj~H&C;~JR<&))#jh#hOaN1T>YkmUiz@~{O~2i>ALbPiXu-8wKL=W9 z<+gIENOrU(2~OCRV17auki{3zG*}&ST(bJGVpFYM8{FEtN@OmairN!4R8*M#-EFnA zgDD6VEX=3;x6JhJ_rqo>_C%BbPDHY0q3U7b+(@rHL8xt!7iRynXSan|B`j=Wang?? z%dlB)as5q*B22{Blw=dy-VUqa+$15{7VlTI>wcUL`*|SS;Yuyq3&Rb$nM>JlnP2TV zv$DO^Mq2mt^z>wMuKjSL@E3&cq^mels>t4+tDAlJQ=77q(rpTyw9y*5FF-24k;?Hq zD*1JL?yovRxYw2&JAx@=gjk9cSd)oh*qzGCVe(Q)#P&ZYqQqjuVd{BgAbwW)NVdhn z9B}g1JFqxrq&U&x-P9D=wd2xhXWIFa<0`4hvb6?DNF8(RLm)@CRu@Dp2u@yxPl99Z z1k>DGHm!z*6)~txom}U~HP!iKv2UAS5b8my8MuF}M*87xqnemfg$>^#dQ+1-L29v( zLEZnvzv)2dp#r(mSGTOJ@N0eD!)Ds)puLBU_iJucP79-0-_TJHjp(Hj4NYSf_WRg@ zy;R23Gxo=3X0O!`d!}3*$6g{5)drfI^r~mk+`57JdP6+B#{p`hm09?elQel9*!iWy3TC;E=p|>X>VV1Qib*B80dzT{y7G>I!OmI41CZyCLyikdD%kuO;5u)VhlF~|JO&uDtqhlPWJ8Wp5~z_`Ws6H zF&m@?lv@f+T>k1G9cnw3{F@T4xV+=F!72qZVt@Bd$QqVNp;!ufs%X0BhB&dp-g7!y zTjFqj3XUO&?~#QDEB+5rs1@8r500#@{Hf>Xeg-v!o0X=0ZxB=kNeJ?Kp6sG@FXXHW zR@J;Ep_MOLlCJ5i=L)LFY$wGKAr@Rpb4z%^m)r|aMY=~hqU~d2n)u(8AOj(XuSpSS zB_Zk2voFe%8~8FM$h+1%8Z_M$2DLT*aJ*?CM9Ub|i`2q&X*RjnABvEWguIWo^yIxX zOIG*9)Cg7ZVWq$I$|40>&UVvy|5^VRNMM0h_H7$MFD(dASYNK$$rSjzYlssku$DW1 znu#k7s6jyeBN)#FqILZt|C>f zi+rubsaOS%cyOu@hWcfES}-)#eB2ux&nh$ura!7w!$jCLo5`C#`%fhQLrxx9vY|h| zHu%BRmZ|gw;Od}b{nwMvzj~E@C3XIqk6&*$xA(r0^Ar9m_yq~J^!3nA;c AX8-^I literal 3501 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 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_light.png index bfc98328480fc723e87dbf0f7c9f2e909788bcf3..359560bc3ac3887927de0a95a66ce5275453cd33 100644 GIT binary patch literal 3528 zcmcgvXIN9|5-w7XB3d&YVa`P@+(K;f` z@gnY>%p19==VuGCvR%?>0brSm$$)MlQd`m~J2>6>rmOiB3>8B--p! z2#MI`@qN%$)e>93x%He(1vncpqOLDgSzfl?T^B}S1cYy!iiz_L)3xIyUaV1Tnzivj+NC7TJ% z0KK_SK2|BT>A6tB0R_r#Ilg)KjUCV$6R0R@f`R~|Jr5IErwk8H*x!?F5tL3fC$Mm- zzUgcC78|XXS#d@pwt~7dePGV9swZ0CG{*WPY&|c07LS404 z#4*9F@(&3yqnmWf^kb$hN@6OUg|_jRY8EziE-%*Q`6u?Mu*}0UO;`t2(4|Z)z}%F< zAqopB)P67TH40bK=pD4w>>@v_YSCFEXQimoCj;lH(~dEb37~(uA*NL>tPnx9YpnOL zpq~vja6co{ES%J|uhUo+s)MqO)S4|If7U8ZOd3a9JKh`I=nsn0X=Zdk-Ws*ynwHpK z?oba5w?p&qKC0EXnTuhF!_ve#scr-G)0pkgISI~NBkMgkA?{g7u@2|UJC5Nr8Ddxe zS5Jz@>a_ysM1sKHTp9;-ePA(Ux>@E!6mk)`3vo%L zW|_bCVoqp*{=muKjas z9)CT_e7CKX1l`L{JLA94gc6q1pn`@wE9PFx@etm`=8TD?IoH3XAIs%r-bncFh7;aB zsx_~XL48|8=g8F)vnphd*0W?LypyB_`bT^L-_uWg2Jr4>Z9KAZ^^6C$x?RKPqI9#& z+nq3$hPT+_^L*=PpY#hwK?A*CDBlYt6mBkOIt`QO=19^fMm^zF>bkfCs%ckFCl0;a zX3>%4TtR7+mw_5yj9ZpZ zTl3Nf2g}({`(LG_v+SHgqGJNVves4ttM!p7*hgoDz^Z%ymsk}T3ZzUtY;#2p4go&v zqxwA7*4FUSKyA2DS~k0=4PgxHTPwPURNIM= zxKj1pR=xP9wRNVwSZBY#hRy3Dy4a)~n&fM0Zr1)g{bq23d_nJJws@OYMHkI;PImg& z36sk!t*_g@wia>kIp!J=aG`)8<$6coqfeeKeyFhMVq%WENPeF&}6pV zAk*YSe&Kiw1c5IqvO|ieWJ4Au%RH31Zh1&keKO3!12WBFoW)XALR9fra@Y2MpMC0L&B&gygGMRAe01 z%(XwA|09tzv&DCq6Poc+CS89qSQD(n6WXNtf$rHh+kz zx%tysWO5vfHnI8>|y|`>XUH+4q@gz)XFM(zxJq{ zqM~B#g*2`oA<=p=-XtZ_CS)o780r+d2?@|FF^-9f0 zpSz19h-;`m7ziDtu+J#3`mLf=(w}9=`2;zPJ3h6cO++Bv@7|RvD3F@|<5h>9IL?>| z`P|WtI$l{h(07k0gLwBk!)9TVp{Q1?At|Y!pJG>B1eRUrU>#j~q)d}!9^62h4{4B} z8$ctcsy?H71zHq2CS3yCME`+1`4_HyD|*|&L}6rPmMX`fQp0F773{oYm0`9No=5tq ztGL~g){8~KsO1xOcxi1|8aL#xmf&7Ldz8dTm>-4nY4FDtC$Nl+IG}&LYiu3u-Qbq> z;QKFJ+@W9^4J+sn*AT zt^sg~9PBI)8-t4T<$kBm!=w4kQI>yHGA3fx!fn|MgC{3>+{?~0d7)x7_oQ$FxRmso zw+81xU(tF$C51;sHqx8OV8P0*b}x33AD2=U;OrdG8S6oH48tNjcB&toOWF_Q5;b0j>VJ-LkhCI(d|+-XV~gTmj42lbOV z2RJR)yXfo8uLAsDu&Bo$IoS literal 3457 zcmds4dpy&7AO9I?<*4MA!f?u^O`Q(m#3E5K)?_X*m!gm&&Fv6#>B3nq9U;XEVT#;h zT`=dkB{7?kFt??(G{Q9J7(2hM=k>hKAJ6OgeAn+r5AzdG%;Ix5fv2~ zaP4l#uAuzrChC$XzmA5ttQ#lh8Qm+ue>op4Xxfa1023SEhR+5HKM^dIe9RVb7ICxh z9>PRpf51|syjT6^-}O+pbvNZjynX6gz?)lsS!SOB04C|vYwyis21eMcsLmuE&%~;0w&JY7qjJj*}2MU_u^;7AK!zS~Dz;4&?go{~Ci{A|be6 zMM((N_Ms{g!jFwk5<+))&C8D}Uh5u(_YBX$x4>spqT-3qc`m})-;|+f@SzTpV1x1N~z}i z;8Lk^@3_m?J4tCJlVrYnbawgGTsD#xkM?y!7NFq=FL53(x9$CuPI-;aCP`zNqI~xh znsAXawI~Yvp+gaN2HVN}J**5`PTEWr{JG5YSu6h#u_`ZnF>Hk5&>064akudg%=fX^ z+tU)|RLUqD5D$yrTa*bkkaHDOJSNPTQ79fHAdD3 zigLzLiTukl<-0?e_2kl|#+#hqk<=#C6|TIpuV#rRX+2 za0-A{5Yc7I#qCtV}OeGI04TPDFwu*v=j|~ znN@ZNuo=!*{wwQ$Tdp%Xn!wBjqI}M89(r~3KKZf-|5KBK-4~j1wLOhb^pj%^%OP{>>jIT5ye}gLW z_S(MZD0Q5e*jIE)MkQ@up2L*z_tQ6yuo=z?F55Qc`hihj^R4{p+t5k<(5$YVy#=an z7`I}&es6(Kc)`vz?drfQi*m$$nnXCcZa!L_qpE_UB`86N!?DwR2!>EhH@nsiF9~S5 zvjK4~v}+x&PalP9Whnag$f(peG}cbtkq^8LZVC=BW*GT8g2wk+-}OAHoif&5(yb=f z*92GHzln3RV}bM@ui?VHMoPIkD6YZUD(Wy*)Wzf^r}@)JBMee^eKxb8B}v3tB;a@J z=rlC5%}dIxc>b~~%!2<_8EZqhQW#sx?9a!!8vy2QP)A^u9CWjua8`=f&)UcCnOLaz zs04TKn6L9-Q2k0_-tgE6GavMOuCe!2U{SijWIspQp)%q{@1?_vKZiO;L5LnRk>>Oe z^K8J85ke^%;oTxh1?yCkn+{QZVj!7;KYS*Yu7St)W+q~_K~A2|i!9>swdA$Hx^T-6 zJsI)t#RTvo%}dKJ-{wsM+P{i3y%0-#WUF-9MD>M z;MD%RiCEMeb*_dlb3aktQ{NG6;$iC#`D&OoVD5n3I9Ed^F=ArKItW56BAG`Q{mo5r z+zbZ}1uId5sGXrG>GN?bE!|K(lA!8OC zxt>hM%XQD26TaM=uP;l_CP6G8)US-Kk8`owb>Z&4bf0G{rB4OYrfv7f4M69Vl1Y8d z7@?JrMLozq7=z7eDOwnNe&)bz^Xl{E2~zM>X)xs$Nm^-P^tY_}_NwM>;FV;ZC^++# zqC4}|ez(x{nW)$8LYLLs;}$99iFKoWSX8T1zD1pq9u3jH_|Iz(>V1Ez$4}v(Dv}XE oHm3?I^>6C?FG~LZVfsSI4Bq=-%ens3;NK{~&K7O+*xEPgFHUZuuK)l5 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_dark.png index 051ec73fab9757134c576f10233c4d5bdfe68ab5..db3fdcd1243c2b7325d304c9eabcdadd47a45d93 100644 GIT binary patch literal 4033 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 J$}Q1%{sT?X^}YZA literal 4021 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 Ay8r+H literal 3993 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 P*MOrv(yr1r@an$+C!@&h diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_dark.png index b586a963a6bf02d3cc54c6527112f570d47f67be..cc8e59f9e634837d7dd5d34fa2dc170a9d1f0548 100644 GIT binary patch literal 3524 zcmdT{c~nzZ8h(Qs9A!c(|3_B^Y>O zVSdTLDA>;0^3tvRxshKpJtv~t`DK$4EM)jyYbJ?&0t;7(kUB&%iad$BXL#9JJL#7n znojN`xa1?LPwej5p*88_UqP#a;5^6^DV6kbcIt}}F*1D7ULr;HGG~cGlDyCmkjx`$H7=3$a< zb5?@novW8m()d2xQbzklwp}OIL&>CKBCseoL?S*QW zT%k2SzfNckf7rFFrUnYt-P1yA{PQ}Y^_60jP~BI)dp3G{*SerbD0V-6Sa24;%5``8 zYicD~l|q{PNsP0R6ToLbTe@j_2r81Y$;=E5-*(=_)0G_Z@zhkpuL1e9$16V9(W#UpdD1XFvTaVNhc{=w=AG2javt0Q6P%9gV-~z zoy4TEq`WQWC?~meu1XQHU4athhrW;&-GD)*YBFFV&~cxb4;G$R%oNSZ$%PAxk;VHp zq4*ucX~zfoevY$mt)O^`ji$^>J$|)HMr(@cS_9F0nLLpPTzE&0JR%6oJB`^>f^D1o znL{04g3{-_3qJ0E6MXP)H5x4rbl;kty6GDbP`9kGmak*u zF2q8%(jM=xV`4N$8`o?+<7OOH(ak|4!8)keg$M=n(9=}vX@unYviiqLs@jd(^zuUf zEro@KC3nx*C9BUQwtB+jb8{)id!5d&M3`-~@TVe7N+-bvX$B0~!@^bCbH(ePw+w9V zyYSR4(pC)n#$E*OD81~CR6sOhqGg9`5qcW*@{Df$0ou-oe*S2Ew!M=G+(#eYy7T{Y25g$=`YTm(5ke_SrVy!jTfQ1Z1cOr(R(u zu%h%Dq(!f-`w~n&qa|RPztk^wVM|pZEpD!rB21G6UpDlK;$`;e#mimx+BhMxmDZy- zFexsFyglw_-mDZ7RIHzXbTKUO5{YSkn%EQDt%eM$teTtVPqGSGxuWdX!Euc@V}cS! z7VBZ^)85(b#Zn2+`Stl9!Ld%MDIHSFrgV8~V;fuH1 z>f~_;PSVvL^zxXHXpE1U(!#X(XOV*HI!<+_699ggCtzuNg-ak~T!9Vv%KI277)ytCZoxM5I>DRSgU( z{74atvB!1WqtUIyn?DAtbs3o^^kY#U9pO;uFE}&sJggZT0bv>yDh1l9?bBF zmZr-9Xw4Je9b>He?@2(8b#`gBjQ=fD15X5Y;Ktt360^C@CEX?ksMk6Qrx9WoYC=BJ z-8A7&xNf|jUbPE)v|1#{6^*{=q^yPzi$nr(ubv*L)R<=0IY(8HG%r>Rttjo3YMFym z{MCIJ{lV{sh;QuUYW+>T_3eo_N~mGpD*5NbwO7`0=22rSGX5+BUEO^JDAl&H(82H* z4JYV$dZ_hyT+h_NILF4iWtQ8@o=n_2sz+}*=s5Yms)R~xG{o*cLi1Kbh{Q|m2X2HI zrBbOql!e0WnS~yT3^V5Cd-}5Yz(EGgzlM*$6fH`Zv=JrW5iG^gT?Er}hJP+AnVOs+IFDGd!_0qRp~8I1cJd5nG@h&qTs^E=dY~w| z4U5I5Y~S&ye*-|jg7Nm&0%3Q=bxS)GdS%RMF{F!M)iP>*c)c^F*DRzHkQ%8r_nDzv zSH6*rU4-T0!_Ooi>8G`Jc+lQ_DN61;B%2hvH5LeJv10iEPSV{YxOFAN{NqGP4e5GV z*^R90aqz&viqNSyw{;B=Zqc$I4Zx`wFE3J6rzKDQdlaZ{Y#tHp|1vo_CqJJQ%#cSj zNT~K=t$#vc4nW}mx+cH5WaXTpr1l4B*v+d;?9c5Ke+O&Q_0hV^s07_yrYuk&V(ipOa0Y)1)c^rw08AZAwsfA8nNz7sGf`2O{{L zG5}e2;&SYcrygC|6bnmHnZcJ@;CsLiaQ@Ms0Iy#-MTejt1VsL?BDDYk$%+>xdScZa zaV~83@BX8>+Bc}tuQQ#dS7BqljHL038eX8Y+6A8a$CCx}Ua|h3(c-c9ED0*3 zaWjn2iN#g`iqc8Qzy*yq3*Gd~$C%B|$JWiw z;+%p!9fZ_;&VEh!*O9@aNV)jICH4QD%72sH|9jDvj@}Y>2%&NH1^5$#?2styM^?CR Fe+L)1Ub34wq_YC;r(1Of!GH`o4u@B8Y@pL@^QYwdmZIs5E&bM=Ie z+tw|+w*UaJ)x+J{4**mH0YC+*p$^XM!Mw-^A1d*FZpVO{9z!uWfW;s4@Yeu;sTyHF z1Ax|J4`(NTa?!hSuiVcs5xQPY{1G47RghF)ob+~|YiOIXi|g(_clT|9?{|>DM8*nq z6hUqpn)}ob-qAEbT(xALZHQ(ol4kswnOd}V>nM5cdM)EJJ?&EZxhGXeDj7b-T#|hD zkqRKCr`F*+LuTJ~Sk~7ItJ>O5rmu$tKiN?d+<^G-wAtwS{4)M9eUK~}s#cV{0l==V zI5f4g|NL4cu7eQVweZw&a5z0aZbuILdWlPDGr-*Rs|On5EcH*mvumfkDgzcCK9-7{o@Yh zv?y<{v(k%w<=jW}Ogv;}t?q`*4;@`0b8R$aCWuZ#=5JO%vTr&Q(;Gu+QoXN%uv>;+c;i%dZ|> z=CbGCeH@~)u06Z$+K5vkC;v?jf&70qod#i1MGI79<|Y8|{$W>8dN7VzVyH~!ab3PJ z7G3yaYJqD`w=7`NpdEYMH^ay_V+F0f2!~t#YT`vy0d^6Baq|g|zBx)KHz4k0`Z<>& zemc?y;B1PqDQs^EZZS%)XKqh#3@loed{~+G0-@4xN!OJWscsLH;N(`pA>}b}=H^k# z1p*rx{ZNYJ&nmA%z6Zt;{6jAfHzFb;HZl!U6MeBgY^rzH`1`hJyVH{92xlnpwY-Y+QzMrqIu=O1MSrL^ zpTgnB#zwOZzKL?iJ?Z};Drg{aEtKR&G4Tbh_DZr* zU5t({psUK9`RsYot2SFS`WpYzYvXsNj^4S&$uWw-K znwgoElK{1txKzUi2ZwS}2B);~-7ZT{UqHS6;14Jeg&R&ZG&Ibkt7tuIZFL%Weom~9 zk5SDjZIo=b)ln!EuYBTs9W0-^D7_tl32^Ml67RFPSKBES@3>#wE;FW9&1@Z$iU`tN^fz) zUjrINIqb+Z)Ls{5IfQ{#Yg`CkPj^$WdVc+9Q#791B(iyVDu<^FOuE4kO-Ua%)}eR2 z3G9j}^IglZN<^4dPJx0C#^uqBe=zXV%fjM11{V#c zwooou6)WFnX<=Wl`Bun5JidvoFJ$UI=pzZ|_tg-_6Ov1uwgt)rsq;?9O?&XI+m2VT zZdsyk(p5;Nb)rYyaCk&P4Om;;ZmDI45z zu;uO31@*HV>{XwB>Y^V7NZ{6P2#3qffWEV;IfRJYri}e_&To&bKR@z&n&ss9A@7qE z)uO9jS+di7dyTejhh8vbFk4+P(*p%vAnVQD8edP}4D0QIveEai?m@CM+;&ei}&i-y-k4oJccTQt&7GO{csu7P7wuI4mUvJP zEVrg{Qf$I9Lk6FOQ?)}n1hdw?&7mjI-NmiR>lZAQVR+LK2a9{Wz{(>&K~t}sO2H04 z=bbbz=7ipuq3A0bdcQCU1#9W?Za3WZvw6!*dye>_w=U=!$BMHnY1IwXA~c~j>s!>M zj>&d9|MwI6de=KwK#%ziv+>|<%ZH)rGcM_u&-<33EifuP4W#HsuH%O; zo-XPkFLUwLPyn|ify6HZf9zdi~!ebYMg3o|&=7;VEd=H5i?KxkyO z3`WfOdo&m^tkje6w6rD}3}u_?f-OJ=$JN4aTyQLLxZ)D4nlr^_vz3t7oiFZ`n<+I2 zl+J@8NY7qCo#-?0=Ik_OWL?E32BZ*fQ%UrHUBtT1OQ+kX?6c_-@IMXU M;o{?5bBy@?U!~k)lmGw# diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_light.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_light.png index c5e25c2f15a2cc429819a7f9279b2311d926b420..6908a496f96d5d0198b1150ae20a184941cca77f 100644 GIT binary patch literal 3431 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 ZyR%v^c+;5a;GZSH!Pd#9(%SFFzX7y*vts}N literal 3272 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 diff --git a/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_dark.png b/packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_dark.png index 0622f6c5b1dd9e34fdf72e1d4376dd47c881d844..cf03f55888393e076a8c2f0c5619ad3caadbdedf 100644 GIT binary patch literal 4068 zcmcgvXH-+!7QP8xKtwRoL1chYiZl@ff(S%J=_QhYKu}Q>3@sS?pdtjw%u^{NO?VOM zRTFBEA~ryZ6bVHcga9E%LW`7lgKxdR@2xd&=Kk6D?Dd`9&ffQaC&|GMA-YFq4*&q7 zHfJoI004>v0EmVlKd4bO?M?>;B*Y0}0aWzJ(ZL08h=q-dAoxTH`rQKnu{0aYQ!WwN zjPWtzgSF@`7IU$-R$!HvACq98jY(k`C!MGL^SrWaIo`*r_~=SOn9EAgTr@#D@;*F& z$DD+&qu(iYxmK#;RCpq6I#VV57l^D#=4tPPBkhYmm+_x|SASmZGuycNB`dnQ0;gbR zvDhA&du4CxL9eJ{SpZl&6XIj00N;4KK1^VCJrZ8VZLL=Zjl(X|HoTj*>Wc~no0{shyFglpVZ-=6+k;HwnijaBtho5al)152`;kDaDcM*@nrgQ07j@WI z>9DOg1hDe69(tW%ZygyLin&{n&PIwdlsT$3yfDCl zmT#2~VmNI|Kjh1N%iZ-Gr61C6eAjApanEl*RRM7=uESiv<`+vbenJ{RKJ$a-t{LI5 zWQ}+}V9?rAnH$72r^H+yI_Fi%Hpqdr^12@>{@vNNeh@SN^l` zAJUG#o2B^?Y3?>DBx%<=kEULYom_)}i% z<$2A1cQ^N?c^31zN8e)Ibk>kB`q2a|=kl_1tQQ#KBMWOkQJgVOl52THf60{_sJCzr3r|@=-UZL!IOD1boDqU{4y%)7U@6+$`*U$#!7|4j*UCF4psE9-@7wyQ#8ne z5J1`YMwD%~NvKMTwD=^075*694eV47$l28Y!=TPb7y?|IOE`ML{-q%fE+?=w6)6Cp z{~l5cMm<%CPvw^Js}MekD{sm!{8;}yw0q7|dbAtdtm01IG~{LlEWOXM=AJG^7`LCB z_LNq%+b$q%y^dRGU?H^em5f%yo~8b_&2GxA5G}X#3{2Q1qmPVmx=ky8amf*D>zBTM zq57&tmwkPMOV}#wmSp9l$}N$f(Aj7YNhF&(Gvw5S`x1&iu@*?9n4$1{9bUZ~`tG~d zPV8(aGKhVB)%_t;xG4P^8SSQZCo)@oT_qr(6g%IcJ6*||c=Ar}j}((j zD=9hK8$YSjR3{~1w`t+s7uzr%m>oUKIKdiXA-w`0=JK$Mt67??b&1}N)5N7z>q1BT zUYc%G-4yK5)@-w0(dUe=iv+tOXZ)V`T^_as?B(Lhojb^AU=$M7H`hB+!F^X*FnCm}Y8ox03yK3owOX0+UsL}717 zlCHFBLJ2L$A{l4pVz)l@>&3}@9}R#f2e?;0$c2bQ2{G>(;nOQS8_YR;_ks5b;f?Y^ zn@nQC*vf?F8wsQ&ZfTK@L}zN7@<;)~%ZAgm(E-wxxYmLuJ!X?99(v3?+j&j^N+?K2 z+3MgJhNLS1kKfYAAm93DE_nV&*{uan2@@+k*MV8sSlQHd6^E2Q1y2$4`6u0Pkq^0=A zPq0Isp^fAInwsgk5Rv?${sJ{`$)Bp!pY-{kfIwvn#u%%id?I*mKmCK-Tz+69DP@6O zbw>41sYEjrfaZvenG9QdAdV=G9Q;^~={n1O#}fAaUp)M|Xxm8wt=0i)Db^tr=?^y# zq~4vCbT~^MOIr0f={D>JPDwpmZo~mfh<9;yJ!jY5k)HJW>5-jxk0)h4$g-QG1wiRMvVW{ zBc^;#f*RK<`}{l7a>QPKy;;ka%ok{H?;ZgGflR%9ys&46I!5w`4_BaHC`n1n6Er29 zNmtB!LH&@wzV9`B0A1R=fSz@u!q+hpO7M_X%)3|e?RQZr6<62Jk&*O%y?iyUT2@ip z6fy$Dkc&^oTa_C;@`~h3@b~j8WAn}>wH6HBr77Hw{{#1^Vfj?yAo6g@ku{^X)P>sO zu4$eDJ=EbgLVA73>C>nC{Pn@s0&`qYu6kM>$cg<34Zv)6x>My{Kcu+FaB!p|2Z_(g z4IzJ5GaN_b0rq_`eUh3;b`DDHrNfL1&vmUH{GdnUIQU`ePgAQ3zLED)79kdORHpCV z=$%?eQG>$q3!0_`8GrH^NzL4zru@&Lh8#P(5bb3m)?jdb>K5&J5@Om`V8^)R@n!ne zL34z+V+dG8l$X~L(|G%@eH6~GuRhzAm(`uMkIMy*ul$)x6{kC`IGVNjg1Ui3NBfU; z6k^$}WJ_4ywX4|be;3)Kyc3C9{yjIQ8guQU33-RqyIKETb*&>rnJ|V#p$Kla-i|?_ zpM~&7>@o*Um$vLkE8b$!wljSF=Xxei)_VG3WevYnJj?}5C6I#?ZEfBDnzx>#`d2~E zv~6m`G^JtX#BZI5x^x%@i)~?x%w@IuDxn+kMni7nM>KqVuOmzvceI(t6=rqO!S*J# zv%Ld2M|ePKDV8xm)32v=2ZV%GHdfGWJFGh^{2Ut8ek@Sw2S14+hm$YvhBg% zF52RUerKhe$~Qhr;=(Rm7|#^Ld0tq4Ty4H3q~Y!9@z(J89~6S7 zVl8AauN68p^KG%1jp@<$OeI~4=lh|0*Eu{e$-vFih|WX-hhz|Ssl0hV9KO;#I4uuf z3A)7QQSbBUWK@hYo+jgmSHzo{XL8USATsn0AL0fLo!EC$=ghW)M45rP#Rm z=|;hLN%zXUq*xA-nyR+8ZDZ0hyHFh#JbWW|b&-_U89?RCQgkCZxq-YCcV5`9PsY7c z4eeU?2W3b7^gN}zV>QcEr+H@E|9BS$d-ZsrhF2QF-TpzYP}L`}UWZ_)VNCUkHC-C8 ziV%eX=DHx$`Sl#g;8Y|)#_}4ZQ-7uEuB{jl6Rf#AT$`teqdg%~hofag{Hoqk@Jm5~rs_Qj9a^S#%P znnI+^do;mTP@jJ>PJECHh~y_Kj5_0?yF}y08sp~Aif0Ur3>bT0okAMPCqvhZ`z7Ka zHEXS)Q7&mgtjVPm)3ZPp1UY78AWvK}LgM)aHQog1%dpcz%b|iF@JljSBcO zwg|<_yU%?ud}AYGei`BUSzzf*Vc)$XvsnGT@-Yo;$#r=zw#DSF>&(ZQnVHGMURyq8 zRgmA}R4aNtkD3ar`{6I67GompO}>qo z`B+Vc@DV&NWKyNU|9#h+Z^30{b?DJwAa1U%`UqY|l7P~EG-03Z0H%x#l9ba z9Pi5UT=Sr^mZC}*>`dfoaS0hkr|tC&1In}|oB|P-_|4~0$!)hTsBZ&u+7bD|P2Qc* zWGD5ugRiUwB_*B+@ZURce^bdq%2;ufH5N=`HWCnd7w7zG2~2>ljW+q32#^Ri! zUGE)0E^f@>`GDnglM^Z(E_L-Y#>&d9k%@_4cQ#$*<>-w#-1@}#NYPQI^yfHtrii?r zr;aHEFfzTxj2ZhHGxPD;;X14GxL8Bv6D;b-vi>gv0h^H)%>zr+ib`1Uf}@Z&FqK=h z@=nSXFq6dO5+|0Z4d-(IQ41vdywF&1(V#PxEc06+K<4}O=Se*pw%&X|dyktRX!cOf zU+V?G9B@JTrPO7J2=L_o<#g>70bmd|u%8Pf4*t&b8gl$N4;Eyf#Z!9@@VsPysNku6 z4gbMae>h~%vo?f{^Q^O-=KfF*@vJ`}qIuSap5r`ggGVr4kQm1TF094w>95?Fyl3y- z=Dwu6;_e@6_+hSd{effqgUBDzeY-5Ux%hiJ`z2mKogJ&XkE;zo>}TP8lAgkIjPEGV zb-dF3@7BNaFaD6g7tmAhGh9XlU>@AM!?AMq(kT6vI}I- z1oBYks0}ZIOJPp%i1JAXG}q}Jp6%3Cu(EF`a!SCI%%`Pmbk0>;$4O^r`peWeU{j$J zjr(f>U@>-#n;4)*H{$vM&a^u6>XMLE&dXt)UtF2{$|*h*J8pc*yV(zUK-Jb%9w5#d z%Zq7B@Qf}ukrv5BC%@>->Kkd-;=(039L`bI9A87FcE4jX#a zHQ2S4JH%rv&gxAX#_nLm!fa36+OUpGW%3#vE*m7T+twI0S5`U3Fei(iD_{RU`?#en z>G427aBy&2&&rBI_Bqh)@gZi+OlvzjBIY+7TV`D#weQ`Pe+|-RXZ@R_wvcxC5w&&1 z+iCr3FOu8+`#*94;LH{g-;aRK1AOeBlh!p-H0jjyE`1p9%`j@W0K;n6a z8-h6j4`FpDPPWU2A5g9jqxP=GFcg>1q*&^Fn;^-5tnoNvx(iVo6h@XMtu5X!<&%V< zPjlT47lk#=2^-~i`bmY6SMsBTi2G^}g$6|#>=75Yr2+me({IiOhlJ*r@ZTqb&~Xtc(Y{NT926U@wJ5@$*jx1npE`I8k?)4r^rX|6`S^*Op2{~|V? zyiOl*z%QnxP3xFvVqo}C3jtUg!iWvYD&v=Hf90m5X*OkHhrcvwYwZZqWgiCQzx6?o zP{PSIbs0a)h8UPH?#BY_A1MUkyH_ zYr4CE1_DyI#y?Gxl=C_(*eceVwS`)6c>CC@F z#S`k|tq?~q@yi*MSB?;B8>C7?YuGYVd_=b@E&_&^kBvFub4;T(QC-GoDtGis`{vG@ugG@40`BxXpI;0 z7Zo%LgLoAhb^!?qhirxpT!Wy`1;sYuGy%<)#QTONEoFTsxV`>)lOYd!=SBivedE-` zEHNuobFdFk!2~wH(&I`u$-d0=0ESlh0f@*pmOKv9w!30-BO96>LsCYu98gY3;cWG4 z#EHMH^`~*W%}Tm^^zN1FN9k54s8`lq5({rKTIfUMbsnfZyk!1u(-$2;)$j>nJYAnR zn9Op1MPDsBS>_S#YoeH6YPrkqU|zrUlxwr4b-6tr)*8Ly=?))q@S;}fx@XjwayWg} zO*niXkk{G3<~Nc9=`EJF8>hLfzL@iDEnQo65OK{F2~k0V#k-Zp0Z%dZM;8_?kKIZY zZySntmalGep|I_9+o`8bmPz(6!M=pV#YxPtp0GueW;egj(Qo3tezxr_j?u5uKbCHo z=C-Fj$fA0h^u>YQDT3iaPT|?28gvjk141)bt=t=%CP(@&X`sc4@nIw|s1qrcGkd=+ zbv$w*S(bSH3~pX#FP#Z@CtLYNP^PDoR8+o!GmLt$wooWG_5>O3`mS}%E#Zq`#7Zd< zho`$xmPZ*RL@9U}Kz7>Fl4ZcdpkD&>xw3TTOpPhnycOZ4x0?UdK6%t7Ca zY6G1I4(3H7mdt}VHuKhc_zV~yMW87hBDRQAL=%r=zgoziV7KTw;z|1{8F z%&#&IqfRF5T(NqswlLD8)-k!m!Qz%6hitt0s4-i^IrN(C=`RiS^{flfwUM1|kLK?* z6#ZF5GG>M(m?BeOKba2Q8HHwDh5oq0YS*Nwc3ss?{2j%a&ECmEaadj*RXsb`E0p(X5j3B0>^}VoT#UiU1>%BymOw zq@C1$10XY8{BNK2;0yquYwKtiTL+_|i6r8;ogHummfQMaOCr4XL_#VgT`%k}@Z6l~ zmxdAhQ=+$9Zmxu>gY-|nxoyy52(hbW92%4_z-T)4L{a<^ls_vHp z;BwMi{T#gM4w>#MBLYpOHG{5&>V}m3=z~0^xgRO+0_{Jnl1V;rPr%L!uHH5>+CowWnv_&ANO?y z$y!}mI9dX;rSSz;4+XZ*6zEak&j&KJmPPpGh%a9>DUm((CgNtY3$v))#Scy#jrj8Z zzR}Ct3rOJvvxUYvY%C_(O-U>*Vqv)IQ$wQh!8{wrDKmQ~xa^T<&j@vOv!{@Q`A1v_ zo$;gDwmDGMx#3|Sa3`y)uk#5Dt6^(Dyz^$vU0Y9&`uYC-uj|!k1AAq)mA))b?OPS! z<71-Kjxdb;O~l_74)0@JD;p1`dh4fqQoN8-Ci;4Oh5J*QzkD7mGZuDm>MA$0{}$9<@7MJ71M?>i;?rD3p%O`& zN$wYjB2ZzGrGG44a4jPYo70NzaBJFGUm z*2$5U9nvqVHXoL&7>^voCU>%R?9Gz5XY! zgEhqt5LZiWZQuR8=;(Z_r;CK%oBSny-<2T;qJJEGoRiMY-0|bLvd%Zw)fHD- zm{_QjsMOKeZFfgA4(mpgNp3?_s|W>d&ZAdpv2iF$aSzJNZ~+Kx;7vzMS69K zZzjcF^|%8{2xL{VBoHfbpXaO6-@iZy{-6y)(f)a+2Eabec_C1z{Y%rDucld~DG;}R zevvQs^mYoIFXn3ZhYBBsR^~_IqqvWs7Le797!{z@pLP_ejVoje2$oA(3DmLnwtTDT z=YfJ{gS`L*t)pLKv(jcXE-xRkeU5Lowd~D!)KcKRY5YvCz;MIAGT$s=BQ*KoRY5KP z6j;}pFHhy8hZ*Op^4X03R$={dzw!xbeLeE|e z?I}CoG+;(=&wh9Iu1sf=s_Dnw@4VaGGT_r*PTOek{Y(&7PUCa?Nth|{(5g=vj8C4P ziwNa|CFWKMTmv#<1Pc_(UiS+Eg(xy2@)fHN&gcjfOr}oOD3LALU!E?WMchqevmfQ< zr8<|W<~zeYof0%GeZJ#b5e#fV5LMZuLc8PlS$~GzPgX>|*25wDOM0^(eB(?g&4lZy zGrKmnrq$5{tkG6x_M@C}B<`T=o5@K+9z5FoT_1&%m6bIV`ANF%9Dr&S8u;u;^b`g^ ziP;GsL^oX#Z3&L5hw7G}wl$y(mK#XBa{1&|f` z=1t=^EC%d9-%t~iqH81)XUsWw?J-L zo(1yeS4SZGPRReIEgO58L{bcA(AL2PlxQT2a33$Q`o*6A{1Z_Ybo4Qh=a>Hh)W~oA zL=FTh?{D7Hpo-Ijy?lH~BS?$wy?CkZyF-zvUbKPoV3=XRvypola_#XnqnXdcSK4RD zouv-dEp>-lJrJUjxrho8MEG$g>T zO786+)kWsWd$_tyvC!Tv2I_GGc30%V#2#fSG0fH)frF#e|E$UUj>E*>nqH1WUqHFV zdOXZ7YF_F&GJK)2S;@gc3&`P=AG9^YPb+lH&R$_CS{5dEmR9(?#e#|UUPy+`%*1I+ z0p;tAY>JTb@hX}D%#Q}Mm~hXh7Y<#6<3;PgG}*s!M!DTY4oQFi5|aA@NI-W_?z+d5 z&5jkS8u?Gc7mapS?E>P#g?9D3sW&p!z|1fA#Ajw@%-K6s*zgebj}6<>k^5xcJozEz zqIIg)i+4H~|DHgPU1kWKc8s4ZQrChPU~wL>0KbpV#YR2zzSHV}F0dDGu^gkmw-`~Z zN=%jaZI&g+tq})P<6D>&j~B7{!CQ^?1BGB9vIv^t%xibgqQR5!B;}V7kJ8dg(NzXi zw`*p95Lz^`oJFw_HOP%`cy5?vO^q7Y{rzAOb8bl~qq84P-W)3)7lCAbWYjshd@|{l zX;*r(^#?E3%G)P$JDJEHRZlqeO6xdLSy^>ClLF#Lpbluq<=GK)ewf|WQudfj9K(q> z^|lB)TWukCoe)xf?Ss0DJ7va^Pbf8w9Zn6AmD4lhd3u*)BUskrFfu`-W>WWyiM;$A z6($IOL|E9cZ*#J$#V&ex>d7<#z+QWk9P{l#MIhTL-`TWlQtg?T2&BF$0Daa|M~|oX zIV)0hOS8wLhC|LZ7;NnI+^9b4s<)+*ptRGxl;!l`BFiv@OEvQ>Sph%>n z@y7?e&3eQmUpr&S$XTG40GXDill8OBkH;V9sgN7{9j!~2o67pR$q8@@wv1)3x4-^Y z{$_W;X4Lp{%tW8Nqce_{zm2g-_Eb_-Ok*&X<>UsJD{Lxf$niijk$c(Hq{!LH zvcAb$qO3RhA=GgGCDiwAY_a6i6G@_Fy}OfZ#VXOPp`l_G=%?}%Rf$n!hHb`1$VR7^ z1(NPh=-`h*=L#9_a^Q&-s;^7_Eqck#a%cXmPw{@BDdFFoS z7Ifj(W`s;zNc8TP0rSI+D+39o;)#Aos}c>Cv0CPvZ}!-)ZCT_d2ah=po5)_;(!zX4 z8wF1rs;!KkQ;eS4csHakWSCC}8+HzJ8qROFB9BOfIZ73fB)+a*Ji4GmW0 z%sn1i#T1FP^xOE>Uds`=tWkwZ-MvrOd~pY*dIUj*St>P32>sR52{>dxGn_>YD%5po zYG*|oE_C@gfTMB<;WZ8iOQQeyKlH?t=-41CN91Wro)-{dx8b$5+l(J9rHvb1bLfS% z`JjX#@Ya7{0h8GOconJF>dl`eLI(2n;7K|_Hy@@tJcMfrJ@Z5$?uZg+fhj;0jx7Xi z+c@W$`QX43+C8T59e?kp8dsc{tFQ+IGRyf!q=qEY3tL{JWO*AL{Xyn;dlw+_|7yxN5E>_R6 zqbgMbQzf)hdOmA(≺3Y3`7j%mi!?nBmXg2LggSK*-G)68?lMdDqtk%%Lp{c(wEl zxtT(Gbi=DxO1}F&AJ{#mPoIt<@Z4rFzLg zUza4zIaVE>l1=x&p`)kQz5WZiBTc@-b|xw$jO#&STbG+D;hd6o}7NOT$k4)&m+AFo||g_-ZUsI9G=O%XBb zKccM}1ogjXwml0Cmq#MKS=eOYzZ+y{?R=@?BI@UV1BGVX A8vp%7VWr+4BhipxAGH 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 Date: Fri, 19 Sep 2025 12:10:31 +0200 Subject: [PATCH 34/34] fix(ui): ensure dialog confirmation for delete/flag actions (#2384) --- packages/stream_chat_flutter/CHANGELOG.md | 6 ++++++ .../lib/src/message_widget/message_widget.dart | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index c768fa0cf6..66c196d656 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming Beta + +🐞 Fixed + +- Fixed delete/flag message dialogs executing action when dialog is dismissed without confirmation. + ## Upcoming 🐞 Fixed diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index 111d479f2c..ec54d488aa 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -1105,7 +1105,7 @@ class _StreamMessageWidgetState extends State ), ); - if (confirmDelete == false) return null; + if (confirmDelete != true) return null; return channel.deleteMessage(message); } @@ -1139,7 +1139,7 @@ class _StreamMessageWidgetState extends State ), ); - if (confirmFlag == false) return null; + if (confirmFlag != true) return null; final messageId = message.id; return channel.client.flagMessage(messageId);