From 3da1f79863e8d646a271a912e036f9c875206787 Mon Sep 17 00:00:00 2001 From: Kelrap Date: Mon, 15 Jul 2024 16:07:21 -0400 Subject: [PATCH] Scroll to make space for toolbar --- lib/pages/chat/chat_event_list.dart | 1 + lib/pages/chat/events/message.dart | 18 ++++++++++---- lib/pages/chat/events/message_content.dart | 8 +++++- lib/pangea/widgets/chat/message_buttons.dart | 3 +++ lib/pangea/widgets/chat/message_toolbar.dart | 26 +++++++++++++++++--- lib/pangea/widgets/chat/overlay_message.dart | 3 +++ lib/pangea/widgets/igc/pangea_rich_text.dart | 7 +++++- 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index 24508bb62..963a2c230 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -168,6 +168,7 @@ class ChatEventList extends StatelessWidget { onSelect: controller.onSelectMessage, scrollToEventId: (String eventId) => controller.scrollToEventId(eventId), + scrollController: controller.scrollController, longPressSelect: controller.selectedEvents.isNotEmpty, // #Pangea selectedDisplayLang: diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 3b2c1b2fb..a1d04cb5c 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -43,6 +43,7 @@ class Message extends StatelessWidget { final bool immersionMode; final bool definitions; final ChatController controller; + final ScrollController scrollController; // Pangea# final Color? avatarPresenceBackgroundColor; @@ -68,6 +69,7 @@ class Message extends StatelessWidget { required this.immersionMode, required this.definitions, required this.controller, + required this.scrollController, // Pangea# super.key, }); @@ -317,10 +319,12 @@ class Message extends StatelessWidget { padding: const EdgeInsets.only(left: 8), child: GestureDetector( // #Pangea - onTap: () => - toolbarController?.showToolbar(context), - onDoubleTap: () => - toolbarController?.showToolbar(context), + onTap: () => toolbarController?.showToolbar( + context, + scrollController, + ), + onDoubleTap: () => toolbarController + ?.showToolbar(context, scrollController), // Pangea# onLongPress: longPressSelect ? null @@ -443,6 +447,8 @@ class Message extends StatelessWidget { immersionMode: immersionMode, toolbarController: toolbarController, + scrollController: + scrollController, // Pangea# ), if (event.hasAggregatedEvents( @@ -588,7 +594,9 @@ class Message extends StatelessWidget { : MainAxisAlignment.start, children: [ if (pangeaMessageEvent?.showMessageButtons ?? false) - MessageButtons(toolbarController: toolbarController), + MessageButtons( + toolbarController: toolbarController, + scrollController: scrollController), MessageReactions(event, timeline), ], ), diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart index 01ae471f8..ab6c60193 100644 --- a/lib/pages/chat/events/message_content.dart +++ b/lib/pages/chat/events/message_content.dart @@ -39,6 +39,7 @@ class MessageContent extends StatelessWidget { final bool immersionMode; final ToolbarDisplayController? toolbarController; final bool isOverlay; + final ScrollController scrollController; // Pangea# const MessageContent( @@ -52,6 +53,7 @@ class MessageContent extends StatelessWidget { required this.immersionMode, required this.toolbarController, this.isOverlay = false, + required this.scrollController, // Pangea# required this.borderRadius, }); @@ -299,6 +301,7 @@ class MessageContent extends StatelessWidget { style: messageTextStyle, pangeaMessageEvent: pangeaMessageEvent!, immersionMode: immersionMode, + scrollController: scrollController, toolbarController: toolbarController, ); } else if (pangeaMessageEvent != null) { @@ -322,7 +325,8 @@ class MessageContent extends StatelessWidget { toolbarController?.toolbar?.textSelection .onTextSelection(selection); }, - onTap: () => toolbarController?.showToolbar(context), + onTap: () => + toolbarController?.showToolbar(context, scrollController), contextMenuBuilder: (context, state) => (toolbarController?.highlighted ?? false) ? const SizedBox.shrink() @@ -331,10 +335,12 @@ class MessageContent extends StatelessWidget { textSelection: state, onDefine: () => toolbarController?.showToolbar( context, + scrollController, mode: MessageMode.definition, ), onListen: () => toolbarController?.showToolbar( context, + scrollController, mode: MessageMode.textToSpeech, ), ), diff --git a/lib/pangea/widgets/chat/message_buttons.dart b/lib/pangea/widgets/chat/message_buttons.dart index f7748675f..7d3539298 100644 --- a/lib/pangea/widgets/chat/message_buttons.dart +++ b/lib/pangea/widgets/chat/message_buttons.dart @@ -4,15 +4,18 @@ import 'package:flutter/material.dart'; class MessageButtons extends StatelessWidget { final ToolbarDisplayController? toolbarController; + final ScrollController scrollController; const MessageButtons({ super.key, + required this.scrollController, this.toolbarController, }); void showActivity(BuildContext context) { toolbarController?.showToolbar( context, + scrollController, mode: MessageMode.practiceActivity, ); } diff --git a/lib/pangea/widgets/chat/message_toolbar.dart b/lib/pangea/widgets/chat/message_toolbar.dart index 8d2d66b7d..57c814bca 100644 --- a/lib/pangea/widgets/chat/message_toolbar.dart +++ b/lib/pangea/widgets/chat/message_toolbar.dart @@ -59,7 +59,11 @@ class ToolbarDisplayController { ); } - void showToolbar(BuildContext context, {MessageMode? mode}) { + void showToolbar( + BuildContext context, + ScrollController scrollController, { + MessageMode? mode, + }) { bool toolbarUp = true; if (highlighted) return; if (controller.selectMode) { @@ -79,8 +83,23 @@ class ToolbarDisplayController { final Size transformTargetSize = (targetRenderBox as RenderBox).size; messageWidth = transformTargetSize.width; final Offset targetOffset = (targetRenderBox).localToGlobal(Offset.zero); - final double screenHeight = MediaQuery.of(context).size.height; - toolbarUp = targetOffset.dy >= screenHeight / 2; + // final double screenHeight = MediaQuery.of(context).size.height; + // If message is too close to top, make space for toolbar + if (targetOffset.dy < 360) { + // If chat can scroll up, do so + final scrollTo = scrollController.offset - targetOffset.dy + 360 + 118; + if (scrollTo >= 0) { + scrollController.animateTo( + scrollTo, + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + ); + } + // If cannot scroll up enough, show toolbar underneath instead + else { + toolbarUp = false; + } + } } final Widget overlayMessage = OverlayMessage( @@ -89,6 +108,7 @@ class ToolbarDisplayController { immersionMode: immersionMode, ownMessage: pangeaMessageEvent.ownMessage, toolbarController: this, + scrollController: scrollController, width: messageWidth, nextEvent: nextEvent, previousEvent: previousEvent, diff --git a/lib/pangea/widgets/chat/overlay_message.dart b/lib/pangea/widgets/chat/overlay_message.dart index 5f3d46c7e..86ad9cfb8 100644 --- a/lib/pangea/widgets/chat/overlay_message.dart +++ b/lib/pangea/widgets/chat/overlay_message.dart @@ -21,6 +21,7 @@ class OverlayMessage extends StatelessWidget { final bool ownMessage; final ToolbarDisplayController toolbarController; final double? width; + final ScrollController scrollController; const OverlayMessage( this.event, { @@ -31,6 +32,7 @@ class OverlayMessage extends StatelessWidget { required this.immersionMode, required this.ownMessage, required this.toolbarController, + required this.scrollController, this.width, super.key, }); @@ -151,6 +153,7 @@ class OverlayMessage extends StatelessWidget { pangeaMessageEvent: pangeaMessageEvent, immersionMode: immersionMode, toolbarController: toolbarController, + scrollController: scrollController, isOverlay: true, ), if (event.hasAggregatedEvents( diff --git a/lib/pangea/widgets/igc/pangea_rich_text.dart b/lib/pangea/widgets/igc/pangea_rich_text.dart index abf583b3b..4302807e6 100644 --- a/lib/pangea/widgets/igc/pangea_rich_text.dart +++ b/lib/pangea/widgets/igc/pangea_rich_text.dart @@ -21,12 +21,14 @@ class PangeaRichText extends StatefulWidget { final bool immersionMode; final ToolbarDisplayController? toolbarController; final TextStyle? style; + final ScrollController scrollController; const PangeaRichText({ super.key, required this.pangeaMessageEvent, required this.immersionMode, required this.toolbarController, + required this.scrollController, this.style, }); @@ -151,7 +153,8 @@ class PangeaRichTextState extends State { widget.toolbarController?.toolbar?.textSelection .onTextSelection(selection); }, - onTap: () => widget.toolbarController?.showToolbar(context), + onTap: () => widget.toolbarController + ?.showToolbar(context, widget.scrollController), enableInteractiveSelection: widget.toolbarController?.highlighted ?? false, contextMenuBuilder: (context, state) => @@ -162,10 +165,12 @@ class PangeaRichTextState extends State { textSelection: state, onDefine: () => widget.toolbarController?.showToolbar( context, + widget.scrollController, mode: MessageMode.definition, ), onListen: () => widget.toolbarController?.showToolbar( context, + widget.scrollController, mode: MessageMode.textToSpeech, ), ),