From 7beb14dfafe1b65d0178e3669cb30bb48e0b1490 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 5 Nov 2024 11:55:05 -0500 Subject: [PATCH 1/2] reorder options in chat header --- .../chat/message_selection_overlay.dart | 64 +++++++++---------- lib/pangea/widgets/chat/overlay_header.dart | 48 ++++++-------- 2 files changed, 50 insertions(+), 62 deletions(-) diff --git a/lib/pangea/widgets/chat/message_selection_overlay.dart b/lib/pangea/widgets/chat/message_selection_overlay.dart index ea42c9854..f614bb4e2 100644 --- a/lib/pangea/widgets/chat/message_selection_overlay.dart +++ b/lib/pangea/widgets/chat/message_selection_overlay.dart @@ -550,7 +550,13 @@ class MessageOverlayController extends State messageOffset!.dy - messageSize!.height - belowMessageHeight, - child: overlayMessage, + child: Padding( + padding: EdgeInsets.only( + left: horizontalPadding, + right: horizontalPadding, + ), + child: overlayMessage, + ), ) : AnimatedBuilder( animation: _overlayPositionAnimation!, @@ -564,39 +570,33 @@ class MessageOverlayController extends State }, ); - return Padding( - padding: EdgeInsets.only( - left: horizontalPadding, - right: horizontalPadding, - ), - child: Stack( - children: [ - positionedOverlayMessage, - Align( - alignment: Alignment.bottomCenter, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - OverlayFooter(controller: widget.chatController), - ], - ), + return Stack( + children: [ + positionedOverlayMessage, + Align( + alignment: Alignment.bottomCenter, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + OverlayFooter(controller: widget.chatController), + ], ), - if (showDetails) - const SizedBox( - width: FluffyThemes.columnWidth, - ), - ], - ), - ), - Material( - child: OverlayHeader(controller: widget.chatController), + ), + if (showDetails) + const SizedBox( + width: FluffyThemes.columnWidth, + ), + ], ), - ], - ), + ), + Material( + child: OverlayHeader(controller: widget.chatController), + ), + ], ); } } diff --git a/lib/pangea/widgets/chat/overlay_header.dart b/lib/pangea/widgets/chat/overlay_header.dart index cce47adcc..7588cea8a 100644 --- a/lib/pangea/widgets/chat/overlay_header.dart +++ b/lib/pangea/widgets/chat/overlay_header.dart @@ -1,7 +1,7 @@ import 'package:fluffychat/pages/chat/chat.dart'; -import 'package:fluffychat/pages/chat/chat_app_bar_title.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:material_symbols_icons/symbols.dart'; import 'package:matrix/matrix.dart'; class OverlayHeader extends StatelessWidget { @@ -21,21 +21,12 @@ class OverlayHeader extends StatelessWidget { actionsIconTheme: IconThemeData( color: Theme.of(context).colorScheme.primary, ), - leading: IconButton( - icon: const Icon(Icons.close), - onPressed: controller.clearSelectedEvents, - tooltip: L10n.of(context)!.close, - color: Theme.of(context).colorScheme.primary, - ), - titleSpacing: 0, - title: ChatAppBarTitle(controller), actions: [ - if (controller.canEditSelectedEvents) - IconButton( - icon: const Icon(Icons.edit_outlined), - tooltip: L10n.of(context)!.edit, - onPressed: controller.editSelectedEventAction, - ), + IconButton( + icon: const Icon(Symbols.forward), + tooltip: L10n.of(context)!.forward, + onPressed: controller.forwardEventsAction, + ), if (controller.selectedEvents.length == 1 && controller.selectedEvents.single.messageType == MessageTypes.Text) @@ -44,27 +35,30 @@ class OverlayHeader extends StatelessWidget { tooltip: L10n.of(context)!.copy, onPressed: controller.copyEventsAction, ), - if (controller.canSaveSelectedEvent) - // Use builder context to correctly position the share dialog on iPad - Builder( - builder: (context) => IconButton( - icon: Icon(Icons.adaptive.share), - tooltip: L10n.of(context)!.share, - onPressed: () => controller.saveSelectedEvent(context), - ), - ), if (controller.canPinSelectedEvents) IconButton( icon: const Icon(Icons.push_pin_outlined), onPressed: controller.pinEvent, tooltip: L10n.of(context)!.pinMessage, ), + if (controller.canEditSelectedEvents) + IconButton( + icon: const Icon(Icons.edit_outlined), + tooltip: L10n.of(context)!.edit, + onPressed: controller.editSelectedEventAction, + ), if (controller.canRedactSelectedEvents) IconButton( icon: const Icon(Icons.delete_outlined), tooltip: L10n.of(context)!.redactMessage, onPressed: controller.redactEventsAction, ), + if (controller.selectedEvents.length == 1) + IconButton( + icon: const Icon(Icons.shield_outlined), + tooltip: L10n.of(context)!.reportMessage, + onPressed: controller.reportEventAction, + ), if (controller.selectedEvents.length == 1) IconButton( icon: const Icon(Icons.info_outlined), @@ -74,12 +68,6 @@ class OverlayHeader extends StatelessWidget { controller.clearSelectedEvents(); }, ), - if (controller.selectedEvents.length == 1) - IconButton( - icon: const Icon(Icons.shield_outlined), - tooltip: L10n.of(context)!.reportMessage, - onPressed: controller.reportEventAction, - ), ], ), ], From 8330f2c505f30e931a13b7b6378e27d0cf522d24 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 5 Nov 2024 12:58:29 -0500 Subject: [PATCH 2/2] mmove reaction picker down into row with reply button --- lib/pages/chat/chat_input_row.dart | 97 +++++++++++-------- lib/pangea/widgets/chat/overlay_footer.dart | 10 +- .../widgets/chat/pangea_reaction_picker.dart | 86 ++++++++++++++++ 3 files changed, 143 insertions(+), 50 deletions(-) create mode 100644 lib/pangea/widgets/chat/pangea_reaction_picker.dart diff --git a/lib/pages/chat/chat_input_row.dart b/lib/pages/chat/chat_input_row.dart index 340784455..90b9c0793 100644 --- a/lib/pages/chat/chat_input_row.dart +++ b/lib/pages/chat/chat_input_row.dart @@ -1,11 +1,13 @@ import 'package:animations/animations.dart'; import 'package:fluffychat/pangea/choreographer/widgets/send_button.dart'; import 'package:fluffychat/pangea/constants/language_constants.dart'; +import 'package:fluffychat/pangea/widgets/chat/pangea_reaction_picker.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:material_symbols_icons/symbols.dart'; import 'package:matrix/matrix.dart'; import '../../config/themes.dart'; @@ -55,9 +57,9 @@ class ChatInputRow extends StatelessWidget { children: [ Row( // crossAxisAlignment: CrossAxisAlignment.end, + // mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, // Pangea# - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: controller.selectMode ? [ if (controller.selectedEvents @@ -77,50 +79,61 @@ class ChatInputRow extends StatelessWidget { ), ), ) + // #Pangea + // else + // SizedBox( + // height: height, + // child: TextButton( + // onPressed: controller.forwardEventsAction, + // child: Row( + // children: [ + // const Icon(Icons.keyboard_arrow_left_outlined), + // Text(L10n.of(context)!.forward), + // ], + // ), + // ), + // ), else - SizedBox( - height: height, - child: TextButton( - onPressed: controller.forwardEventsAction, - child: Row( - children: [ - const Icon(Icons.keyboard_arrow_left_outlined), - Text(L10n.of(context)!.forward), - ], - ), - ), - ), - controller.selectedEvents.length == 1 - ? controller.selectedEvents.first - .getDisplayEvent(controller.timeline!) - .status - .isSent - ? SizedBox( - height: height, - child: TextButton( - onPressed: controller.replyAction, - child: Row( - children: [ - Text(L10n.of(context)!.reply), - const Icon(Icons.keyboard_arrow_right), - ], + // Pangea# + controller.selectedEvents.length == 1 + ? controller.selectedEvents.first + .getDisplayEvent(controller.timeline!) + .status + .isSent + ? SizedBox( + height: height, + child: TextButton( + onPressed: controller.replyAction, + child: Row( + children: [ + // #Pangea + // Text(L10n.of(context)!.reply), + // const Icon(Icons.keyboard_arrow_right), + const Icon(Symbols.reply), + const SizedBox(width: 6), + Text(L10n.of(context)!.reply), + // Pangea# + ], + ), ), - ), - ) - : SizedBox( - height: height, - child: TextButton( - onPressed: controller.sendAgainAction, - child: Row( - children: [ - Text(L10n.of(context)!.tryToSendAgain), - const SizedBox(width: 4), - const Icon(Icons.send_outlined, size: 16), - ], + ) + : SizedBox( + height: height, + child: TextButton( + onPressed: controller.sendAgainAction, + child: Row( + children: [ + Text(L10n.of(context)!.tryToSendAgain), + const SizedBox(width: 4), + const Icon(Icons.send_outlined, size: 16), + ], + ), ), - ), - ) - : const SizedBox.shrink(), + ) + : const SizedBox.shrink(), + // #Pangea + PangeaReactionsPicker(controller), + // Pangea# ] : [ // #Pangea diff --git a/lib/pangea/widgets/chat/overlay_footer.dart b/lib/pangea/widgets/chat/overlay_footer.dart index b4c51d07c..43c6acbb2 100644 --- a/lib/pangea/widgets/chat/overlay_footer.dart +++ b/lib/pangea/widgets/chat/overlay_footer.dart @@ -1,7 +1,6 @@ import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pages/chat/chat_input_row.dart'; -import 'package:fluffychat/pages/chat/reactions_picker.dart'; import 'package:flutter/material.dart'; class OverlayFooter extends StatelessWidget { @@ -18,7 +17,7 @@ class OverlayFooter extends StatelessWidget { return Container( margin: EdgeInsets.only( - bottom: bottomSheetPadding, + bottom: bottomSheetPadding + 16, left: bottomSheetPadding, right: bottomSheetPadding, ), @@ -34,12 +33,7 @@ class OverlayFooter extends StatelessWidget { borderRadius: const BorderRadius.all( Radius.circular(24), ), - child: Column( - children: [ - ReactionsPicker(controller), - ChatInputRow(controller), - ], - ), + child: ChatInputRow(controller), ), ], ), diff --git a/lib/pangea/widgets/chat/pangea_reaction_picker.dart b/lib/pangea/widgets/chat/pangea_reaction_picker.dart new file mode 100644 index 000000000..33f1a490f --- /dev/null +++ b/lib/pangea/widgets/chat/pangea_reaction_picker.dart @@ -0,0 +1,86 @@ +import 'package:fluffychat/config/app_emojis.dart'; +import 'package:fluffychat/pages/chat/chat.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:matrix/matrix.dart'; + +class PangeaReactionsPicker extends StatelessWidget { + final ChatController controller; + + const PangeaReactionsPicker(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + if (controller.showEmojiPicker) return const SizedBox.shrink(); + final display = controller.editEvent == null && + controller.replyEvent == null && + controller.room.canSendDefaultMessages && + controller.selectedEvents.isNotEmpty; + + if (!display) { + return const SizedBox.shrink(); + } + final emojis = List.from(AppEmojis.emojis); + final allReactionEvents = controller.selectedEvents.first + .aggregatedEvents( + controller.timeline!, + RelationshipTypes.reaction, + ) + .where( + (event) => + event.senderId == event.room.client.userID && + event.type == 'm.reaction', + ); + + for (final event in allReactionEvents) { + try { + emojis.remove(event.content.tryGetMap('m.relates_to')!['key']); + } catch (_) {} + } + return Flexible( + child: Row( + children: [ + Flexible( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: emojis + .map( + (emoji) => InkWell( + borderRadius: BorderRadius.circular(8), + onTap: () => controller.sendEmojiAction(emoji), + child: Container( + width: kIsWeb ? 56 : 48, + alignment: Alignment.center, + child: Text( + emoji, + style: const TextStyle(fontSize: 24), + ), + ), + ), + ) + .toList(), + ), + ), + ), + InkWell( + borderRadius: BorderRadius.circular(8), + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 8), + width: 36, + height: 56, + decoration: BoxDecoration( + color: theme.colorScheme.onInverseSurface, + shape: BoxShape.circle, + ), + child: const Icon(Icons.add_outlined), + ), + onTap: () => controller.pickEmojiReactionAction(allReactionEvents), + ), + ], + ), + ); + } +}