diff --git a/example/pubspec.yaml b/example/pubspec.yaml index cdc07de7..46dc8820 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.1.0+1 +version: 1.1.0+2 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 95ecdea5..7f9c5e85 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -84,155 +84,146 @@ class _MessageActionsModalState extends State { ? 1 : (roughSentenceSize == 0 ? 1 : (roughSentenceSize / roughMaxSize)); - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => Navigator.maybePop(context), - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: StreamChatTheme.of(context).colorTheme.overlay, - ), - ), - ), - Center( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - crossAxisAlignment: widget.reverse - ? CrossAxisAlignment.end - : CrossAxisAlignment.start, - children: [ - if (widget.showReactions && - (widget.message.status == MessageSendingStatus.SENT || - widget.message.status == null)) - Align( - alignment: Alignment( - user.id == widget.message.user.id - ? (divFactor > 1.0 ? 0.0 : (1.0 - divFactor)) - : (divFactor > 1.0 ? 0.0 : -(1.0 - divFactor)), - 0.0), - child: ReactionPicker( - message: widget.message, - messageTheme: widget.messageTheme, - ), - ), - TweenAnimationBuilder( - tween: Tween(begin: 0.0, end: 1.0), - duration: Duration(milliseconds: 300), - builder: (context, val, snapshot) { - return Transform.scale( - scale: val, - child: IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: widget.reverse, - message: widget.message.copyWith( - text: widget.message.text.length > 200 - ? '${widget.message.text.substring(0, 200)}...' - : widget.message.text, - ), - messageTheme: widget.messageTheme, - showReactions: false, - showUsername: false, - showThreadReplyIndicator: false, - showReplyMessage: false, - showUserAvatar: widget.showUserAvatar, - showTimestamp: false, - translateUserAvatar: false, - showReactionPickerIndicator: - widget.showReactions && - (widget.message.status == - MessageSendingStatus.SENT || - widget.message.status == null), - showInChannelIndicator: false, - showSendingIndicator: false, - shape: widget.messageShape, - ), - ), - ); - }), - TweenAnimationBuilder( - tween: Tween(begin: 0.0, end: 1.0), - duration: Duration(milliseconds: 300), - curve: Curves.easeInOut, - builder: (context, val, wid) { - return Transform( - transform: Matrix4.identity() - ..scale(val) - ..rotateZ(-1.0 + val), - alignment: widget.reverse - ? Alignment.topRight - : Alignment.topLeft, - child: Padding( - padding: EdgeInsets.only( - right: widget.reverse ? 16 : 0, - left: widget.reverse ? 0 : 48, - ), - 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 (widget.showReplyMessage && - (widget.message.status == - MessageSendingStatus.SENT || - widget.message.status == - null) && - widget.message.parentId == null) - _buildReplyButton(context), - if (widget.showThreadReplyMessage && - (widget.message.status == - MessageSendingStatus.SENT || - widget.message.status == - null) && - widget.message.parentId == null) - _buildThreadReplyButton(context), - if (widget.showResendMessage) - _buildResendMessage(context), - if (widget.showEditMessage) - _buildEditMessage(context), - if (widget.showCopyMessage) - _buildCopyButton(context), - if (widget.showFlagButton) - _buildFlagButton(context), - if (widget.showDeleteMessage) - _buildDeleteButton(context), - ], - ).toList(), - ), - ), - ), - ), - ); - }) - ], + return TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOutBack, + builder: (context, val, snapshot) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => Navigator.maybePop(context), + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10, + sigmaY: 10, + ), + child: Container( + color: StreamChatTheme.of(context).colorTheme.overlay, + ), ), ), - ), + Transform.scale( + scale: val, + child: Center( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + crossAxisAlignment: widget.reverse + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + if (widget.showReactions && + (widget.message.status == + MessageSendingStatus.SENT || + widget.message.status == null)) + Align( + alignment: Alignment( + user.id == widget.message.user.id + ? (divFactor > 1.0 + ? 0.0 + : (1.0 - divFactor)) + : (divFactor > 1.0 + ? 0.0 + : -(1.0 - divFactor)), + 0.0), + child: ReactionPicker( + message: widget.message, + messageTheme: widget.messageTheme, + ), + ), + IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: widget.reverse, + message: widget.message.copyWith( + text: widget.message.text.length > 200 + ? '${widget.message.text.substring(0, 200)}...' + : widget.message.text, + ), + messageTheme: widget.messageTheme, + showReactions: false, + showUsername: false, + showThreadReplyIndicator: false, + showReplyMessage: false, + showUserAvatar: widget.showUserAvatar, + showTimestamp: false, + translateUserAvatar: false, + showReactionPickerIndicator: + widget.showReactions && + (widget.message.status == + MessageSendingStatus.SENT || + widget.message.status == null), + showInChannelIndicator: false, + showSendingIndicator: false, + shape: widget.messageShape, + ), + ), + Padding( + padding: EdgeInsets.only( + right: widget.reverse ? 16 : 0, + left: widget.reverse ? 0 : 48, + ), + 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 (widget.showReplyMessage && + (widget.message.status == + MessageSendingStatus.SENT || + widget.message.status == null) && + widget.message.parentId == null) + _buildReplyButton(context), + if (widget.showThreadReplyMessage && + (widget.message.status == + MessageSendingStatus.SENT || + widget.message.status == null) && + widget.message.parentId == null) + _buildThreadReplyButton(context), + if (widget.showResendMessage) + _buildResendMessage(context), + if (widget.showEditMessage) + _buildEditMessage(context), + if (widget.showCopyMessage) + _buildCopyButton(context), + if (widget.showFlagButton) + _buildFlagButton(context), + if (widget.showDeleteMessage) + _buildDeleteButton(context), + ], + ).toList(), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ), + ], ), - ], - ), + ); + }, ); } diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index 5c24e047..15a301cc 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -56,86 +56,92 @@ class MessageReactionsModal extends StatelessWidget { ? 1 : (roughSentenceSize == 0 ? 1 : (roughSentenceSize / roughMaxSize)); - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () => Navigator.maybePop(context), - child: Stack( - children: [ - Positioned.fill( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 10, - sigmaY: 10, - ), - child: Container( - color: StreamChatTheme.of(context).colorTheme.overlay, - ), - ), - ), - Center( - child: SingleChildScrollView( - child: 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)) - Align( - alignment: Alignment( - user.id == message.user.id - ? (divFactor > 1.0 ? 0.0 : (1.0 - divFactor)) - : (divFactor > 1.0 ? 0.0 : -(1.0 - divFactor)), - 0.0), - child: ReactionPicker( - message: message, - messageTheme: messageTheme, - ), - ), - TweenAnimationBuilder( - tween: Tween(begin: 0.0, end: 1.0), - duration: Duration(milliseconds: 300), - builder: (context, val, snapshot) { - return Transform.scale( - scale: val, - child: 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, - showUserAvatar: showUserAvatar, - showThreadReplyIndicator: false, - showTimestamp: false, - translateUserAvatar: false, - showSendingIndicator: false, - shape: messageShape, - showInChannelIndicator: false, - showReactionPickerIndicator: showReactions && - (message.status == - MessageSendingStatus.SENT || - message.status == null), - ), - ), - ); - }), - if (message.latestReactions?.isNotEmpty == true) - _buildReactionCard(context), - ], + return TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOutBack, + builder: (context, val, snapshot) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => Navigator.maybePop(context), + child: Stack( + children: [ + Positioned.fill( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: 10, + sigmaY: 10, + ), + child: Container( + color: StreamChatTheme.of(context).colorTheme.overlay, + ), ), ), - ), + Transform.scale( + scale: val, + child: Center( + child: SingleChildScrollView( + child: 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)) + Align( + alignment: Alignment( + user.id == message.user.id + ? (divFactor > 1.0 + ? 0.0 + : (1.0 - divFactor)) + : (divFactor > 1.0 + ? 0.0 + : -(1.0 - divFactor)), + 0.0), + 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, + showUserAvatar: showUserAvatar, + showThreadReplyIndicator: false, + showTimestamp: false, + translateUserAvatar: false, + showSendingIndicator: false, + shape: messageShape, + showInChannelIndicator: false, + showReactionPickerIndicator: showReactions && + (message.status == + MessageSendingStatus.SENT || + message.status == null), + ), + ), + if (message.latestReactions?.isNotEmpty == true) + _buildReactionCard(context), + ], + ), + ), + ), + ), + ), + ], ), - ], - ), + ); + }, ); } @@ -191,64 +197,53 @@ class MessageReactionsModal extends StatelessWidget { BuildContext context, ) { final isCurrentUser = reaction.user.id == currentUser.id; - return TweenAnimationBuilder( - tween: Tween(begin: 0.0, end: 1.0), - duration: Duration(milliseconds: 300), - curve: Curves.easeInOut, - builder: (context, val, snapshot) { - return Transform.scale( - scale: val, - child: 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), - ), - Positioned( - child: Align( - alignment: reverse - ? Alignment.centerRight - : Alignment.centerLeft, - child: ReactionBubble( - reactions: [reaction], - flipTail: !reverse, - borderColor: messageTheme.reactionsBorderColor, - backgroundColor: - messageTheme.reactionsBackgroundColor, - highlightOwnReactions: false, - ), - ), - bottom: 6, - left: isCurrentUser ? 0 : null, - right: isCurrentUser ? 0 : null, - ), - ], - ), - const SizedBox(height: 8), - Text( - reaction.user.name, - style: StreamChatTheme.of(context).textTheme.footnoteBold, - textAlign: TextAlign.center, - ), - ], + 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), ), - ), - ); - }); + Positioned( + child: Align( + alignment: + reverse ? Alignment.centerRight : Alignment.centerLeft, + child: ReactionBubble( + reactions: [reaction], + flipTail: !reverse, + borderColor: messageTheme.reactionsBorderColor, + backgroundColor: messageTheme.reactionsBackgroundColor, + highlightOwnReactions: false, + ), + ), + bottom: 6, + left: isCurrentUser ? 0 : null, + right: isCurrentUser ? 0 : null, + ), + ], + ), + const SizedBox(height: 8), + Text( + reaction.user.name, + style: StreamChatTheme.of(context).textTheme.footnoteBold, + textAlign: TextAlign.center, + ), + ], + ), + ); } } diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index c5c42bd1..bca74a99 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:ezanimation/ezanimation.dart'; import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; @@ -36,13 +38,10 @@ class _ReactionPickerState extends State if (animations.isEmpty && reactionIcons.isNotEmpty) { reactionIcons.forEach((element) { animations.add( - EzAnimation.sequence( - [ - SequenceItem(0.0, 1.4), - SequenceItem(1.4, 1.0), - ], + EzAnimation.tween( + Tween(begin: 0.0, end: 1.0), Duration(milliseconds: 500), - vsync: this, + curve: Curves.easeInOutBack, ), ); }); @@ -52,7 +51,7 @@ class _ReactionPickerState extends State return TweenAnimationBuilder( tween: Tween(begin: 0.0, end: 1.0), - curve: Curves.easeInOutExpo, + curve: Curves.easeInOutBack, duration: Duration(milliseconds: 500), builder: (context, val, wid) { return Transform.scale( @@ -81,15 +80,18 @@ class _ReactionPickerState extends State 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), + return Transform.scale( + scale: animations[index].value, child: StreamSvgIcon( assetName: reactionIcon.assetName, - height: animations[index].value * 24.0, - width: animations[index].value * 24.0, + height: max( + 0, + animations[index].value * 24.0, + ), + width: max( + 0, + animations[index].value * 24.0, + ), color: ownReactionIndex != -1 ? StreamChatTheme.of(context) .colorTheme