From 2382141cc568f7f5dcab0e3b94a70d2a18f988c1 Mon Sep 17 00:00:00 2001 From: krille-chan Date: Thu, 28 Dec 2023 18:46:24 +0100 Subject: [PATCH] chore: Follow up select events --- lib/pages/chat/events/message.dart | 98 ++++++++----------- .../events/message_popup_menu_button.dart | 54 ++++++++++ 2 files changed, 93 insertions(+), 59 deletions(-) create mode 100644 lib/pages/chat/events/message_popup_menu_button.dart diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 938dc045..f04e3e7d 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -1,5 +1,3 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -7,6 +5,7 @@ import 'package:matrix/matrix.dart'; import 'package:swipe_to_action/swipe_to_action.dart'; import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/chat/events/message_popup_menu_button.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/string_color.dart'; import 'package:fluffychat/widgets/avatar.dart'; @@ -125,8 +124,6 @@ class Message extends StatelessWidget { final resetAnimateIn = this.resetAnimateIn; var animateIn = this.animateIn; - TapDownDetails? lastTapDownDetails; - final row = StatefulBuilder( builder: (context, setState) { if (animateIn && resetAnimateIn != null) { @@ -143,6 +140,16 @@ class Message extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: rowMainAxisAlignment, children: [ + AnimatedSize( + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + child: longPressSelect + ? Checkbox.adaptive( + value: selected, + onChanged: (_) => onSelect(event), + ) + : const SizedBox.shrink(), + ), if (sameSender || ownMessage) SizedBox( width: Avatar.defaultSize, @@ -205,19 +212,9 @@ class Message extends StatelessWidget { alignment: alignment, padding: const EdgeInsets.only(left: 8), child: GestureDetector( - onTapDown: (details) { - lastTapDownDetails = details; - }, - onTap: () { - if (lastTapDownDetails?.kind == - PointerDeviceKind.mouse) { - return; - } - onSelect(event); - }, - onLongPress: event.messageType == MessageTypes.Text - ? null - : () => onSelect(event), + onTap: !longPressSelect ? () {} : () => onSelect(event), + onLongPress: + longPressSelect ? () {} : () => onSelect(event), child: AnimatedOpacity( opacity: animateIn ? 0 @@ -232,17 +229,8 @@ class Message extends StatelessWidget { child: Material( color: noBubble ? Colors.transparent : color, clipBehavior: Clip.antiAlias, - elevation: highlightMarker || selected ? 10 : 0, shape: RoundedRectangleBorder( borderRadius: borderRadius, - side: BorderSide( - width: highlightMarker || selected ? 1 : 0, - color: selected - ? Theme.of(context).colorScheme.onBackground - : highlightMarker - ? Theme.of(context).colorScheme.primary - : Colors.transparent, - ), ), child: Container( decoration: BoxDecoration( @@ -433,7 +421,13 @@ class Message extends StatelessWidget { container = row; } - return Center( + return Container( + alignment: Alignment.center, + color: selected + ? Theme.of(context).colorScheme.secondaryContainer.withAlpha(100) + : highlightMarker + ? Theme.of(context).colorScheme.tertiaryContainer.withAlpha(100) + : Colors.transparent, child: Swipeable( key: ValueKey(event.eventId), background: const Padding( @@ -457,50 +451,36 @@ class Message extends StatelessWidget { ), child: container, ), - if (hovered || selected) - Positioned( - left: 4, - bottom: 4, + Positioned( + left: 4, + bottom: 4, + child: AnimatedScale( + duration: Duration( + milliseconds: + (FluffyThemes.animationDuration.inMilliseconds / 2) + .floor(), + ), + curve: FluffyThemes.animationCurve, + scale: !longPressSelect && hovered ? 1 : 0, + alignment: Alignment.center, child: Material( color: Theme.of(context) .colorScheme - .background + .surfaceVariant .withOpacity(0.9), elevation: Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4, borderRadius: BorderRadius.circular(AppConfig.borderRadius), shadowColor: Theme.of(context).appBarTheme.shadowColor, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - IconButton( - icon: Icon( - selected - ? Icons.check_circle - : longPressSelect - ? Icons.check_circle_outlined - : Icons.check_circle_outlined, - size: 16, - ), - tooltip: L10n.of(context)!.select, - onPressed: () => onSelect(event), - ), - if (hovered && - event.room.canSendDefaultMessages && - event.status.isSent) - IconButton( - icon: const Icon( - Icons.reply_outlined, - size: 16, - ), - tooltip: L10n.of(context)!.reply, - onPressed: () => onSwipe(), - ), - ], + child: MessagePopupMenuButton( + event: event, + onReply: onSwipe, + onSelect: () => onSelect(event), ), ), ), + ), ], ), ), diff --git a/lib/pages/chat/events/message_popup_menu_button.dart b/lib/pages/chat/events/message_popup_menu_button.dart new file mode 100644 index 00000000..4cf26421 --- /dev/null +++ b/lib/pages/chat/events/message_popup_menu_button.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +class MessagePopupMenuButton extends StatelessWidget { + final Event event; + final double height; + final void Function() onReply; + final void Function() onSelect; + + const MessagePopupMenuButton({ + required this.event, + required this.onReply, + required this.onSelect, + this.height = 38, + super.key, + }); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: height, + height: height, + child: PopupMenuButton( + iconSize: height / 2, + itemBuilder: (context) => [ + PopupMenuItem( + onTap: onSelect, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.check_box_outlined), + const SizedBox(width: 16), + Text(L10n.of(context)!.select), + ], + ), + ), + PopupMenuItem( + onTap: onReply, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.reply_outlined), + const SizedBox(width: 16), + Text(L10n.of(context)!.reply), + ], + ), + ), + ], + ), + ); + } +}