From 91feed9bace0f8a928ac083c648ff4597b9aeeb7 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 8 Jan 2021 14:19:24 +0530 Subject: [PATCH] [MessageActionsModal] Fix various alignment, size and color issues Signed-off-by: Sahil Kumar --- lib/src/message_actions_modal.dart | 207 ++++++++++++++++++----------- lib/src/message_widget.dart | 26 ++-- lib/src/reaction_picker.dart | 103 +++++++------- lib/src/stream_chat_theme.dart | 32 +---- 4 files changed, 199 insertions(+), 169 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index c7ff56e0..d7497676 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:ui'; import 'package:flutter/foundation.dart'; @@ -92,8 +93,9 @@ class MessageActionsModal extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, + crossAxisAlignment: reverse + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, children: [ if (showReactions && (message.status == MessageSendingStatus.SENT || @@ -143,7 +145,6 @@ class MessageActionsModal extends StatelessWidget { ), ); }), - SizedBox(height: 8), TweenAnimationBuilder( tween: Tween(begin: 0.0, end: 1.0), duration: Duration(milliseconds: 300), @@ -153,47 +154,56 @@ class MessageActionsModal extends StatelessWidget { transform: Matrix4.identity() ..scale(val) ..rotateZ(-1.0 + val), - alignment: Alignment.topRight, + alignment: reverse + ? Alignment.topRight + : Alignment.topLeft, child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 48.0, + padding: EdgeInsets.only( + right: reverse ? 16 : 0, + left: reverse ? 0 : 48, ), - child: Material( - color: StreamChatTheme.of(context) - .colorTheme - .whiteSnow, - 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 (showThreadReply && - (message.status == - MessageSendingStatus.SENT || - message.status == null) && - message.parentId == null) - _buildThreadReplyButton(context), - if (showResendMessage) - _buildResendMessage(context), - if (showEditMessage) - _buildEditMessage(context), - if (showDeleteMessage) - _buildDeleteButton(context), - if (showCopyMessage) - _buildCopyButton(context), - ], - ).toList(), + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.75, + child: Material( + color: StreamChatTheme.of(context) + .colorTheme + .whiteSnow, + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.stretch, + children: ListTile.divideTiles( + color: StreamChatTheme.of(context) + .colorTheme + .greyWhisper, + context: context, + tiles: [ + if (showReply && + (message.status == + MessageSendingStatus.SENT || + message.status == null) && + message.parentId == null) + _buildReplyButton(context), + if (showThreadReply && + (message.status == + MessageSendingStatus.SENT || + message.status == null) && + message.parentId == null) + _buildThreadReplyButton(context), + if (showResendMessage) + _buildResendMessage(context), + if (showEditMessage) + _buildEditMessage(context), + if (showCopyMessage) + _buildCopyButton(context), + if (showDeleteMessage) + _buildDeleteButton(context), + ], + ).toList(), + ), ), ), ), @@ -211,12 +221,18 @@ class MessageActionsModal extends StatelessWidget { Widget _buildReplyButton(BuildContext context) { return ListTile( - title: Text( - 'Reply', - style: Theme.of(context).textTheme.headline6, - ), - leading: StreamSvgIcon.reply( - color: StreamChatTheme.of(context).primaryIconTheme.color, + dense: true, + title: Row( + children: [ + StreamSvgIcon.reply( + color: StreamChatTheme.of(context).primaryIconTheme.color, + ), + const SizedBox(width: 16), + Text( + 'Reply', + style: StreamChatTheme.of(context).textTheme.headline, + ), + ], ), onTap: () { Navigator.pop(context); @@ -230,13 +246,21 @@ class MessageActionsModal extends StatelessWidget { Widget _buildDeleteButton(BuildContext context) { final isDeleteFailed = message.status == MessageSendingStatus.FAILED_DELETE; return ListTile( - title: Text( - isDeleteFailed ? 'Retry deleting message' : 'Delete message', - style: - Theme.of(context).textTheme.headline6.copyWith(color: Colors.red), - ), - leading: StreamSvgIcon.delete( - color: Colors.red, + dense: true, + title: Row( + children: [ + StreamSvgIcon.delete( + color: Colors.red, + ), + const SizedBox(width: 16), + Text( + isDeleteFailed ? 'Retry Deleting Message' : 'Delete Message', + style: StreamChatTheme.of(context) + .textTheme + .headline + .copyWith(color: Colors.red), + ), + ], ), onTap: () { Navigator.pop(context); @@ -250,12 +274,19 @@ class MessageActionsModal extends StatelessWidget { Widget _buildCopyButton(BuildContext context) { return ListTile( - title: Text( - 'Copy message', - style: Theme.of(context).textTheme.headline6, - ), - leading: StreamSvgIcon.copy( - color: StreamChatTheme.of(context).primaryIconTheme.color, + dense: true, + title: Row( + children: [ + StreamSvgIcon.copy( + size: 24, + color: StreamChatTheme.of(context).primaryIconTheme.color, + ), + const SizedBox(width: 16), + Text( + 'Copy Message', + style: StreamChatTheme.of(context).textTheme.headline, + ), + ], ), onTap: () async { await Clipboard.setData(ClipboardData(text: message.text)); @@ -266,12 +297,18 @@ class MessageActionsModal extends StatelessWidget { Widget _buildEditMessage(BuildContext context) { return ListTile( - title: Text( - 'Edit message', - style: Theme.of(context).textTheme.headline6, - ), - leading: StreamSvgIcon.edit( - color: StreamChatTheme.of(context).primaryIconTheme.color, + dense: true, + title: Row( + children: [ + StreamSvgIcon.edit( + color: StreamChatTheme.of(context).primaryIconTheme.color, + ), + const SizedBox(width: 16), + Text( + 'Edit Message', + style: StreamChatTheme.of(context).textTheme.headline, + ), + ], ), onTap: () async { Navigator.pop(context); @@ -283,12 +320,18 @@ class MessageActionsModal extends StatelessWidget { Widget _buildResendMessage(BuildContext context) { final isUpdateFailed = message.status == MessageSendingStatus.FAILED_UPDATE; return ListTile( - title: Text( - isUpdateFailed ? 'Resend edited message' : 'Resend', - style: Theme.of(context).textTheme.headline6, - ), - leading: StreamSvgIcon.circle_up( - color: StreamChatTheme.of(context).colorTheme.accentBlue, + dense: true, + title: Row( + children: [ + StreamSvgIcon.circle_up( + color: StreamChatTheme.of(context).colorTheme.accentBlue, + ), + const SizedBox(width: 16), + Text( + isUpdateFailed ? 'Resend Edited Message' : 'Resend', + style: StreamChatTheme.of(context).textTheme.headline, + ), + ], ), onTap: () { Navigator.pop(context); @@ -374,12 +417,18 @@ class MessageActionsModal extends StatelessWidget { Widget _buildThreadReplyButton(BuildContext context) { return ListTile( - title: Text( - 'Thread reply', - style: Theme.of(context).textTheme.headline6, - ), - leading: StreamSvgIcon.thread( - color: StreamChatTheme.of(context).primaryIconTheme.color, + dense: true, + title: Row( + children: [ + StreamSvgIcon.thread( + color: StreamChatTheme.of(context).primaryIconTheme.color, + ), + const SizedBox(width: 16), + Text( + 'Thread Reply', + style: StreamChatTheme.of(context).textTheme.headline, + ), + ], ), onTap: () { Navigator.pop(context); diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 1200f38d..5acf473b 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -423,10 +423,12 @@ class _MessageWidgetState extends State { widget.reverse ? pi : 0), child: CustomPaint( painter: ReactionBubblePainter( - widget.messageTheme - .reactionsBackgroundColor, - widget.messageTheme - .reactionsBorderColor, + StreamChatTheme.of(context) + .colorTheme + .white, + StreamChatTheme.of(context) + .colorTheme + .white, ), ), ), @@ -492,18 +494,16 @@ class _MessageWidgetState extends State { mainAxisSize: MainAxisSize.min, children: [ StreamSvgIcon.eye( - color: - StreamChatTheme.of(context).colorTheme.black.withOpacity(0.5), + color: StreamChatTheme.of(context).colorTheme.grey, size: 16.0, ), SizedBox(width: 8.0), Text( 'Only visible to you', - style: StreamChatTheme.of(context).textTheme.footnote.copyWith( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(0.5)), + style: StreamChatTheme.of(context) + .textTheme + .footnote + .copyWith(color: StreamChatTheme.of(context).colorTheme.grey), ), ], ), @@ -754,9 +754,7 @@ class _MessageWidgetState extends State { side: widget.attachmentBorderSide ?? widget.borderSide ?? BorderSide( - color: Theme.of(context).brightness == Brightness.dark - ? StreamChatTheme.of(context).colorTheme.white.withAlpha(24) - : StreamChatTheme.of(context).colorTheme.black.withAlpha(24), + color: StreamChatTheme.of(context).colorTheme.greyGainsboro, ), borderRadius: widget.attachmentBorderRadiusGeometry ?? widget.borderRadiusGeometry ?? diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 9344b386..c5c42bd1 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -58,62 +58,65 @@ class _ReactionPickerState extends State return Transform.scale( scale: val, child: Material( - color: widget.messageTheme.reactionsBackgroundColor, + color: StreamChatTheme.of(context).colorTheme.white, clipBehavior: Clip.hardEdge, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: reactionIcons.map((reactionIcon) { - final ownReactionIndex = widget.message.ownReactions - ?.indexWhere((reaction) => - reaction.type == reactionIcon.type) ?? - -1; - var index = reactionIcons.indexOf(reactionIcon); + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: reactionIcons.map((reactionIcon) { + final ownReactionIndex = widget.message.ownReactions + ?.indexWhere((reaction) => + reaction.type == reactionIcon.type) ?? + -1; + var index = reactionIcons.indexOf(reactionIcon); - return IconButton( - iconSize: 24, - icon: AnimatedBuilder( - animation: animations[index], - builder: (context, val) { - return Transform( - transform: Matrix4.identity() - ..scale(animations[index].value, - animations[index].value) - ..rotateZ(1.0 - animations[index].value), - child: StreamSvgIcon( - assetName: reactionIcon.assetName, - height: animations[index].value * 24.0, - width: animations[index].value * 24.0, - color: ownReactionIndex != -1 - ? StreamChatTheme.of(context) - .colorTheme - .accentBlue - : Theme.of(context) - .iconTheme - .color - .withOpacity(.5), - ), + return IconButton( + iconSize: 24, + icon: AnimatedBuilder( + animation: animations[index], + builder: (context, val) { + return Transform( + transform: Matrix4.identity() + ..scale(animations[index].value, + animations[index].value) + ..rotateZ(1.0 - animations[index].value), + child: StreamSvgIcon( + assetName: reactionIcon.assetName, + height: animations[index].value * 24.0, + width: animations[index].value * 24.0, + color: ownReactionIndex != -1 + ? StreamChatTheme.of(context) + .colorTheme + .accentBlue + : Theme.of(context) + .iconTheme + .color + .withOpacity(.5), + ), + ); + }), + onPressed: () { + if (ownReactionIndex != -1) { + removeReaction( + context, + widget.message.ownReactions[ownReactionIndex], ); - }), - onPressed: () { - if (ownReactionIndex != -1) { - removeReaction( - context, - widget.message.ownReactions[ownReactionIndex], - ); - } else { - sendReaction( - context, - reactionIcon.type, - ); - } - }, - ); - }).toList(), + } else { + sendReaction( + context, + reactionIcon.type, + ); + } + }, + ); + }).toList(), + ), ), ), ); diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 439bd5ef..c6d2d72f 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -228,19 +228,9 @@ class StreamChatThemeData { inputBackground: colorTheme.white.withAlpha(12), ), ownMessageTheme: MessageTheme( - messageText: TextStyle( - fontSize: 14.5, - color: colorTheme.black, - ), - createdAt: TextStyle( - color: colorTheme.black.withOpacity(.5), - fontSize: 12, - ), - replies: TextStyle( - color: accentColor, - fontWeight: FontWeight.w600, - fontSize: 12, - ), + messageText: textTheme.body, + createdAt: textTheme.footnote.copyWith(color: colorTheme.grey), + replies: textTheme.footnoteBold.copyWith(color: accentColor), messageBackgroundColor: colorTheme.greyGainsboro, reactionsBackgroundColor: colorTheme.white, reactionsBorderColor: colorTheme.greyWhisper, @@ -259,19 +249,9 @@ class StreamChatThemeData { otherMessageTheme: MessageTheme( reactionsBackgroundColor: colorTheme.greyGainsboro, reactionsBorderColor: colorTheme.white, - messageText: TextStyle( - fontSize: 14.5, - color: colorTheme.black, - ), - createdAt: TextStyle( - color: colorTheme.black.withOpacity(.5), - fontSize: 12, - ), - replies: TextStyle( - color: accentColor, - fontWeight: FontWeight.w600, - fontSize: 12, - ), + messageText: textTheme.body, + createdAt: textTheme.footnote.copyWith(color: colorTheme.grey), + replies: textTheme.footnoteBold.copyWith(color: accentColor), messageLinks: TextStyle( color: accentColor, ),