From 4fb41bf601763de9d7c98009a044d48bf956147d Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 21 Oct 2020 10:02:46 +0200 Subject: [PATCH 01/18] fix message radius and reaction padding --- lib/src/message_widget.dart | 6 +++--- lib/src/reaction_bubble.dart | 1 + lib/src/reaction_picker.dart | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 967fb72b..10298436 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -498,8 +498,8 @@ class _MessageWidgetState extends State { }); } - ContinuousRectangleBorder _getDefaultShape(BuildContext context) { - return ContinuousRectangleBorder( + ShapeBorder _getDefaultShape(BuildContext context) { + return RoundedRectangleBorder( side: widget.attachmentBorderSide ?? widget.borderSide ?? BorderSide( @@ -718,7 +718,7 @@ class _MessageWidgetState extends State { onLongPress: () => onLongPress(context), child: Material( shape: widget.shape ?? - ContinuousRectangleBorder( + RoundedRectangleBorder( side: widget.borderSide ?? BorderSide( color: Theme.of(context).brightness == Brightness.dark diff --git a/lib/src/reaction_bubble.dart b/lib/src/reaction_bubble.dart index 0d37d87f..a166e4da 100644 --- a/lib/src/reaction_bubble.dart +++ b/lib/src/reaction_bubble.dart @@ -40,6 +40,7 @@ class ReactionBubble extends StatelessWidget { borderRadius: BorderRadius.all(Radius.circular(14)), ), child: Wrap( + spacing: 8, children: [ ...reactions.map((reaction) { final reactionIcon = reactionIcons.firstWhere( diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 5855b59f..f954902b 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -45,7 +45,7 @@ class ReactionPicker extends StatelessWidget { reactionIcon.iconData, color: ownReactionIndex != -1 ? StreamChatTheme.of(context).accentColor - : Theme.of(context).iconTheme.color, + : Theme.of(context).iconTheme.color.withOpacity(.5), ), onPressed: () { if (ownReactionIndex != -1) { From 886b9faf3762e728c5b0e1d5f4ca1407256eb777 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 21 Oct 2020 10:26:36 +0200 Subject: [PATCH 02/18] fix message reaction modal --- lib/src/message_reactions_modal.dart | 124 ++++++++++++++------------- 1 file changed, 63 insertions(+), 61 deletions(-) diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index b30f92b3..a7557146 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -119,30 +119,26 @@ class MessageReactionsModal extends StatelessWidget { ), ), Flexible( - child: Padding( - padding: const EdgeInsets.only( - left: 16.0, - right: 16, - bottom: 16, - ), - child: GridView.builder( - shrinkWrap: true, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, - crossAxisSpacing: 16, - childAspectRatio: 0.75, - mainAxisSpacing: 22, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only( + left: 18, + right: 18, + bottom: 26, + ), + child: Wrap( + spacing: 16, + runSpacing: 22, + alignment: WrapAlignment.start, + children: + [...message.latestReactions, ...message.latestReactions] + .map((e) => _buildReaction( + e, + currentUser, + context, + )) + .toList(), ), - itemCount: message.latestReactions.length, - itemBuilder: (context, i) { - final reaction = message.latestReactions[i]; - - return _buildReaction( - reaction, - currentUser, - context, - ); - }, ), ), ), @@ -152,51 +148,57 @@ class MessageReactionsModal extends StatelessWidget { ); } - Column _buildReaction( + Widget _buildReaction( Reaction reaction, User currentUser, BuildContext context, ) { final isCurrentUser = reaction.user.id == currentUser.id; - return Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Stack( - children: [ - UserAvatar( - onTap: onUserAvatarTap, - user: reaction.user, - constraints: BoxConstraints.tightFor( - height: 64, - width: 64, + return ConstrainedBox( + constraints: BoxConstraints.loose(Size( + 64, + 98, + )), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Stack( + children: [ + UserAvatar( + onTap: onUserAvatarTap, + user: reaction.user, + constraints: BoxConstraints.tightFor( + height: 64, + width: 64, + ), + borderRadius: BorderRadius.circular(32), ), - borderRadius: BorderRadius.circular(32), - ), - Positioned( - child: ReactionBubble( - reactions: [reaction], - borderColor: isCurrentUser - ? messageTheme.ownReactionsBorderColor - : messageTheme.otherReactionsBorderColor, - backgroundColor: isCurrentUser - ? messageTheme.ownReactionsBackgroundColor - : messageTheme.otherReactionsBackgroundColor, - flipTail: !isCurrentUser, + Positioned( + child: ReactionBubble( + reactions: [reaction], + borderColor: isCurrentUser + ? messageTheme.ownReactionsBorderColor + : messageTheme.otherReactionsBorderColor, + backgroundColor: isCurrentUser + ? messageTheme.ownReactionsBackgroundColor + : messageTheme.otherReactionsBackgroundColor, + flipTail: !isCurrentUser, + ), + bottom: 0, + left: isCurrentUser ? 0 : null, + right: isCurrentUser ? 0 : null, ), - bottom: 0, - left: isCurrentUser ? 0 : null, - right: isCurrentUser ? 0 : null, - ), - ], - ), - Text( - reaction.user.name, - style: Theme.of(context).textTheme.subtitle2, - textAlign: TextAlign.center, - ), - ], + ], + ), + Text( + reaction.user.name, + style: Theme.of(context).textTheme.subtitle2, + textAlign: TextAlign.center, + ), + ], + ), ); } } From 3980ddde578bbe7b2a856d1748fa5f8417bab188 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 21 Oct 2020 10:28:45 +0200 Subject: [PATCH 03/18] fix message reaction modal --- lib/src/message_reactions_modal.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index a7557146..6ee5bf51 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -131,7 +131,7 @@ class MessageReactionsModal extends StatelessWidget { runSpacing: 22, alignment: WrapAlignment.start, children: - [...message.latestReactions, ...message.latestReactions] + message.latestReactions .map((e) => _buildReaction( e, currentUser, From eebe2ce171b57501046dffdf4c910f6dccb90811 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 21 Oct 2020 10:30:40 +0200 Subject: [PATCH 04/18] fix message reaction modal --- lib/src/message_reactions_modal.dart | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 6ee5bf51..56e49382 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -130,14 +130,13 @@ class MessageReactionsModal extends StatelessWidget { spacing: 16, runSpacing: 22, alignment: WrapAlignment.start, - children: - message.latestReactions - .map((e) => _buildReaction( - e, - currentUser, - context, - )) - .toList(), + children: message.latestReactions + .map((e) => _buildReaction( + e, + currentUser, + context, + )) + .toList(), ), ), ), From bbb71ec47fb6d1ba349654e87c04a9bc4ee7ba78 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 27 Oct 2020 13:28:17 +0530 Subject: [PATCH 05/18] feat: Added sticky header to display position data --- lib/src/message_list_view.dart | 278 ++++++++++++++++++--------------- pubspec.yaml | 1 + 2 files changed, 149 insertions(+), 130 deletions(-) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 7c529f95..42b434fd 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -6,6 +6,7 @@ import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/message_widget.dart'; import 'package:stream_chat_flutter/src/system_message.dart'; import 'package:visibility_detector/visibility_detector.dart'; +import 'package:widgets_visibility_provider/widgets_visibility_provider.dart'; import '../stream_chat_flutter.dart'; import 'date_divider.dart'; @@ -149,150 +150,167 @@ class _MessageListViewState extends State { List _newMessageList = []; Function _onThreadTap; bool _showScrollToBottom = false; + var positionData; @override Widget build(BuildContext context) { final streamChannel = StreamChannel.of(context); /// TODO: find a better solution when (https://github.com/flutter/flutter/issues/21023) is fixed - return Stack( - children: [ - NotificationListener( - onNotification: (_) { - if (_scrollController.offset < 150 && _newMessageList.isNotEmpty) { - setState(() { - _messages.insertAll(0, _newMessageList); - _newMessageList.clear(); - }); - } - return true; - }, - child: ListView.custom( - key: Key('messageListView'), - physics: widget.scrollPhysics, - keyboardDismissBehavior: widget.keyboardDismissBehavior, - controller: _scrollController, - reverse: true, - childrenDelegate: SliverChildBuilderDelegate( - (context, i) { - if (i == _messages.length + 1) { - if (widget.parentMessage != null) { - if (widget.parentMessageBuilder != null) { - return widget.parentMessageBuilder( - context, - widget.parentMessage, - ); - } else { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - buildParentMessage(widget.parentMessage), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 32), - child: Container( - padding: const EdgeInsets.all(8), - child: Text( - 'Start of thread', - textAlign: TextAlign.center, - ), - color: - Theme.of(context).accentColor.withAlpha(50), - ), - ), - ], - ); - } - } else { - return SizedBox(); - } - } - - if (i == _messages.length) { - return _buildLoadingIndicator(streamChannel); - } - final message = _messages[i]; - final nextMessage = i > 0 ? _messages[i - 1] : null; - - Widget messageWidget; - - if (i == 0) { - messageWidget = _buildBottomMessage( - context, - message, - _messages, - streamChannel, - ); - } else if (i == _messages.length - 1) { - messageWidget = _buildTopMessage( - context, - message, - _messages, - streamChannel, - ); - } else { - if (widget.messageBuilder != null) { - messageWidget = Builder( - key: ValueKey('MESSAGE-${message.id}'), - builder: (_) => widget.messageBuilder( + return WidgetsVisibilityProvider( + condition: (c) => null, + child: Stack( + children: [ + NotificationListener( + onNotification: (_) { + if (_scrollController.offset < 150 && _newMessageList.isNotEmpty) { + setState(() { + _messages.insertAll(0, _newMessageList); + _newMessageList.clear(); + }); + } + return true; + }, + child: ListView.custom( + key: Key('messageListView'), + physics: widget.scrollPhysics, + keyboardDismissBehavior: widget.keyboardDismissBehavior, + controller: _scrollController, + reverse: true, + childrenDelegate: SliverChildBuilderDelegate( + (context, i) { + if (i == _messages.length + 1) { + if (widget.parentMessage != null) { + if (widget.parentMessageBuilder != null) { + return widget.parentMessageBuilder( context, - MessageDetails( - context, - message, - _messages, - i, - ), - _messages), + widget.parentMessage, + ); + } else { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + buildParentMessage(widget.parentMessage), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: Container( + padding: const EdgeInsets.all(8), + child: Text( + 'Start of thread', + textAlign: TextAlign.center, + ), + color: + Theme.of(context).accentColor.withAlpha(50), + ), + ), + ], + ); + } + } else { + return SizedBox(); + } + } + + if (i == _messages.length) { + return _buildLoadingIndicator(streamChannel); + } + final message = _messages[i]; + final nextMessage = i > 0 ? _messages[i - 1] : null; + + Widget messageWidget; + + if (i == 0) { + messageWidget = _buildBottomMessage( + context, + message, + _messages, + streamChannel, + ); + } else if (i == _messages.length - 1) { + messageWidget = _buildTopMessage( + context, + message, + _messages, + streamChannel, ); } else { - messageWidget = buildMessage(message, _messages, i); + if (widget.messageBuilder != null) { + messageWidget = Builder( + key: ValueKey('MESSAGE-${message.id}'), + builder: (_) => widget.messageBuilder( + context, + MessageDetails( + context, + message, + _messages, + i, + ), + _messages), + ); + } else { + messageWidget = buildMessage(message, _messages, i); + } } - } - if (nextMessage != null && - !Jiffy(message.createdAt.toLocal()) - .isSame(nextMessage.createdAt.toLocal(), Units.DAY)) { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - messageWidget, - Padding( - padding: const EdgeInsets.symmetric(vertical: 12.0), - child: widget.dateDividerBuilder != null - ? widget.dateDividerBuilder( - nextMessage.createdAt.toLocal()) - : DateDivider( - dateTime: nextMessage.createdAt.toLocal(), - ), - ), - ], - ); - } + if (nextMessage != null && + !Jiffy(message.createdAt.toLocal()) + .isSame(nextMessage.createdAt.toLocal(), Units.DAY)) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + messageWidget, + Padding( + padding: const EdgeInsets.symmetric(vertical: 12.0), + child: widget.dateDividerBuilder != null + ? widget.dateDividerBuilder( + nextMessage.createdAt.toLocal()) + : DateDivider( + dateTime: nextMessage.createdAt.toLocal(), + ), + ), + ], + ); + } - return messageWidget; - }, - childCount: _messages.length + 2, - findChildIndexCallback: (key) { - final ValueKey valueKey = key; - final index = _messages - .indexWhere((m) => 'MESSAGE-${m.id}' == valueKey.value); - return index != -1 ? index : null; - }, + return VisibleNotifierWidget(child: messageWidget); + }, + childCount: _messages.length + 2, + findChildIndexCallback: (key) { + final ValueKey valueKey = key; + final index = _messages + .indexWhere((m) => 'MESSAGE-${m.id}' == valueKey.value); + return index != -1 ? index : null; + }, + ), ), ), - ), - if (widget.showScrollToBottom) - StreamBuilder( - stream: streamChannel.channel.on( - EventType.messageNew, - ), - builder: (context, _) { - if (!_showScrollToBottom || - streamChannel.channel.state.unreadCount == 0) { - return SizedBox(); - } - return _buildScrollToBottom(streamChannel); - }), - ], + if (widget.showScrollToBottom) + StreamBuilder( + stream: streamChannel.channel.on( + EventType.messageNew, + ), + builder: (context, _) { + if (!_showScrollToBottom || + streamChannel.channel.state.unreadCount == 0) { + return SizedBox(); + } + return _buildScrollToBottom(streamChannel); + }), + Positioned( + top: 20.0, + child: WidgetsVisibilityListener( + listener: (context, event) { + setState(() { + positionData = event.positionDataList.first.startPosition; + }); + }, + child: Chip( + label: Text(positionData.toString()), + ), + ), + ), + ], + ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 4ae31b50..26144e64 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ dependencies: flutter_slidable: ^0.5.4 carousel_slider: ^2.2.1 clipboard: ^0.1.2+8 + widgets_visibility_provider: ^2.0.2 flutter: fonts: From d93dfb5af4014cac52f6433bf5edd2b36bfdbba9 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 27 Oct 2020 13:37:00 +0530 Subject: [PATCH 06/18] feat: Added sticky header to display position data --- lib/src/message_list_view.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 42b434fd..0eaab75b 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -160,6 +160,7 @@ class _MessageListViewState extends State { return WidgetsVisibilityProvider( condition: (c) => null, child: Stack( + alignment: Alignment.center, children: [ NotificationListener( onNotification: (_) { @@ -301,13 +302,13 @@ class _MessageListViewState extends State { child: WidgetsVisibilityListener( listener: (context, event) { setState(() { - positionData = event.positionDataList.first.startPosition; + positionData = event.positionDataList.isNotEmpty ? event.positionDataList[0] : null; }); }, - child: Chip( - label: Text(positionData.toString()), + child: DateDivider( + dateTime: _messages[positionData].createdAt.toLocal(), + ), ), - ), ), ], ), From 6de4ee9963e2d447e7c8f9647271b60f6da5f642 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 27 Oct 2020 13:50:16 +0530 Subject: [PATCH 07/18] feat: Added sticky header to display position data --- lib/src/message_list_view.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 0eaab75b..83fbd75f 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -273,7 +273,7 @@ class _MessageListViewState extends State { ); } - return VisibleNotifierWidget(child: messageWidget); + return VisibleNotifierWidget(child: messageWidget, data: i,); }, childCount: _messages.length + 2, findChildIndexCallback: (key) { @@ -297,12 +297,13 @@ class _MessageListViewState extends State { } return _buildScrollToBottom(streamChannel); }), + if(positionData != null) Positioned( top: 20.0, child: WidgetsVisibilityListener( listener: (context, event) { setState(() { - positionData = event.positionDataList.isNotEmpty ? event.positionDataList[0] : null; + positionData = event.positionDataList.isNotEmpty ? event.positionDataList[0].data : null; }); }, child: DateDivider( From 1cb007ec2da153eebbe15fe562696900c8c69665 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 27 Oct 2020 14:14:00 +0530 Subject: [PATCH 08/18] feat: Added sticky header to display position data --- lib/src/message_list_view.dart | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 83fbd75f..e3502539 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -150,7 +150,6 @@ class _MessageListViewState extends State { List _newMessageList = []; Function _onThreadTap; bool _showScrollToBottom = false; - var positionData; @override Widget build(BuildContext context) { @@ -164,7 +163,8 @@ class _MessageListViewState extends State { children: [ NotificationListener( onNotification: (_) { - if (_scrollController.offset < 150 && _newMessageList.isNotEmpty) { + if (_scrollController.offset < 150 && + _newMessageList.isNotEmpty) { setState(() { _messages.insertAll(0, _newMessageList); _newMessageList.clear(); @@ -193,7 +193,8 @@ class _MessageListViewState extends State { children: [ buildParentMessage(widget.parentMessage), Padding( - padding: const EdgeInsets.symmetric(horizontal: 32), + padding: + const EdgeInsets.symmetric(horizontal: 32), child: Container( padding: const EdgeInsets.all(8), child: Text( @@ -273,7 +274,10 @@ class _MessageListViewState extends State { ); } - return VisibleNotifierWidget(child: messageWidget, data: i,); + return VisibleNotifierWidget( + child: messageWidget, + data: i, + ); }, childCount: _messages.length + 2, findChildIndexCallback: (key) { @@ -297,19 +301,19 @@ class _MessageListViewState extends State { } return _buildScrollToBottom(streamChannel); }), - if(positionData != null) Positioned( top: 20.0, - child: WidgetsVisibilityListener( - listener: (context, event) { - setState(() { - positionData = event.positionDataList.isNotEmpty ? event.positionDataList[0].data : null; - }); - }, - child: DateDivider( - dateTime: _messages[positionData].createdAt.toLocal(), - ), - ), + child: WidgetsVisibilityConsumer( + builder: (context, event) { + if(event.positionDataList == null || event.positionDataList.isEmpty) { + return Container(); + } + + return DateDivider( + dateTime: _messages[event.positionDataList[0].data].createdAt.toLocal(), + ); + }, + ), ), ], ), From 42d758264af3a53ebf60b2b4b89b65e4c4836399 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Tue, 27 Oct 2020 14:27:56 +0530 Subject: [PATCH 09/18] fix: Corrected date header --- lib/src/message_list_view.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index e3502539..e833f2e1 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -304,13 +304,14 @@ class _MessageListViewState extends State { Positioned( top: 20.0, child: WidgetsVisibilityConsumer( + listener: (context, event,) {}, builder: (context, event) { if(event.positionDataList == null || event.positionDataList.isEmpty) { return Container(); } return DateDivider( - dateTime: _messages[event.positionDataList[0].data].createdAt.toLocal(), + dateTime: _messages[event.positionDataList.last.data].createdAt.toLocal(), ); }, ), From ba37258427b48a7b8fa99b2821fcb77df5c756f9 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 27 Oct 2020 09:58:15 +0100 Subject: [PATCH 10/18] wip --- lib/src/message_actions_modal.dart | 12 ++- lib/src/message_list_view.dart | 2 +- lib/src/message_reactions_modal.dart | 31 ++++--- lib/src/message_widget.dart | 116 ++++++++--------------- lib/src/reaction_bubble.dart | 132 +++++++++++++++++---------- lib/src/reaction_picker.dart | 7 +- lib/src/stream_chat.dart | 23 ++--- lib/src/stream_chat_theme.dart | 44 +++------ 8 files changed, 171 insertions(+), 196 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 714966ce..ded377fc 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -79,10 +79,14 @@ class MessageActionsModal extends StatelessWidget { child: MessageWidget( key: Key('MessageWidget'), reverse: reverse, - message: message.text.length > 200 - ? message.copyWith( - text: '${message.text.substring(0, 200)}...') - : message, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + attachments: message.attachments.length > 1 + ? [message.attachments[0]] + : message.attachments, + ), messageTheme: messageTheme, showReactions: false, showUsername: false, diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 7c529f95..87d79622 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -543,7 +543,7 @@ class _MessageListViewState extends State { topRight: Radius.circular(16), bottomRight: Radius.circular(16), ), - showUserAvatar: isMyMessage + showUserAvatar: !isMyMessage ? DisplayWidget.gone : (isNextUser ? DisplayWidget.hide : DisplayWidget.show), messageTheme: isMyMessage diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 56e49382..9d2a30bf 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -70,10 +70,14 @@ class MessageReactionsModal extends StatelessWidget { child: MessageWidget( key: Key('MessageWidget'), reverse: reverse, - message: message.text.length > 200 - ? message.copyWith( - text: '${message.text.substring(0, 200)}...') - : message, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + attachments: message.attachments.length > 1 + ? [message.attachments[0]] + : message.attachments, + ), messageTheme: messageTheme, showReactions: false, showUsername: false, @@ -175,15 +179,16 @@ class MessageReactionsModal extends StatelessWidget { borderRadius: BorderRadius.circular(32), ), Positioned( - child: ReactionBubble( - reactions: [reaction], - borderColor: isCurrentUser - ? messageTheme.ownReactionsBorderColor - : messageTheme.otherReactionsBorderColor, - backgroundColor: isCurrentUser - ? messageTheme.ownReactionsBackgroundColor - : messageTheme.otherReactionsBackgroundColor, - flipTail: !isCurrentUser, + child: Align( + alignment: Alignment.centerLeft, + child: Container( + child: ReactionBubble( + reactions: [reaction], + borderColor: messageTheme.reactionsBorderColor, + backgroundColor: messageTheme.reactionsBackgroundColor, + flipTail: !isCurrentUser, + ), + ), ), bottom: 0, left: isCurrentUser ? 0 : null, diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 10298436..9a2200c3 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -239,20 +239,23 @@ class _MessageWidgetState extends State { 8, ), Flexible( - child: Padding( - padding: widget.showReactions - ? EdgeInsets.only( - top: widget.message.reactionCounts - ?.isNotEmpty == - true - ? 12 - : 0, - ) - : EdgeInsets.zero, - child: PortalEntry( - portalAnchor: Alignment(-0.81, 0), - childAnchor: Alignment.topRight, - portal: _buildReactionIndicator(context), + child: PortalEntry( + portal: ConstrainedBox( + child: _buildReactionIndicator(context), + constraints: BoxConstraints(maxWidth: 22 * 6.0), + ), + portalAnchor: Alignment(-1.0, -1.0), + childAnchor: Alignment(1, -1.0), + child: Padding( + padding: widget.showReactions + ? EdgeInsets.only( + top: widget.message.reactionCounts + ?.isNotEmpty == + true + ? 18 + : 0, + ) + : EdgeInsets.zero, child: (widget.message.isDeleted && widget.message.status != MessageSendingStatus.FAILED_DELETE) @@ -378,74 +381,33 @@ class _MessageWidgetState extends State { ); } - Widget _buildReactionIndicator(BuildContext context) { - final otherReactions = widget.message.latestReactions - ?.where( - (element) => element.user.id != StreamChat.of(context).user.id) - ?.toList() ?? - []; + Widget _buildReactionIndicator( + BuildContext context, + ) { + final ownId = StreamChat.of(context).user.id; + final reactionsMap = {}; + widget.message.latestReactions.forEach((element) { + if (!reactionsMap.containsKey(element.type) || element.user.id == ownId) { + reactionsMap[element.type] = element; + } + }); - var rowChildren = [ - if (widget.message.ownReactions?.isNotEmpty == true) ...[ - Transform.translate( - offset: Offset( - widget.reverse ? -6 : 0, - 0, - ), - child: ReactionBubble( - key: ValueKey('${widget.message.id}.own'), - reverse: widget.reverse, - backgroundColor: widget.messageTheme.ownReactionsBackgroundColor, - borderColor: widget.messageTheme.ownReactionsBorderColor, - reactions: widget.message.ownReactions, - ), - ), - if (otherReactions.isEmpty) - Container( - width: 18, - ), - ], - if (otherReactions?.isNotEmpty == true) ...[ - if (widget.message.ownReactions?.isEmpty == true) - Container( - width: 18, - ), - Transform.translate( - offset: Offset( - widget.reverse ? 0 : -6, - 0, - ), - child: ReactionBubble( - key: ValueKey('${widget.message.id}.other'), - reactions: otherReactions, - reverse: widget.reverse, - flipTail: true, - backgroundColor: widget.messageTheme.otherReactionsBackgroundColor, - borderColor: widget.messageTheme.otherReactionsBorderColor, - ), - ), - ] - ]; - - if (widget.reverse) { - rowChildren = rowChildren.reversed.toList(); - } return AnimatedSwitcher( duration: Duration(milliseconds: 300), child: (widget.showReactions && - (widget.message.reactionCounts?.isNotEmpty == true || - otherReactions.isNotEmpty) && + (widget.message.reactionCounts?.isNotEmpty == true) && !widget.message.isDeleted) - ? Container( - child: GestureDetector( - onTap: () => _showMessageReactionsModalBottomSheet(context), - child: FractionallySizedBox( - widthFactor: 0.5, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: rowChildren, - ), + ? GestureDetector( + onTap: () => _showMessageReactionsModalBottomSheet(context), + child: Transform.translate( + offset: Offset(-16, 0), + child: ReactionBubble( + key: ValueKey('${widget.message.id}.reactions'), + reverse: widget.reverse, + flipTail: widget.reverse, + backgroundColor: widget.messageTheme.reactionsBackgroundColor, + borderColor: widget.messageTheme.reactionsBorderColor, + reactions: reactionsMap.values.toList(), ), ), ) diff --git a/lib/src/reaction_bubble.dart b/lib/src/reaction_bubble.dart index a166e4da..9db6e112 100644 --- a/lib/src/reaction_bubble.dart +++ b/lib/src/reaction_bubble.dart @@ -1,6 +1,8 @@ import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:stream_chat_flutter/src/reaction_icon.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class ReactionBubble extends StatelessWidget { @@ -25,60 +27,92 @@ class ReactionBubble extends StatelessWidget { return Transform( transform: Matrix4.rotationY(reverse ? pi : 0), alignment: Alignment.center, - child: Column( - crossAxisAlignment: - flipTail ? CrossAxisAlignment.start : CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.min, + child: Stack( + alignment: Alignment.center, children: [ - Container( - padding: const EdgeInsets.all(4), - decoration: BoxDecoration( - border: Border.all( - color: borderColor, + Transform.translate( + offset: Offset(reverse ? 5 : -5, 0), + child: Container( + padding: const EdgeInsets.symmetric(vertical: 6), + decoration: BoxDecoration( + border: Border.all( + color: borderColor, + ), + color: backgroundColor, + borderRadius: BorderRadius.all(Radius.circular(14)), ), - color: backgroundColor, - borderRadius: BorderRadius.all(Radius.circular(14)), - ), - child: Wrap( - spacing: 8, - children: [ - ...reactions.map((reaction) { - final reactionIcon = reactionIcons.firstWhere( - (r) => r.type == reaction.type, - orElse: () => null, + child: LayoutBuilder( + builder: (context, constraints) { + return Flex( + direction: Axis.horizontal, + mainAxisSize: MainAxisSize.min, + children: [ + if (constraints.maxWidth < double.infinity) + ...reactions + .take((constraints.maxWidth) ~/ 22) + .map((reaction) { + return _buildReaction( + reactionIcons, + reaction, + context, + ); + }).toList(), + if (constraints.maxWidth == double.infinity) + ...reactions.map((reaction) { + return _buildReaction( + reactionIcons, + reaction, + context, + ); + }).toList(), + ], ); - if (reactionIcon == null) { - return Text( - '?', - style: TextStyle( - color: StreamChatTheme.of(context).accentColor, - ), - ); - } - - return Icon( - reactionIcon.iconData, - size: 16, - color: StreamChatTheme.of(context).accentColor, - ); - }).toList(), - ], + }, + ), ), ), - _buildReactionsTail(context), + Positioned( + bottom: 0, + left: reverse ? null : 16, + right: !reverse ? null : 16, + child: _buildReactionsTail(context), + ), ], ), ); } + Widget _buildReaction( + List reactionIcons, + Reaction reaction, + BuildContext context, + ) { + final reactionIcon = reactionIcons.firstWhere( + (r) => r.type == reaction.type, + orElse: () => null, + ); + + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4.0, + ), + child: Icon( + reactionIcon?.iconData ?? Icons.help_outline_rounded, + size: 16, + color: reaction.user.id == StreamChat.of(context).user.id + ? StreamChatTheme.of(context).accentColor + : Colors.black.withOpacity(.5), + ), + ); + } + Widget _buildReactionsTail(BuildContext context) { final tail = Transform.translate( - offset: Offset(reactions.length > 1 ? -9 : -9, 0), + offset: Offset(-5, 0), child: CustomPaint( painter: ReactionBubblePainter( backgroundColor, borderColor, - reactions.length, ), ), ); @@ -98,12 +132,10 @@ class ReactionBubble extends StatelessWidget { class ReactionBubblePainter extends CustomPainter { final Color color; final Color borderColor; - final int reactionsCount; ReactionBubblePainter( this.color, this.borderColor, - this.reactionsCount, ); @override @@ -126,7 +158,7 @@ class ReactionBubblePainter extends CustomPainter { final path = Path(); path.addOval( Rect.fromCircle( - center: Offset(6, 2), + center: Offset(4, 3), radius: 2, ), ); @@ -140,7 +172,7 @@ class ReactionBubblePainter extends CustomPainter { final path = Path(); path.addOval(Rect.fromCircle( - center: Offset(6, 2), + center: Offset(4, 3), radius: 2, )); canvas.drawPath(path, paint); @@ -152,13 +184,13 @@ class ReactionBubblePainter extends CustomPainter { ..strokeWidth = 1 ..style = PaintingStyle.stroke; - final dy = reactionsCount > 1 ? -2.0 : -3.0; - final startAngle = reactionsCount > 1 ? 1.08 : 1.16; - final sweepAngle = reactionsCount > 1 ? 0.95 : 1.1; + final dy = -2.2; + final startAngle = 1.1; + final sweepAngle = 1.2; final path = Path(); path.addArc( Rect.fromCircle( - center: Offset(0, dy), + center: Offset(1, dy), radius: 4, ), -pi * startAngle, @@ -172,13 +204,13 @@ class ReactionBubblePainter extends CustomPainter { ..color = color ..strokeWidth = 1; - final dy = reactionsCount > 1 ? -2.0 : -3.0; - final startAngle = reactionsCount > 1 ? 1 : 1.16; - final sweepAngle = reactionsCount > 1 ? 1.2 : 1; + final dy = -2.2; + final startAngle = 1; + final sweepAngle = 1.3; final path = Path(); path.addArc( Rect.fromCircle( - center: Offset(0, dy), + center: Offset(1, dy), radius: 4, ), -pi * startAngle, diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index f954902b..87487cde 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -26,7 +26,7 @@ class ReactionPicker extends StatelessWidget { fit: StackFit.passthrough, children: [ Material( - color: messageTheme.ownReactionsBackgroundColor, + color: messageTheme.reactionsBackgroundColor, clipBehavior: Clip.hardEdge, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), @@ -69,9 +69,8 @@ class ReactionPicker extends StatelessWidget { bottom: 0, child: CustomPaint( painter: ReactionBubblePainter( - messageTheme.ownReactionsBackgroundColor, - messageTheme.ownReactionsBorderColor, - 2, + messageTheme.reactionsBackgroundColor, + messageTheme.reactionsBorderColor, ), ), ), diff --git a/lib/src/stream_chat.dart b/lib/src/stream_chat.dart index b22c257c..e8eca6d6 100644 --- a/lib/src/stream_chat.dart +++ b/lib/src/stream_chat.dart @@ -129,14 +129,9 @@ class StreamChatState extends State with WidgetsBindingObserver { constraints: themeData?.ownMessageTheme?.avatarTheme?.constraints, borderRadius: themeData?.ownMessageTheme?.avatarTheme?.borderRadius, ), - otherReactionsBorderColor: - themeData?.ownMessageTheme?.otherReactionsBorderColor, - otherReactionsBackgroundColor: - themeData?.ownMessageTheme?.otherReactionsBackgroundColor, - ownReactionsBackgroundColor: - themeData?.ownMessageTheme?.ownReactionsBackgroundColor, - ownReactionsBorderColor: - themeData?.ownMessageTheme?.ownReactionsBorderColor, + reactionsBorderColor: themeData?.ownMessageTheme?.reactionsBorderColor, + reactionsBackgroundColor: + themeData?.ownMessageTheme?.reactionsBackgroundColor, ), otherMessageTheme: defaultTheme.otherMessageTheme.copyWith( replies: themeData?.otherMessageTheme?.replies, @@ -150,14 +145,10 @@ class StreamChatState extends State with WidgetsBindingObserver { constraints: themeData?.otherMessageTheme?.avatarTheme?.constraints, borderRadius: themeData?.otherMessageTheme?.avatarTheme?.borderRadius, ), - otherReactionsBorderColor: - themeData?.otherMessageTheme?.otherReactionsBorderColor, - otherReactionsBackgroundColor: - themeData?.otherMessageTheme?.otherReactionsBackgroundColor, - ownReactionsBackgroundColor: - themeData?.otherMessageTheme?.ownReactionsBackgroundColor, - ownReactionsBorderColor: - themeData?.otherMessageTheme?.ownReactionsBorderColor, + reactionsBorderColor: + themeData?.otherMessageTheme?.reactionsBorderColor, + reactionsBackgroundColor: + themeData?.otherMessageTheme?.reactionsBackgroundColor, ), accentColor: themeData?.accentColor, secondaryColor: themeData?.secondaryColor, diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 359ab102..504864b2 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -302,12 +302,8 @@ class StreamChatThemeData { fontSize: 12, ), messageBackgroundColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), - ownReactionsBackgroundColor: - isDark ? Color(0xff191919) : Color(0xffEAEAEA), - ownReactionsBorderColor: isDark ? Colors.black : Colors.white, - otherReactionsBackgroundColor: isDark ? Colors.black : Colors.white, - otherReactionsBorderColor: - isDark ? Color(0xff191919) : Color(0xffEAEAEA), + reactionsBackgroundColor: isDark ? Colors.black : Colors.white, + reactionsBorderColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( @@ -320,12 +316,9 @@ class StreamChatThemeData { ), ), otherMessageTheme: MessageTheme( - ownReactionsBackgroundColor: - isDark ? Color(0xff191919) : Color(0xffEAEAEA), - ownReactionsBorderColor: isDark ? Colors.black : Colors.white, - otherReactionsBackgroundColor: isDark ? Colors.black : Colors.white, - otherReactionsBorderColor: + reactionsBackgroundColor: isDark ? Color(0xff191919) : Color(0xffEAEAEA), + reactionsBorderColor: isDark ? Colors.black : Colors.white, messageText: TextStyle( fontSize: 15, color: isDark ? Colors.white : Colors.black, @@ -457,10 +450,8 @@ class MessageTheme { final TextStyle createdAt; final TextStyle replies; final Color messageBackgroundColor; - final Color ownReactionsBackgroundColor; - final Color ownReactionsBorderColor; - final Color otherReactionsBackgroundColor; - final Color otherReactionsBorderColor; + final Color reactionsBackgroundColor; + final Color reactionsBorderColor; final AvatarTheme avatarTheme; const MessageTheme({ @@ -469,10 +460,8 @@ class MessageTheme { this.messageAuthor, this.messageLinks, this.messageBackgroundColor, - this.ownReactionsBackgroundColor, - this.ownReactionsBorderColor, - this.otherReactionsBackgroundColor, - this.otherReactionsBorderColor, + this.reactionsBackgroundColor, + this.reactionsBorderColor, this.avatarTheme, this.createdAt, }); @@ -485,10 +474,8 @@ class MessageTheme { TextStyle replies, Color messageBackgroundColor, AvatarTheme avatarTheme, - Color ownReactionsBackgroundColor, - Color ownReactionsBorderColor, - Color otherReactionsBackgroundColor, - Color otherReactionsBorderColor, + Color reactionsBackgroundColor, + Color reactionsBorderColor, }) => MessageTheme( messageText: messageText ?? this.messageText, @@ -499,14 +486,9 @@ class MessageTheme { messageBackgroundColor ?? this.messageBackgroundColor, avatarTheme: avatarTheme ?? this.avatarTheme, replies: replies ?? this.replies, - ownReactionsBackgroundColor: - ownReactionsBackgroundColor ?? this.ownReactionsBackgroundColor, - ownReactionsBorderColor: - ownReactionsBorderColor ?? this.ownReactionsBorderColor, - otherReactionsBackgroundColor: - otherReactionsBackgroundColor ?? this.otherReactionsBackgroundColor, - otherReactionsBorderColor: - otherReactionsBorderColor ?? this.otherReactionsBorderColor, + reactionsBackgroundColor: + reactionsBackgroundColor ?? this.reactionsBackgroundColor, + reactionsBorderColor: reactionsBorderColor ?? this.reactionsBorderColor, ); } From 58511e8f4bfe277deb41aa11361643c493a84421 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 27 Oct 2020 10:32:22 +0100 Subject: [PATCH 11/18] fix reactions ontap --- example/ios/Flutter/.last_build_id | 2 +- example/lib/main.dart | 2 +- example/pubspec.yaml | 2 +- lib/src/message_list_view.dart | 2 +- lib/src/message_reactions_modal.dart | 97 ++++++++++++++-------------- lib/src/message_widget.dart | 20 +++--- lib/src/reaction_bubble.dart | 24 +++---- 7 files changed, 75 insertions(+), 74 deletions(-) diff --git a/example/ios/Flutter/.last_build_id b/example/ios/Flutter/.last_build_id index 171fde31..661f8167 100644 --- a/example/ios/Flutter/.last_build_id +++ b/example/ios/Flutter/.last_build_id @@ -1 +1 @@ -0289cdadbd29bab804f275e3c5907d07 \ No newline at end of file +89eb023669fee58472de747080d78b5a \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 89ed9381..667b1e0f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -76,7 +76,7 @@ void main() async { await client.setUser( User(id: 'super-band-9', extraData: { - 'name': 'John Doe', + 'name': 'Jonathan Doe', }), 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A', ); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 9a6554e6..cb0eca8e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.31+33 +version: 1.0.32+34 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 87d79622..7c529f95 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -543,7 +543,7 @@ class _MessageListViewState extends State { topRight: Radius.circular(16), bottomRight: Radius.circular(16), ), - showUserAvatar: !isMyMessage + showUserAvatar: isMyMessage ? DisplayWidget.gone : (isNextUser ? DisplayWidget.hide : DisplayWidget.show), messageTheme: isMyMessage diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 9d2a30bf..319b8acd 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -53,49 +53,54 @@ class MessageReactionsModal extends StatelessWidget { ), ), ), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (showReactions && - (message.status == MessageSendingStatus.SENT || - message.status == null)) - Center( - child: ReactionPicker( - message: message, + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (showReactions && + (message.status == MessageSendingStatus.SENT || + message.status == null)) + Center( + child: ReactionPicker( + message: message, + messageTheme: messageTheme, + ), + ), + AbsorbPointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + attachments: message.attachments.length > 1 + ? [message.attachments[0]] + : message.attachments, + ), messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showTimestamp: false, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, ), ), - AbsorbPointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - attachments: message.attachments.length > 1 - ? [message.attachments[0]] - : message.attachments, + SizedBox( + height: 16, + ), + if (message.latestReactions?.isNotEmpty == true) + Flexible( + child: Container( + constraints: BoxConstraints.loose(Size.fromHeight(400)), + child: _buildReactionCard(context), + ), ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showTimestamp: false, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, - ), - ), - SizedBox( - height: 16, - ), - if (message.latestReactions?.isNotEmpty == true) - Container( - constraints: BoxConstraints.loose(Size.fromHeight(400)), - child: _buildReactionCard(context), - ), - ], + ], + ), ), ], ); @@ -181,16 +186,14 @@ class MessageReactionsModal extends StatelessWidget { Positioned( child: Align( alignment: Alignment.centerLeft, - child: Container( - child: ReactionBubble( - reactions: [reaction], - borderColor: messageTheme.reactionsBorderColor, - backgroundColor: messageTheme.reactionsBackgroundColor, - flipTail: !isCurrentUser, - ), + child: ReactionBubble( + reactions: [reaction], + borderColor: messageTheme.reactionsBorderColor, + backgroundColor: messageTheme.reactionsBackgroundColor, + highlightOwnReactions: false, ), ), - bottom: 0, + bottom: 4, left: isCurrentUser ? 0 : null, right: isCurrentUser ? 0 : null, ), diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 9a2200c3..beff166a 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -240,7 +240,8 @@ class _MessageWidgetState extends State { ), Flexible( child: PortalEntry( - portal: ConstrainedBox( + portal: Container( + transform: Matrix4.translationValues(-16, 0, 0), child: _buildReactionIndicator(context), constraints: BoxConstraints(maxWidth: 22 * 6.0), ), @@ -399,16 +400,13 @@ class _MessageWidgetState extends State { !widget.message.isDeleted) ? GestureDetector( onTap: () => _showMessageReactionsModalBottomSheet(context), - child: Transform.translate( - offset: Offset(-16, 0), - child: ReactionBubble( - key: ValueKey('${widget.message.id}.reactions'), - reverse: widget.reverse, - flipTail: widget.reverse, - backgroundColor: widget.messageTheme.reactionsBackgroundColor, - borderColor: widget.messageTheme.reactionsBorderColor, - reactions: reactionsMap.values.toList(), - ), + child: ReactionBubble( + key: ValueKey('${widget.message.id}.reactions'), + reverse: widget.reverse, + flipTail: widget.reverse, + backgroundColor: widget.messageTheme.reactionsBackgroundColor, + borderColor: widget.messageTheme.reactionsBorderColor, + reactions: reactionsMap.values.toList(), ), ) : SizedBox(), diff --git a/lib/src/reaction_bubble.dart b/lib/src/reaction_bubble.dart index 9db6e112..03f415b0 100644 --- a/lib/src/reaction_bubble.dart +++ b/lib/src/reaction_bubble.dart @@ -13,6 +13,7 @@ class ReactionBubble extends StatelessWidget { @required this.backgroundColor, this.reverse = false, this.flipTail = false, + this.highlightOwnReactions = true, }) : super(key: key); final List reactions; @@ -20,6 +21,7 @@ class ReactionBubble extends StatelessWidget { final Color backgroundColor; final bool reverse; final bool flipTail; + final bool highlightOwnReactions; @override Widget build(BuildContext context) { @@ -31,9 +33,9 @@ class ReactionBubble extends StatelessWidget { alignment: Alignment.center, children: [ Transform.translate( - offset: Offset(reverse ? 5 : -5, 0), + offset: Offset(reverse ? 2 : -2, 0), child: Container( - padding: const EdgeInsets.symmetric(vertical: 6), + padding: const EdgeInsets.symmetric(vertical: 4), decoration: BoxDecoration( border: Border.all( color: borderColor, @@ -73,8 +75,8 @@ class ReactionBubble extends StatelessWidget { ), Positioned( bottom: 0, - left: reverse ? null : 16, - right: !reverse ? null : 16, + left: reverse ? null : 11, + right: !reverse ? null : 11, child: _buildReactionsTail(context), ), ], @@ -99,7 +101,8 @@ class ReactionBubble extends StatelessWidget { child: Icon( reactionIcon?.iconData ?? Icons.help_outline_rounded, size: 16, - color: reaction.user.id == StreamChat.of(context).user.id + color: (!highlightOwnReactions || + reaction.user.id == StreamChat.of(context).user.id) ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(.5), ), @@ -107,13 +110,10 @@ class ReactionBubble extends StatelessWidget { } Widget _buildReactionsTail(BuildContext context) { - final tail = Transform.translate( - offset: Offset(-5, 0), - child: CustomPaint( - painter: ReactionBubblePainter( - backgroundColor, - borderColor, - ), + final tail = CustomPaint( + painter: ReactionBubblePainter( + backgroundColor, + borderColor, ), ); From e8411d3aa4fe39cb7907da22f5ea6397d16cf5c8 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 27 Oct 2020 16:15:50 +0100 Subject: [PATCH 12/18] fix reactions overflowing the screen --- lib/src/message_actions_modal.dart | 127 ++++++++++++++------------- lib/src/message_reactions_modal.dart | 2 +- lib/src/message_widget.dart | 2 +- lib/src/reaction_bubble.dart | 3 +- 4 files changed, 71 insertions(+), 63 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index ded377fc..c1c572a7 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -62,71 +62,78 @@ class MessageActionsModal extends StatelessWidget { ), ), ), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (showReactions && - (message.status == MessageSendingStatus.SENT || - message.status == null)) - Center( - child: ReactionPicker( - message: message, + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (showReactions && + (message.status == MessageSendingStatus.SENT || + message.status == null)) + Center( + child: ReactionPicker( + message: message, + messageTheme: messageTheme, + ), + ), + IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + attachments: message.attachments.length > 1 + ? [message.attachments[0]] + : message.attachments, + ), messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showTimestamp: false, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, ), ), - AbsorbPointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - attachments: message.attachments.length > 1 - ? [message.attachments[0]] - : message.attachments, - ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showTimestamp: false, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, + SizedBox( + height: 8, ), - ), - SizedBox( - height: 8, - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 48.0, - ), - child: Material( - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), + Flexible( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 48.0, + ), + child: Material( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: ListTile.divideTiles( + context: context, + tiles: [ + if (showReply && + (message.status == MessageSendingStatus.SENT || + message.status == null) && + message.parentId == null) + _buildReplyButton(context), + if (showEditMessage) _buildEditMessage(context), + if (showDeleteMessage) _buildDeleteButton(context), + if (showCopyMessage) _buildCopyButton(context), + ], + ).toList(), + ), + ), + ), ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: ListTile.divideTiles( - context: context, - tiles: [ - if (showReply && - (message.status == MessageSendingStatus.SENT || - message.status == null) && - message.parentId == null) - _buildReplyButton(context), - if (showEditMessage) _buildEditMessage(context), - if (showDeleteMessage) _buildDeleteButton(context), - if (showCopyMessage) _buildCopyButton(context), - ], - ).toList(), - ), - ), - ) - ], + ) + ], + ), ), ], ); diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 319b8acd..b6026cf7 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -68,7 +68,7 @@ class MessageReactionsModal extends StatelessWidget { messageTheme: messageTheme, ), ), - AbsorbPointer( + IgnorePointer( child: MessageWidget( key: Key('MessageWidget'), reverse: reverse, diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index beff166a..a2c886af 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -387,7 +387,7 @@ class _MessageWidgetState extends State { ) { final ownId = StreamChat.of(context).user.id; final reactionsMap = {}; - widget.message.latestReactions.forEach((element) { + widget.message.latestReactions?.forEach((element) { if (!reactionsMap.containsKey(element.type) || element.user.id == ownId) { reactionsMap[element.type] = element; } diff --git a/lib/src/reaction_bubble.dart b/lib/src/reaction_bubble.dart index 03f415b0..83593afc 100644 --- a/lib/src/reaction_bubble.dart +++ b/lib/src/reaction_bubble.dart @@ -26,6 +26,7 @@ class ReactionBubble extends StatelessWidget { @override Widget build(BuildContext context) { final reactionIcons = StreamChatTheme.of(context).reactionIcons; + final offset = reactions.length > 1 ? 16.0 : 2.0; return Transform( transform: Matrix4.rotationY(reverse ? pi : 0), alignment: Alignment.center, @@ -33,7 +34,7 @@ class ReactionBubble extends StatelessWidget { alignment: Alignment.center, children: [ Transform.translate( - offset: Offset(reverse ? 2 : -2, 0), + offset: Offset(reverse ? offset : -offset, 0), child: Container( padding: const EdgeInsets.symmetric(vertical: 4), decoration: BoxDecoration( From e9572d48b9b2971fddafe7f2f6723a8072cc884a Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 27 Oct 2020 16:56:51 +0100 Subject: [PATCH 13/18] put own reaction to the right --- lib/src/message_actions_modal.dart | 140 +++++++++++++-------------- lib/src/message_reactions_modal.dart | 121 +++++++++++------------ lib/src/message_widget.dart | 4 +- 3 files changed, 129 insertions(+), 136 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index c1c572a7..582e8496 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -43,75 +43,71 @@ class MessageActionsModal extends StatelessWidget { @override Widget build(BuildContext context) { - return Stack( - children: [ - Positioned.fill( - child: GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - Navigator.pop(context); - }, - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: Colors.transparent, + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + Navigator.pop(context); + }, + child: SingleChildScrollView( + padding: const EdgeInsets.only(top: 160), + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10, + sigmaY: 10, + ), + child: Container( + color: Colors.transparent, + ), ), ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (showReactions && - (message.status == MessageSendingStatus.SENT || - message.status == null)) - Center( - child: ReactionPicker( - message: message, - messageTheme: messageTheme, - ), - ), - IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - attachments: message.attachments.length > 1 - ? [message.attachments[0]] - : message.attachments, - ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showTimestamp: false, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, - ), - ), - SizedBox( - height: 8, - ), - Flexible( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 48.0, - ), - child: Material( - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (showReactions && + (message.status == MessageSendingStatus.SENT || + message.status == null)) + Center( + child: ReactionPicker( + message: message, + messageTheme: messageTheme, + ), ), - child: SingleChildScrollView( + IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + ), + messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showTimestamp: false, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, + ), + ), + SizedBox( + height: 8, + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 48.0, + ), + child: Material( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: ListTile.divideTiles( @@ -129,13 +125,13 @@ class MessageActionsModal extends StatelessWidget { ).toList(), ), ), - ), - ), - ) - ], - ), + ) + ], + ), + ), + ], ), - ], + ), ); } diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index b6026cf7..7db22ee1 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -34,75 +34,70 @@ class MessageReactionsModal extends StatelessWidget { @override Widget build(BuildContext context) { - return Stack( - children: [ - Positioned.fill( - child: GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - Navigator.pop(context); - }, - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: Colors.transparent, + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + Navigator.pop(context); + }, + child: SingleChildScrollView( + padding: const EdgeInsets.only(top: 160), + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10, + sigmaY: 10, + ), + child: Container( + color: Colors.transparent, + ), ), ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (showReactions && - (message.status == MessageSendingStatus.SENT || - message.status == null)) - Center( - child: ReactionPicker( - message: message, - messageTheme: messageTheme, + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (showReactions && + (message.status == MessageSendingStatus.SENT || + message.status == null)) + Center( + child: ReactionPicker( + message: message, + messageTheme: messageTheme, + ), + ), + IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + ), + messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showTimestamp: false, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, + ), ), - ), - IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - attachments: message.attachments.length > 1 - ? [message.attachments[0]] - : message.attachments, + SizedBox( + height: 16, ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showTimestamp: false, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, - ), + if (message.latestReactions?.isNotEmpty == true) + _buildReactionCard(context), + ], ), - SizedBox( - height: 16, - ), - if (message.latestReactions?.isNotEmpty == true) - Flexible( - child: Container( - constraints: BoxConstraints.loose(Size.fromHeight(400)), - child: _buildReactionCard(context), - ), - ), - ], - ), + ), + ], ), - ], + ), ); } diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index a2c886af..c3fa4c6e 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -392,6 +392,8 @@ class _MessageWidgetState extends State { reactionsMap[element.type] = element; } }); + final reactionsList = reactionsMap.values.toList() + ..sort((a, b) => a.user.id == ownId ? 1 : -1); return AnimatedSwitcher( duration: Duration(milliseconds: 300), @@ -406,7 +408,7 @@ class _MessageWidgetState extends State { flipTail: widget.reverse, backgroundColor: widget.messageTheme.reactionsBackgroundColor, borderColor: widget.messageTheme.reactionsBorderColor, - reactions: reactionsMap.values.toList(), + reactions: reactionsList, ), ) : SizedBox(), From d2801b2b1324a7d62915c9e0b1938245e5477ead Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 27 Oct 2020 17:11:57 +0100 Subject: [PATCH 14/18] fix scrollview --- lib/src/message_actions_modal.dart | 149 ++++++++++++++------------- lib/src/message_reactions_modal.dart | 101 +++++++++--------- lib/src/message_widget.dart | 2 +- 3 files changed, 128 insertions(+), 124 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 582e8496..4b6c4d4f 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -48,88 +48,91 @@ class MessageActionsModal extends StatelessWidget { onTap: () { Navigator.pop(context); }, - child: SingleChildScrollView( - padding: const EdgeInsets.only(top: 160), - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: Colors.transparent, + child: Center( + child: SingleChildScrollView( + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10, + sigmaY: 10, + ), + child: Container( + color: Colors.transparent, + ), ), ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (showReactions && - (message.status == MessageSendingStatus.SENT || - message.status == null)) - Center( - child: ReactionPicker( - message: message, + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (showReactions && + (message.status == MessageSendingStatus.SENT || + message.status == null)) + Center( + child: ReactionPicker( + message: message, + messageTheme: messageTheme, + ), + ), + IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + ), messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showTimestamp: false, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, ), ), - IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showTimestamp: false, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, + SizedBox( + height: 8, ), - ), - SizedBox( - height: 8, - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 48.0, - ), - child: Material( - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 48.0, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: ListTile.divideTiles( - context: context, - tiles: [ - if (showReply && - (message.status == MessageSendingStatus.SENT || - message.status == null) && - message.parentId == null) - _buildReplyButton(context), - if (showEditMessage) _buildEditMessage(context), - if (showDeleteMessage) _buildDeleteButton(context), - if (showCopyMessage) _buildCopyButton(context), - ], - ).toList(), + child: Material( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: ListTile.divideTiles( + context: context, + tiles: [ + if (showReply && + (message.status == + MessageSendingStatus.SENT || + message.status == null) && + message.parentId == null) + _buildReplyButton(context), + if (showEditMessage) _buildEditMessage(context), + if (showDeleteMessage) + _buildDeleteButton(context), + if (showCopyMessage) _buildCopyButton(context), + ], + ).toList(), + ), ), - ), - ) - ], + ) + ], + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 7db22ee1..0582eb79 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -39,63 +39,64 @@ class MessageReactionsModal extends StatelessWidget { onTap: () { Navigator.pop(context); }, - child: SingleChildScrollView( - padding: const EdgeInsets.only(top: 160), - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: Colors.transparent, + child: Center( + child: SingleChildScrollView( + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10, + sigmaY: 10, + ), + child: Container( + color: Colors.transparent, + ), ), ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (showReactions && - (message.status == MessageSendingStatus.SENT || - message.status == null)) - Center( - child: ReactionPicker( - message: message, + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (showReactions && + (message.status == MessageSendingStatus.SENT || + message.status == null)) + Center( + child: ReactionPicker( + message: message, + messageTheme: messageTheme, + ), + ), + IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + ), messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showTimestamp: false, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, ), ), - IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showTimestamp: false, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, + SizedBox( + height: 16, ), - ), - SizedBox( - height: 16, - ), - if (message.latestReactions?.isNotEmpty == true) - _buildReactionCard(context), - ], + if (message.latestReactions?.isNotEmpty == true) + _buildReactionCard(context), + ], + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index c3fa4c6e..0e703fa0 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -241,7 +241,7 @@ class _MessageWidgetState extends State { Flexible( child: PortalEntry( portal: Container( - transform: Matrix4.translationValues(-16, 0, 0), + transform: Matrix4.translationValues(-16, 2, 0), child: _buildReactionIndicator(context), constraints: BoxConstraints(maxWidth: 22 * 6.0), ), From b22cf7bdf36f88aeb2b07cf483c973cdc1f4f1a1 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 28 Oct 2020 13:24:41 +0530 Subject: [PATCH 15/18] fix: Fixed Visiblity --- lib/src/message_list_view.dart | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index e833f2e1..da260b0e 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -257,20 +257,23 @@ class _MessageListViewState extends State { if (nextMessage != null && !Jiffy(message.createdAt.toLocal()) .isSame(nextMessage.createdAt.toLocal(), Units.DAY)) { - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - messageWidget, - Padding( - padding: const EdgeInsets.symmetric(vertical: 12.0), - child: widget.dateDividerBuilder != null - ? widget.dateDividerBuilder( - nextMessage.createdAt.toLocal()) - : DateDivider( - dateTime: nextMessage.createdAt.toLocal(), - ), - ), - ], + return VisibleNotifierWidget( + data: i, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + messageWidget, + Padding( + padding: const EdgeInsets.symmetric(vertical: 12.0), + child: widget.dateDividerBuilder != null + ? widget.dateDividerBuilder( + nextMessage.createdAt.toLocal()) + : DateDivider( + dateTime: nextMessage.createdAt.toLocal(), + ), + ), + ], + ), ); } From 3f619fe79c4a8a95f52c70896781d13738c53cee Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 28 Oct 2020 10:39:55 +0100 Subject: [PATCH 16/18] fix backdrop filter --- lib/src/message_actions_modal.dart | 38 +++++++++++++++------------- lib/src/message_reactions_modal.dart | 38 +++++++++++++++------------- lib/src/stream_chat_theme.dart | 8 +++--- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 4b6c4d4f..54108df7 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -43,27 +43,28 @@ class MessageActionsModal extends StatelessWidget { @override Widget build(BuildContext context) { + final ownId = StreamChat.of(context).user.id; return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { Navigator.pop(context); }, - child: Center( - child: SingleChildScrollView( - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: Colors.transparent, - ), - ), + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10.8731, + sigmaY: 10.8731, ), - Padding( + child: Container( + color: Colors.black.withOpacity(0.2), + ), + ), + ), + Center( + child: SingleChildScrollView( + child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -91,6 +92,9 @@ class MessageActionsModal extends StatelessWidget { showReactions: false, showUsername: false, showReplyIndicator: false, + showUserAvatar: message.user.id == ownId + ? DisplayWidget.gone + : DisplayWidget.show, showTimestamp: false, showSendingIndicator: DisplayWidget.gone, shape: messageShape, @@ -131,9 +135,9 @@ class MessageActionsModal extends StatelessWidget { ], ), ), - ], + ), ), - ), + ], ), ); } diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 0582eb79..375da94e 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -34,27 +34,28 @@ class MessageReactionsModal extends StatelessWidget { @override Widget build(BuildContext context) { + final ownId = StreamChat.of(context).user.id; return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { Navigator.pop(context); }, - child: Center( - child: SingleChildScrollView( - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: Colors.transparent, - ), - ), + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10.8731, + sigmaY: 10.8731, ), - Padding( + child: Container( + color: Colors.black.withOpacity(0.2), + ), + ), + ), + Center( + child: SingleChildScrollView( + child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -81,6 +82,9 @@ class MessageReactionsModal extends StatelessWidget { messageTheme: messageTheme, showReactions: false, showUsername: false, + showUserAvatar: message.user.id == ownId + ? DisplayWidget.gone + : DisplayWidget.show, showReplyIndicator: false, showTimestamp: false, showSendingIndicator: DisplayWidget.gone, @@ -95,9 +99,9 @@ class MessageReactionsModal extends StatelessWidget { ], ), ), - ], + ), ), - ), + ], ), ); } diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 504864b2..cc959a35 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -220,8 +220,8 @@ class StreamChatThemeData { return StreamChatThemeData( accentColor: accentColor, primaryColor: isDark ? Colors.black : Colors.white, - primaryIconTheme: - IconThemeData(color: isDark ? Colors.white : Colors.black), + primaryIconTheme: IconThemeData( + color: isDark ? Colors.white : Colors.black.withOpacity(.5)), defaultChannelImage: (context, channel) => SizedBox(), backgroundColor: isDark ? Colors.black : Colors.white, defaultUserImage: (context, user) => Center( @@ -287,7 +287,7 @@ class StreamChatThemeData { ), ownMessageTheme: MessageTheme( messageText: TextStyle( - fontSize: 15, + fontSize: 14.5, color: isDark ? Colors.white : Colors.black, ), createdAt: TextStyle( @@ -320,7 +320,7 @@ class StreamChatThemeData { isDark ? Color(0xff191919) : Color(0xffEAEAEA), reactionsBorderColor: isDark ? Colors.black : Colors.white, messageText: TextStyle( - fontSize: 15, + fontSize: 14.5, color: isDark ? Colors.white : Colors.black, ), createdAt: TextStyle( From bb46710f2416b5409160ee56daf470b35b3140e6 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 28 Oct 2020 11:42:02 +0100 Subject: [PATCH 17/18] modify condition --- example/ios/Flutter/.last_build_id | 2 +- example/pubspec.yaml | 2 +- lib/src/message_list_view.dart | 46 +++++++++++++++++++++--------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/example/ios/Flutter/.last_build_id b/example/ios/Flutter/.last_build_id index 171fde31..661f8167 100644 --- a/example/ios/Flutter/.last_build_id +++ b/example/ios/Flutter/.last_build_id @@ -1 +1 @@ -0289cdadbd29bab804f275e3c5907d07 \ No newline at end of file +89eb023669fee58472de747080d78b5a \ No newline at end of file diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 9a6554e6..cb0eca8e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.31+33 +version: 1.0.32+34 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index da260b0e..bb0f98c0 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -157,7 +157,9 @@ class _MessageListViewState extends State { /// TODO: find a better solution when (https://github.com/flutter/flutter/issues/21023) is fixed return WidgetsVisibilityProvider( - condition: (c) => null, + condition: (positionData) => + positionData.endPosition >= 20 && + positionData.startPosition <= positionData.viewportSize, child: Stack( alignment: Alignment.center, children: [ @@ -257,14 +259,24 @@ class _MessageListViewState extends State { if (nextMessage != null && !Jiffy(message.createdAt.toLocal()) .isSame(nextMessage.createdAt.toLocal(), Units.DAY)) { - return VisibleNotifierWidget( - data: i, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - messageWidget, - Padding( - padding: const EdgeInsets.symmetric(vertical: 12.0), + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + messageWidget, + Padding( + padding: const EdgeInsets.symmetric(vertical: 12.0), + child: VisibleNotifierWidget( + condition: ( + ScrollNotification previousNotification, + PositionData previousPositionData, + ScrollNotification currentNotification, + PositionData currentPositionData, + ) { + print( + 'currentPositionData.endPosition: ${currentPositionData.endPosition}'); + return true; + }, + data: i, child: widget.dateDividerBuilder != null ? widget.dateDividerBuilder( nextMessage.createdAt.toLocal()) @@ -272,8 +284,8 @@ class _MessageListViewState extends State { dateTime: nextMessage.createdAt.toLocal(), ), ), - ], - ), + ), + ], ); } @@ -307,14 +319,20 @@ class _MessageListViewState extends State { Positioned( top: 20.0, child: WidgetsVisibilityConsumer( - listener: (context, event,) {}, + listener: ( + context, + event, + ) {}, builder: (context, event) { - if(event.positionDataList == null || event.positionDataList.isEmpty) { + if (event.positionDataList == null || + event.positionDataList.isEmpty) { return Container(); } return DateDivider( - dateTime: _messages[event.positionDataList.last.data].createdAt.toLocal(), + dateTime: _messages[event.positionDataList.last.data] + .createdAt + .toLocal(), ); }, ), From d5f23549f456b426ad4fe7b5fe5f2f665b2997d8 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 28 Oct 2020 11:42:09 +0100 Subject: [PATCH 18/18] modify condition --- lib/src/message_actions_modal.dart | 7 +++++-- lib/src/message_input.dart | 22 +++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 7ee4311c..ce680d34 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -218,13 +218,16 @@ class MessageActionsModal extends StatelessWidget { StreamIcons.edit, size: 22, color: - StreamChatTheme.of(context).primaryIconTheme.color, + StreamChatTheme.of(context).primaryIconTheme.color, ), onPressed: () {}, ), Text( 'Edit message', - style: Theme.of(context).textTheme.headline6.copyWith(fontWeight: FontWeight.bold), + style: Theme.of(context) + .textTheme + .headline6 + .copyWith(fontWeight: FontWeight.bold), ), IconButton( icon: Icon( diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 30910924..d03a61bc 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -192,7 +192,7 @@ class MessageInputState extends State { padding: const EdgeInsets.all(8.0), child: _buildTextField(context), ), - if(widget.parentMessage != null) + if (widget.parentMessage != null) Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: _buildDmCheckbox(), @@ -222,7 +222,11 @@ class MessageInputState extends State { Widget _buildDmCheckbox() { return Row( children: [ - Checkbox(value: _sendAsDm, onChanged: (val) => setState(() {_sendAsDm = val;})), + Checkbox( + value: _sendAsDm, + onChanged: (val) => setState(() { + _sendAsDm = val; + })), Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Text('Send also as direct message'), @@ -316,9 +320,11 @@ class MessageInputState extends State { var matchedCommandsList = StreamChannel.of(context) .channel .config - .commands.where((element) => element.name == s.substring(1)).toList(); + .commands + .where((element) => element.name == s.substring(1)) + .toList(); - if(matchedCommandsList.length == 1) { + if (matchedCommandsList.length == 1) { _chosenCommand = matchedCommandsList[0]; textEditingController.clear(); _messageIsPresent = false; @@ -796,8 +802,8 @@ class MessageInputState extends State { return Center( child: InkWell( child: Padding( - padding: EdgeInsets.only( - left: 8.0, right: padding, top: 8.0, bottom: 8.0), + padding: + EdgeInsets.only(left: 8.0, right: padding, top: 8.0, bottom: 8.0), child: Icon(StreamIcons.attach), ), onTap: () { @@ -1053,7 +1059,9 @@ class MessageInputState extends State { child: Transform.rotate( angle: widget.editMessage == null ? -pi / 2 : 0, child: Icon( - widget.editMessage == null ? StreamIcons.send_message : StreamIcons.check_send, + widget.editMessage == null + ? StreamIcons.send_message + : StreamIcons.check_send, color: StreamChatTheme.of(context).accentColor, ), ),