fix(ui): not able to hide reaction picker.
Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
+10
-8
@@ -15,7 +15,7 @@ class MessageActionsModal extends StatefulWidget {
|
|||||||
required this.message,
|
required this.message,
|
||||||
required this.messageWidget,
|
required this.messageWidget,
|
||||||
required this.messageTheme,
|
required this.messageTheme,
|
||||||
this.showReactions = true,
|
this.showReactionPicker = true,
|
||||||
this.showDeleteMessage = true,
|
this.showDeleteMessage = true,
|
||||||
this.showEditMessage = true,
|
this.showEditMessage = true,
|
||||||
this.onReplyTap,
|
this.onReplyTap,
|
||||||
@@ -54,8 +54,8 @@ class MessageActionsModal extends StatefulWidget {
|
|||||||
/// [StreamMessageThemeData] for message
|
/// [StreamMessageThemeData] for message
|
||||||
final StreamMessageThemeData messageTheme;
|
final StreamMessageThemeData messageTheme;
|
||||||
|
|
||||||
/// Flag for showing reactions
|
/// Flag for showing reaction picker.
|
||||||
final bool showReactions;
|
final bool showReactionPicker;
|
||||||
|
|
||||||
/// Callback when copy is tapped
|
/// Callback when copy is tapped
|
||||||
final OnMessageTap? onCopyTap;
|
final OnMessageTap? onCopyTap;
|
||||||
@@ -105,6 +105,10 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
final user = StreamChat.of(context).currentUser;
|
final user = StreamChat.of(context).currentUser;
|
||||||
final orientation = mediaQueryData.orientation;
|
final orientation = mediaQueryData.orientation;
|
||||||
|
|
||||||
|
final _userPermissions = StreamChannel.of(context).channel.ownCapabilities;
|
||||||
|
final hasReactionPermission =
|
||||||
|
_userPermissions.contains(PermissionType.sendReaction);
|
||||||
|
|
||||||
final fontSize = widget.messageTheme.messageTextStyle?.fontSize;
|
final fontSize = widget.messageTheme.messageTextStyle?.fontSize;
|
||||||
final streamChatThemeData = StreamChatTheme.of(context);
|
final streamChatThemeData = StreamChatTheme.of(context);
|
||||||
|
|
||||||
@@ -115,12 +119,10 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: widget.reverse
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
? CrossAxisAlignment.end
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (widget.showReactions &&
|
if (widget.showReactionPicker && hasReactionPermission)
|
||||||
(widget.message.status == MessageSendingStatus.sent))
|
|
||||||
LayoutBuilder(
|
LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
return Align(
|
return Align(
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:contextmenu/contextmenu.dart';
|
|||||||
import 'package:flutter/material.dart' hide ButtonStyle;
|
import 'package:flutter/material.dart' hide ButtonStyle;
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_portal/flutter_portal.dart';
|
import 'package:flutter_portal/flutter_portal.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
import 'package:stream_chat_flutter/conditional_parent_builder/conditional_parent_builder.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/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/context_menu_reaction_picker.dart';
|
||||||
@@ -54,7 +55,10 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
this.attachmentBorderRadiusGeometry,
|
this.attachmentBorderRadiusGeometry,
|
||||||
this.onMentionTap,
|
this.onMentionTap,
|
||||||
this.onMessageTap,
|
this.onMessageTap,
|
||||||
this.showReactionPickerIndicator = false,
|
bool? showReactionPicker,
|
||||||
|
@Deprecated('Use `showReactionPicker` instead')
|
||||||
|
bool showReactionPickerIndicator = true,
|
||||||
|
@internal this.showReactionPickerTail = false,
|
||||||
this.showUserAvatar = DisplayWidget.show,
|
this.showUserAvatar = DisplayWidget.show,
|
||||||
this.showSendingIndicator = true,
|
this.showSendingIndicator = true,
|
||||||
this.showThreadReplyIndicator = false,
|
this.showThreadReplyIndicator = false,
|
||||||
@@ -114,6 +118,7 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
bottomRowBuilder == null || bottomRowBuilderWithDefaultWidget == null,
|
bottomRowBuilder == null || bottomRowBuilderWithDefaultWidget == null,
|
||||||
'You can only use one of the two bottom row builders',
|
'You can only use one of the two bottom row builders',
|
||||||
),
|
),
|
||||||
|
showReactionPicker = showReactionPicker ?? showReactionPickerIndicator,
|
||||||
attachmentBuilders = {
|
attachmentBuilders = {
|
||||||
'image': (context, message, attachments) {
|
'image': (context, message, attachments) {
|
||||||
final border = RoundedRectangleBorder(
|
final border = RoundedRectangleBorder(
|
||||||
@@ -460,10 +465,22 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
final void Function(String)? onLinkTap;
|
final void Function(String)? onLinkTap;
|
||||||
|
|
||||||
|
/// {@template showReactionPicker}
|
||||||
|
/// Whether or not to show the reaction picker.
|
||||||
|
/// Used in [StreamMessageReactionsModal] and [MessageActionsModal].
|
||||||
|
/// {@endtemplate}
|
||||||
|
final bool showReactionPicker;
|
||||||
|
|
||||||
/// {@template showReactionPickerIndicator}
|
/// {@template showReactionPickerIndicator}
|
||||||
/// Used in [StreamMessageReactionsModal] and [MessageActionsModal]
|
/// Used in [StreamMessageReactionsModal] and [MessageActionsModal]
|
||||||
|
/// {@endtemplate} @Deprecated('Use `showReactionPicker` instead')
|
||||||
|
bool get showReactionPickerIndicator => showReactionPicker;
|
||||||
|
|
||||||
|
/// {@template showReactionPickerTail}
|
||||||
|
/// Whether or not to show the reaction picker tail
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
final bool showReactionPickerIndicator;
|
@internal
|
||||||
|
final bool showReactionPickerTail;
|
||||||
|
|
||||||
/// {@template onShowMessage}
|
/// {@template onShowMessage}
|
||||||
/// Callback when show message is tapped
|
/// Callback when show message is tapped
|
||||||
@@ -619,7 +636,10 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
bool? showInChannelIndicator,
|
bool? showInChannelIndicator,
|
||||||
void Function(User)? onUserAvatarTap,
|
void Function(User)? onUserAvatarTap,
|
||||||
void Function(String)? onLinkTap,
|
void Function(String)? onLinkTap,
|
||||||
|
bool? showReactionPicker,
|
||||||
|
@Deprecated('Use `showReactionPicker` instead')
|
||||||
bool? showReactionPickerIndicator,
|
bool? showReactionPickerIndicator,
|
||||||
|
@internal bool? showReactionPickerTail,
|
||||||
List<Read>? readList,
|
List<Read>? readList,
|
||||||
ShowMessageCallback? onShowMessage,
|
ShowMessageCallback? onShowMessage,
|
||||||
bool? showUsername,
|
bool? showUsername,
|
||||||
@@ -703,8 +723,11 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
showInChannelIndicator ?? this.showInChannelIndicator,
|
showInChannelIndicator ?? this.showInChannelIndicator,
|
||||||
onUserAvatarTap: onUserAvatarTap ?? this.onUserAvatarTap,
|
onUserAvatarTap: onUserAvatarTap ?? this.onUserAvatarTap,
|
||||||
onLinkTap: onLinkTap ?? this.onLinkTap,
|
onLinkTap: onLinkTap ?? this.onLinkTap,
|
||||||
showReactionPickerIndicator:
|
showReactionPicker: showReactionPicker ??
|
||||||
showReactionPickerIndicator ?? this.showReactionPickerIndicator,
|
showReactionPickerIndicator ??
|
||||||
|
this.showReactionPicker,
|
||||||
|
showReactionPickerTail:
|
||||||
|
showReactionPickerTail ?? this.showReactionPickerTail,
|
||||||
onShowMessage: onShowMessage ?? this.onShowMessage,
|
onShowMessage: onShowMessage ?? this.onShowMessage,
|
||||||
showUsername: showUsername ?? this.showUsername,
|
showUsername: showUsername ?? this.showUsername,
|
||||||
showTimestamp: showTimestamp ?? this.showTimestamp,
|
showTimestamp: showTimestamp ?? this.showTimestamp,
|
||||||
@@ -885,12 +908,12 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
if (!widget.message.isDeleted) {
|
if (!widget.message.isDeleted) {
|
||||||
return ContextMenuArea(
|
return ContextMenuArea(
|
||||||
verticalPadding: 0,
|
verticalPadding: 0,
|
||||||
builder: (context) => _buildContextMenu(),
|
builder: (_) => _buildContextMenu(),
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
return child;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
},
|
},
|
||||||
child: Material(
|
child: Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
@@ -963,9 +986,9 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
messageWidget: widget,
|
messageWidget: widget,
|
||||||
showBottomRow: showBottomRow,
|
showBottomRow: showBottomRow,
|
||||||
showPinHighlight: widget.showPinHighlight,
|
showPinHighlight: widget.showPinHighlight,
|
||||||
showReactionPickerIndicator:
|
showReactionPickerTail: widget.showReactionPickerTail,
|
||||||
widget.showReactionPickerIndicator,
|
|
||||||
showReactions: showReactions,
|
showReactions: showReactions,
|
||||||
|
onReactionsTap: () => _showMessageReactionsModal(context),
|
||||||
showUserAvatar: widget.showUserAvatar,
|
showUserAvatar: widget.showUserAvatar,
|
||||||
streamChat: _streamChat,
|
streamChat: _streamChat,
|
||||||
translateUserAvatar: widget.translateUserAvatar,
|
translateUserAvatar: widget.translateUserAvatar,
|
||||||
@@ -996,14 +1019,15 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
final channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
StreamChatContextMenuItem(
|
if (widget.showReactionPicker)
|
||||||
child: StreamChannel(
|
StreamChatContextMenuItem(
|
||||||
channel: channel,
|
child: StreamChannel(
|
||||||
child: ContextMenuReactionPicker(
|
channel: channel,
|
||||||
message: widget.message,
|
child: ContextMenuReactionPicker(
|
||||||
|
message: widget.message,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
if (shouldShowReplyAction) ...[
|
if (shouldShowReplyAction) ...[
|
||||||
StreamChatContextMenuItem(
|
StreamChatContextMenuItem(
|
||||||
leading: StreamSvgIcon.reply(),
|
leading: StreamSvgIcon.reply(),
|
||||||
@@ -1149,21 +1173,7 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
void onLongPress(BuildContext context) {
|
void _showMessageReactionsModal(BuildContext context) {
|
||||||
if (widget.message.isEphemeral ||
|
|
||||||
widget.message.status == MessageSendingStatus.sending) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widget.onMessageActions != null) {
|
|
||||||
widget.onMessageActions!(context, widget.message);
|
|
||||||
} else {
|
|
||||||
_showMessageActionModalBottomSheet(context);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showMessageActionModalBottomSheet(BuildContext context) {
|
|
||||||
final channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
|
|
||||||
showDialog(
|
showDialog(
|
||||||
@@ -1173,7 +1183,8 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
barrierColor: _streamChatTheme.colorTheme.overlay,
|
barrierColor: _streamChatTheme.colorTheme.overlay,
|
||||||
builder: (context) => StreamChannel(
|
builder: (context) => StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: MessageActionsModal(
|
child: StreamMessageReactionsModal(
|
||||||
|
showReactionPicker: widget.showReactionPicker,
|
||||||
messageWidget: widget.copyWith(
|
messageWidget: widget.copyWith(
|
||||||
key: const Key('MessageWidget'),
|
key: const Key('MessageWidget'),
|
||||||
message: widget.message.copyWith(
|
message: widget.message.copyWith(
|
||||||
@@ -1187,37 +1198,93 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
translateUserAvatar: false,
|
translateUserAvatar: false,
|
||||||
showSendingIndicator: false,
|
showSendingIndicator: false,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
showReactionPickerIndicator: widget.showReactions &&
|
// Show the tail if the reaction picker is visible.
|
||||||
(widget.message.status == MessageSendingStatus.sent),
|
showReactionPickerTail: widget.showReactionPicker,
|
||||||
showPinHighlight: false,
|
showPinHighlight: false,
|
||||||
showUserAvatar:
|
showUserAvatar:
|
||||||
widget.message.user!.id == channel.client.state.currentUser!.id
|
widget.message.user!.id == channel.client.state.currentUser!.id
|
||||||
? DisplayWidget.gone
|
? DisplayWidget.gone
|
||||||
: DisplayWidget.show,
|
: DisplayWidget.show,
|
||||||
),
|
),
|
||||||
onCopyTap: (message) {
|
onUserAvatarTap: widget.onUserAvatarTap,
|
||||||
final text = message.text;
|
|
||||||
if (text != null) Clipboard.setData(ClipboardData(text: text));
|
|
||||||
},
|
|
||||||
messageTheme: widget.messageTheme,
|
messageTheme: widget.messageTheme,
|
||||||
reverse: widget.reverse,
|
reverse: widget.reverse,
|
||||||
showDeleteMessage: shouldShowDeleteAction,
|
|
||||||
onConfirmDeleteTap: widget.onConfirmDeleteTap,
|
|
||||||
message: widget.message,
|
message: widget.message,
|
||||||
editMessageInputBuilder: widget.editMessageInputBuilder,
|
|
||||||
onReplyTap: widget.onReplyTap,
|
|
||||||
onThreadReplyTap: widget.onThreadTap,
|
|
||||||
showResendMessage: shouldShowResendAction,
|
|
||||||
showCopyMessage: shouldShowCopyAction,
|
|
||||||
showEditMessage: shouldShowEditAction,
|
|
||||||
showReactions: widget.showReactions,
|
|
||||||
showReplyMessage: shouldShowReplyAction,
|
|
||||||
showThreadReplyMessage: shouldShowThreadReplyAction,
|
|
||||||
showFlagButton: widget.showFlagButton,
|
|
||||||
showPinButton: widget.showPinButton,
|
|
||||||
customActions: widget.customActions,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onLongPress(BuildContext context) {
|
||||||
|
if (widget.message.isEphemeral ||
|
||||||
|
widget.message.status == MessageSendingStatus.sending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widget.onMessageActions != null) {
|
||||||
|
return widget.onMessageActions!(context, widget.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _showMessageActionModalBottomSheet(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showMessageActionModalBottomSheet(BuildContext context) {
|
||||||
|
final channel = StreamChannel.of(context).channel;
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
useRootNavigator: false,
|
||||||
|
context: context,
|
||||||
|
useSafeArea: false,
|
||||||
|
barrierColor: _streamChatTheme.colorTheme.overlay,
|
||||||
|
builder: (context) {
|
||||||
|
return StreamChannel(
|
||||||
|
channel: channel,
|
||||||
|
child: MessageActionsModal(
|
||||||
|
messageWidget: widget.copyWith(
|
||||||
|
key: const Key('MessageWidget'),
|
||||||
|
message: widget.message.copyWith(
|
||||||
|
text: (widget.message.text?.length ?? 0) > 200
|
||||||
|
? '${widget.message.text!.substring(0, 200)}...'
|
||||||
|
: widget.message.text,
|
||||||
|
),
|
||||||
|
showReactions: false,
|
||||||
|
showUsername: false,
|
||||||
|
showTimestamp: false,
|
||||||
|
translateUserAvatar: false,
|
||||||
|
showSendingIndicator: false,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
// Show both the tail and indicator if the indicator is shown.
|
||||||
|
showReactionPickerTail: widget.showReactionPickerIndicator,
|
||||||
|
showPinHighlight: false,
|
||||||
|
showUserAvatar: widget.message.user!.id ==
|
||||||
|
channel.client.state.currentUser!.id
|
||||||
|
? DisplayWidget.gone
|
||||||
|
: DisplayWidget.show,
|
||||||
|
),
|
||||||
|
onCopyTap: (message) {
|
||||||
|
final text = message.text;
|
||||||
|
if (text != null) Clipboard.setData(ClipboardData(text: text));
|
||||||
|
},
|
||||||
|
messageTheme: widget.messageTheme,
|
||||||
|
reverse: widget.reverse,
|
||||||
|
showDeleteMessage: shouldShowDeleteAction,
|
||||||
|
onConfirmDeleteTap: widget.onConfirmDeleteTap,
|
||||||
|
message: widget.message,
|
||||||
|
editMessageInputBuilder: widget.editMessageInputBuilder,
|
||||||
|
onReplyTap: widget.onReplyTap,
|
||||||
|
onThreadReplyTap: widget.onThreadTap,
|
||||||
|
showResendMessage: shouldShowResendAction,
|
||||||
|
showCopyMessage: shouldShowCopyAction,
|
||||||
|
showEditMessage: shouldShowEditAction,
|
||||||
|
showReactionPicker: widget.showReactionPickerIndicator,
|
||||||
|
showReplyMessage: shouldShowReplyAction,
|
||||||
|
showThreadReplyMessage: shouldShowThreadReplyAction,
|
||||||
|
showFlagButton: widget.showFlagButton,
|
||||||
|
showPinButton: widget.showPinButton,
|
||||||
|
customActions: widget.customActions,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_portal/flutter_portal.dart';
|
import 'package:flutter_portal/flutter_portal.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
import 'package:stream_chat_flutter/src/message_widget/message_widget_content_components.dart';
|
import 'package:stream_chat_flutter/src/message_widget/message_widget_content_components.dart';
|
||||||
import 'package:stream_chat_flutter/src/message_widget/reactions/desktop_reactions_builder.dart';
|
import 'package:stream_chat_flutter/src/message_widget/reactions/desktop_reactions_builder.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
@@ -21,6 +22,7 @@ typedef BottomRowBuilderWithDefaultWidget = Widget Function(
|
|||||||
///
|
///
|
||||||
/// Should not be used outside of [MessageWidget.
|
/// Should not be used outside of [MessageWidget.
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
|
@internal
|
||||||
class MessageWidgetContent extends StatelessWidget {
|
class MessageWidgetContent extends StatelessWidget {
|
||||||
/// {@macro messageWidgetContent}
|
/// {@macro messageWidgetContent}
|
||||||
const MessageWidgetContent({
|
const MessageWidgetContent({
|
||||||
@@ -33,6 +35,7 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
required this.showUserAvatar,
|
required this.showUserAvatar,
|
||||||
required this.avatarWidth,
|
required this.avatarWidth,
|
||||||
required this.showReactions,
|
required this.showReactions,
|
||||||
|
required this.onReactionsTap,
|
||||||
required this.messageTheme,
|
required this.messageTheme,
|
||||||
required this.shouldShowReactions,
|
required this.shouldShowReactions,
|
||||||
required this.streamChatTheme,
|
required this.streamChatTheme,
|
||||||
@@ -45,7 +48,7 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
required this.attachmentBuilders,
|
required this.attachmentBuilders,
|
||||||
required this.attachmentPadding,
|
required this.attachmentPadding,
|
||||||
required this.textPadding,
|
required this.textPadding,
|
||||||
required this.showReactionPickerIndicator,
|
required this.showReactionPickerTail,
|
||||||
required this.translateUserAvatar,
|
required this.translateUserAvatar,
|
||||||
required this.bottomRowPadding,
|
required this.bottomRowPadding,
|
||||||
required this.showInChannel,
|
required this.showInChannel,
|
||||||
@@ -111,6 +114,11 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
/// {@macro showReactions}
|
/// {@macro showReactions}
|
||||||
final bool showReactions;
|
final bool showReactions;
|
||||||
|
|
||||||
|
/// Callback called when the reactions icon is tapped.
|
||||||
|
///
|
||||||
|
/// Do not confuse this with the tap action on the reactions picker.
|
||||||
|
final VoidCallback onReactionsTap;
|
||||||
|
|
||||||
/// {@macro messageTheme}
|
/// {@macro messageTheme}
|
||||||
final StreamMessageThemeData messageTheme;
|
final StreamMessageThemeData messageTheme;
|
||||||
|
|
||||||
@@ -174,8 +182,8 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
/// {@macro quotedMessageBuilder}
|
/// {@macro quotedMessageBuilder}
|
||||||
final Widget Function(BuildContext, Message)? quotedMessageBuilder;
|
final Widget Function(BuildContext, Message)? quotedMessageBuilder;
|
||||||
|
|
||||||
/// {@macro showReactionPickerIndicator}
|
/// {@macro showReactionPickerTail}
|
||||||
final bool showReactionPickerIndicator;
|
final bool showReactionPickerTail;
|
||||||
|
|
||||||
/// {@macro translateUserAvatar}
|
/// {@macro translateUserAvatar}
|
||||||
final bool translateUserAvatar;
|
final bool translateUserAvatar;
|
||||||
@@ -288,9 +296,7 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
ownId: streamChat.currentUser!.id,
|
ownId: streamChat.currentUser!.id,
|
||||||
reverse: reverse,
|
reverse: reverse,
|
||||||
shouldShowReactions: shouldShowReactions,
|
shouldShowReactions: shouldShowReactions,
|
||||||
onTap: () => _showMessageReactionsModal(
|
onTap: onReactionsTap,
|
||||||
context,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
anchor: Aligned(
|
anchor: Aligned(
|
||||||
@@ -363,7 +369,8 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
shape: shape,
|
shape: shape,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (showReactionPickerIndicator)
|
// TODO: Make tail part of the Reaction Picker.
|
||||||
|
if (showReactionPickerTail)
|
||||||
Positioned(
|
Positioned(
|
||||||
right: reverse ? null : 4,
|
right: reverse ? null : 4,
|
||||||
left: reverse ? 4 : null,
|
left: reverse ? 4 : null,
|
||||||
@@ -374,6 +381,7 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
Colors.transparent,
|
Colors.transparent,
|
||||||
Colors.transparent,
|
Colors.transparent,
|
||||||
tailCirclesSpace: 1,
|
tailCirclesSpace: 1,
|
||||||
|
flipTail: !reverse,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -434,47 +442,6 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showMessageReactionsModal(BuildContext context) {
|
|
||||||
final channel = StreamChannel.of(context).channel;
|
|
||||||
showDialog(
|
|
||||||
useRootNavigator: false,
|
|
||||||
context: context,
|
|
||||||
useSafeArea: false,
|
|
||||||
barrierColor: streamChatTheme.colorTheme.overlay,
|
|
||||||
builder: (context) => StreamChannel(
|
|
||||||
channel: channel,
|
|
||||||
child: StreamMessageReactionsModal(
|
|
||||||
messageWidget: messageWidget.copyWith(
|
|
||||||
key: const Key('MessageWidget'),
|
|
||||||
message: message.copyWith(
|
|
||||||
text: (message.text?.length ?? 0) > 200
|
|
||||||
? '${message.text!.substring(0, 200)}...'
|
|
||||||
: message.text,
|
|
||||||
),
|
|
||||||
showReactions: false,
|
|
||||||
showUsername: false,
|
|
||||||
showTimestamp: false,
|
|
||||||
translateUserAvatar: false,
|
|
||||||
showSendingIndicator: false,
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
showReactionPickerIndicator:
|
|
||||||
showReactions && (message.status == MessageSendingStatus.sent),
|
|
||||||
showPinHighlight: false,
|
|
||||||
showUserAvatar:
|
|
||||||
message.user!.id == channel.client.state.currentUser!.id
|
|
||||||
? DisplayWidget.gone
|
|
||||||
: DisplayWidget.show,
|
|
||||||
),
|
|
||||||
onUserAvatarTap: onUserAvatarTap,
|
|
||||||
messageTheme: messageTheme,
|
|
||||||
reverse: reverse,
|
|
||||||
message: message,
|
|
||||||
showReactions: showReactions,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildBottomRow(BuildContext context) {
|
Widget _buildBottomRow(BuildContext context) {
|
||||||
final defaultWidget = BottomRow(
|
final defaultWidget = BottomRow(
|
||||||
message: message,
|
message: message,
|
||||||
|
|||||||
+4
-5
@@ -15,7 +15,7 @@ class StreamMessageReactionsModal extends StatelessWidget {
|
|||||||
required this.message,
|
required this.message,
|
||||||
required this.messageWidget,
|
required this.messageWidget,
|
||||||
required this.messageTheme,
|
required this.messageTheme,
|
||||||
this.showReactions,
|
this.showReactionPicker = true,
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
this.onUserAvatarTap,
|
this.onUserAvatarTap,
|
||||||
});
|
});
|
||||||
@@ -32,8 +32,8 @@ class StreamMessageReactionsModal extends StatelessWidget {
|
|||||||
/// {@macro reverse}
|
/// {@macro reverse}
|
||||||
final bool reverse;
|
final bool reverse;
|
||||||
|
|
||||||
/// {@macro showReactions}
|
/// Flag for showing reaction picker.
|
||||||
final bool? showReactions;
|
final bool showReactionPicker;
|
||||||
|
|
||||||
/// {@macro onUserAvatarTap}
|
/// {@macro onUserAvatarTap}
|
||||||
final void Function(User)? onUserAvatarTap;
|
final void Function(User)? onUserAvatarTap;
|
||||||
@@ -56,8 +56,7 @@ class StreamMessageReactionsModal extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if ((showReactions ?? hasReactionPermission) &&
|
if (showReactionPicker && hasReactionPermission)
|
||||||
(message.status == MessageSendingStatus.sent))
|
|
||||||
LayoutBuilder(
|
LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
return Align(
|
return Align(
|
||||||
|
|||||||
@@ -43,19 +43,9 @@ double calculateReactionsHorizontalAlignment(
|
|||||||
final signal = user?.id == message.user?.id ? 1 : -1;
|
final signal = user?.id == message.user?.id ? 1 : -1;
|
||||||
final result = signal * (1 - divFactor * 2.0);
|
final result = signal * (1 - divFactor * 2.0);
|
||||||
|
|
||||||
return _capResult(result);
|
// 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
|
||||||
// Ensure reactions don't get pushed past the edge of the screen.
|
// move the model all the way to the end of screen.
|
||||||
//
|
return result.clamp(-1, 1);
|
||||||
// This happens if divFactor is really big. When this happens, we can simply
|
|
||||||
// move the model all the way to the end of screen.
|
|
||||||
double _capResult(double result) {
|
|
||||||
if (result > 1.0) {
|
|
||||||
return 1;
|
|
||||||
} else if (result < -1.0) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -104,7 +104,7 @@ void main() {
|
|||||||
message: message,
|
message: message,
|
||||||
messageTheme: streamTheme.ownMessageTheme,
|
messageTheme: streamTheme.ownMessageTheme,
|
||||||
reverse: true,
|
reverse: true,
|
||||||
showReactions: false,
|
showReactionPicker: false,
|
||||||
onUserAvatarTap: onUserAvatarTap,
|
onUserAvatarTap: onUserAvatarTap,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user