From ac586e0a4db36b416a42e124d8023b876e1227dd Mon Sep 17 00:00:00 2001 From: ggurdin Date: Tue, 15 Oct 2024 10:40:02 -0400 Subject: [PATCH] position overlay cards via tranform follower instead of manually calculating offset, close keyboard when showing span card --- .../controllers/igc_controller.dart | 3 +- lib/pangea/choreographer/widgets/it_bar.dart | 2 + lib/pangea/utils/overlay.dart | 221 +++++++++--------- .../widgets/igc/pangea_text_controller.dart | 4 +- 4 files changed, 112 insertions(+), 118 deletions(-) diff --git a/lib/pangea/choreographer/controllers/igc_controller.dart b/lib/pangea/choreographer/controllers/igc_controller.dart index 470f7a45a..9eeee47b4 100644 --- a/lib/pangea/choreographer/controllers/igc_controller.dart +++ b/lib/pangea/choreographer/controllers/igc_controller.dart @@ -105,6 +105,7 @@ class IgcController { return; } + choreographer.chatController.inputFocus.unfocus(); OverlayUtil.showPositionedCard( context: context, cardToShow: SpanCard( @@ -124,7 +125,7 @@ class IgcController { ), roomId: choreographer.roomId, ), - cardSize: match.isITStart ? const Size(325, 260) : const Size(400, 400), + cardSize: match.isITStart ? const Size(350, 260) : const Size(350, 350), transformTargetId: choreographer.inputTransformTargetKey, ); } diff --git a/lib/pangea/choreographer/widgets/it_bar.dart b/lib/pangea/choreographer/widgets/it_bar.dart index bfc4a174d..0c6a07498 100644 --- a/lib/pangea/choreographer/widgets/it_bar.dart +++ b/lib/pangea/choreographer/widgets/it_bar.dart @@ -308,6 +308,8 @@ class ITChoices extends StatelessWidget { ); return; } + + controller.choreographer.chatController.inputFocus.unfocus(); OverlayUtil.showPositionedCard( context: context, cardToShow: choiceFeedback == null diff --git a/lib/pangea/utils/overlay.dart b/lib/pangea/utils/overlay.dart index cb6ed626a..c15d8e945 100644 --- a/lib/pangea/utils/overlay.dart +++ b/lib/pangea/utils/overlay.dart @@ -1,8 +1,6 @@ import 'dart:developer'; -import 'dart:math'; import 'dart:ui'; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/utils/any_state_holder.dart'; import 'package:fluffychat/pangea/widgets/common_widgets/overlay_container.dart'; import 'package:flutter/foundation.dart'; @@ -22,7 +20,6 @@ class OverlayUtil { required BuildContext context, required Widget child, required String transformTargetId, - // Size? size, double? width, double? height, Offset? offset, @@ -63,13 +60,13 @@ class OverlayUtil { child: (position != OverlayPositionEnum.transform) ? child : CompositedTransformFollower( - targetAnchor: targetAnchor ?? Alignment.topLeft, - followerAnchor: followerAnchor ?? Alignment.topLeft, + targetAnchor: targetAnchor ?? Alignment.topCenter, + followerAnchor: + followerAnchor ?? Alignment.bottomCenter, link: MatrixState.pAnyState .layerLinkAndKey(transformTargetId) .link, showWhenUnlinked: false, - offset: offset ?? Offset.zero, child: child, ), ), @@ -103,11 +100,6 @@ class OverlayUtil { return; } - final Offset cardOffset = _calculateCardOffset( - cardSize: cardSize, - transformTargetContext: layerLinkAndKey.key.currentContext!, - ); - final Widget child = Material( borderOnForeground: false, color: Colors.transparent, @@ -124,7 +116,6 @@ class OverlayUtil { width: cardSize.width, height: cardSize.height, transformTargetId: transformTargetId, - offset: cardOffset, backDropToDismiss: backDropToDismiss, borderColor: borderColor, closePrevOverlay: closePrevOverlay, @@ -135,73 +126,73 @@ class OverlayUtil { } } - /// calculates the card offset relative to the target - /// identified by [transformTargetKey] - static Offset _calculateCardOffset({ - required Size cardSize, - required BuildContext transformTargetContext, - final double minPadding = 10.0, - }) { - // debugger(when: kDebugMode); - //Note: assumes overlay in chatview - final OverlayConstraints constraints = - ChatViewConstraints(transformTargetContext); + // /// calculates the card offset relative to the target + // /// identified by [transformTargetKey] + // static Offset _calculateCardOffset({ + // required Size cardSize, + // required BuildContext transformTargetContext, + // final double minPadding = 10.0, + // }) { + // // debugger(when: kDebugMode); + // //Note: assumes overlay in chatview + // final OverlayConstraints constraints = + // ChatViewConstraints(transformTargetContext); - final RenderObject? targetRenderBox = - transformTargetContext.findRenderObject(); - if (targetRenderBox == null) return Offset.zero; - final Offset transformTargetOffset = - (targetRenderBox as RenderBox).localToGlobal(Offset.zero); - final Size transformTargetSize = targetRenderBox.size; + // final RenderObject? targetRenderBox = + // transformTargetContext.findRenderObject(); + // if (targetRenderBox == null) return Offset.zero; + // final Offset transformTargetOffset = + // (targetRenderBox as RenderBox).localToGlobal(Offset.zero); + // final Size transformTargetSize = targetRenderBox.size; - // ideally horizontally centered on target - double dx = transformTargetSize.width / 2 - cardSize.width / 2; - // make sure it's not off the left edge of the screen - // if transformTargetOffset.dx + dc < constraints.x0 + minPadding + // // ideally horizontally centered on target + // double dx = transformTargetSize.width / 2 - cardSize.width / 2; + // // make sure it's not off the left edge of the screen + // // if transformTargetOffset.dx + dc < constraints.x0 + minPadding - if (transformTargetOffset.dx + dx < minPadding + constraints.x0) { - debugPrint("setting dx"); - dx = minPadding + constraints.x0 - transformTargetOffset.dx; - } - // make sure it's not off the right edge of the screen - if (transformTargetOffset.dx + dx + cardSize.width + minPadding > - constraints.x1) { - dx = constraints.x1 - - transformTargetOffset.dx - - cardSize.width - - minPadding; - } + // if (transformTargetOffset.dx + dx < minPadding + constraints.x0) { + // debugPrint("setting dx"); + // dx = minPadding + constraints.x0 - transformTargetOffset.dx; + // } + // // make sure it's not off the right edge of the screen + // if (transformTargetOffset.dx + dx + cardSize.width + minPadding > + // constraints.x1) { + // dx = constraints.x1 - + // transformTargetOffset.dx - + // cardSize.width - + // minPadding; + // } - // if there's more room above target, - // put the card there - // else, - // put it below - // debugPrint( - // "transformTargetOffset.dx ${transformTargetOffset.dx} transformTargetOffset.dy ${transformTargetOffset.dy}"); - // debugPrint( - // "transformTargetSize.width ${transformTargetSize.width} transformTargetSize.height ${transformTargetSize.height}"); - double dy = transformTargetOffset.dy > - constraints.y1 - - transformTargetOffset.dy - - transformTargetSize.height - ? -cardSize.height - minPadding - : transformTargetSize.height + minPadding; - // make sure it's not off the top edge of the screen - if (dy < minPadding + constraints.y0 - transformTargetOffset.dy) { - dy = minPadding + constraints.y0 - transformTargetOffset.dy; - } - // make sure it's not off the bottom edge of the screen - if (transformTargetOffset.dy + dy + cardSize.height + minPadding > - constraints.y1) { - dy = constraints.y1 - - transformTargetOffset.dy - - cardSize.height - - minPadding; - } - // debugPrint("dx $dx dy $dy"); + // // if there's more room above target, + // // put the card there + // // else, + // // put it below + // // debugPrint( + // // "transformTargetOffset.dx ${transformTargetOffset.dx} transformTargetOffset.dy ${transformTargetOffset.dy}"); + // // debugPrint( + // // "transformTargetSize.width ${transformTargetSize.width} transformTargetSize.height ${transformTargetSize.height}"); + // double dy = transformTargetOffset.dy > + // constraints.y1 - + // transformTargetOffset.dy - + // transformTargetSize.height + // ? -cardSize.height - minPadding + // : transformTargetSize.height + minPadding; + // // make sure it's not off the top edge of the screen + // if (dy < minPadding + constraints.y0 - transformTargetOffset.dy) { + // dy = minPadding + constraints.y0 - transformTargetOffset.dy; + // } + // // make sure it's not off the bottom edge of the screen + // if (transformTargetOffset.dy + dy + cardSize.height + minPadding > + // constraints.y1) { + // dy = constraints.y1 - + // transformTargetOffset.dy - + // cardSize.height - + // minPadding; + // } + // // debugPrint("dx $dx dy $dy"); - return Offset(dx, dy); - } + // return Offset(dx, dy); + // } static bool get isOverlayOpen => MatrixState.pAnyState.entries.isNotEmpty; } @@ -250,48 +241,48 @@ class TransparentBackdrop extends StatelessWidget { } } -/// global coordinates that the overlay should stay inside -abstract class OverlayConstraints { - late double x0; - late double y0; - late double x1; - late double y1; -} +// /// global coordinates that the overlay should stay inside +// abstract class OverlayConstraints { +// late double x0; +// late double y0; +// late double x1; +// late double y1; +// } -class ChatViewConstraints implements OverlayConstraints { - @override - late double x0; - @override - late double y0; - @override - late double x1; - @override - late double y1; +// class ChatViewConstraints implements OverlayConstraints { +// @override +// late double x0; +// @override +// late double y0; +// @override +// late double x1; +// @override +// late double y1; - ChatViewConstraints(BuildContext context) { - final MediaQueryData mediaQueryData = - MediaQuery.of(Scaffold.of(context).context); - final bool isColumnMode = FluffyThemes.isColumnMode(context); +// ChatViewConstraints(BuildContext context) { +// final MediaQueryData mediaQueryData = +// MediaQuery.of(Scaffold.of(context).context); +// final bool isColumnMode = FluffyThemes.isColumnMode(context); - x0 = isColumnMode - ? AppConfig.columnWidth + 70.0 - : max(mediaQueryData.viewPadding.left, mediaQueryData.viewInsets.left); - y0 = max(mediaQueryData.viewPadding.top, mediaQueryData.viewInsets.top); - x1 = mediaQueryData.size.width - - max(mediaQueryData.viewPadding.right, mediaQueryData.viewInsets.right); - y1 = mediaQueryData.size.height - - max( - mediaQueryData.viewPadding.bottom, - mediaQueryData.viewInsets.bottom, - ); +// x0 = isColumnMode +// ? AppConfig.columnWidth + 70.0 +// : max(mediaQueryData.viewPadding.left, mediaQueryData.viewInsets.left); +// y0 = max(mediaQueryData.viewPadding.top, mediaQueryData.viewInsets.top); +// x1 = mediaQueryData.size.width - +// max(mediaQueryData.viewPadding.right, mediaQueryData.viewInsets.right); +// y1 = mediaQueryData.size.height - +// max( +// mediaQueryData.viewPadding.bottom, +// mediaQueryData.viewInsets.bottom, +// ); - // https://medium.com/flutter-community/a-flutter-guide-to-visual-overlap-padding-viewpadding-and-viewinsets-a63e214be6e8 - // debugPrint( - // "viewInsets ${mediaQueryData.viewInsets.left} ${mediaQueryData.viewInsets.top} ${mediaQueryData.viewInsets.right} ${mediaQueryData.viewInsets.bottom}"); - // debugPrint( - // "padding ${mediaQueryData.padding.left} ${mediaQueryData.padding.top} ${mediaQueryData.padding.right} ${mediaQueryData.padding.bottom}"); - // debugPrint( - // "viewPadding ${mediaQueryData.viewPadding.left} ${mediaQueryData.viewPadding.top} ${mediaQueryData.viewPadding.right} ${mediaQueryData.viewPadding.bottom}"); - // debugPrint("chatViewConstraints x0: $x0 y0: $y0 x1: $x1 y1: $y1"); - } -} +// // https://medium.com/flutter-community/a-flutter-guide-to-visual-overlap-padding-viewpadding-and-viewinsets-a63e214be6e8 +// // debugPrint( +// // "viewInsets ${mediaQueryData.viewInsets.left} ${mediaQueryData.viewInsets.top} ${mediaQueryData.viewInsets.right} ${mediaQueryData.viewInsets.bottom}"); +// // debugPrint( +// // "padding ${mediaQueryData.padding.left} ${mediaQueryData.padding.top} ${mediaQueryData.padding.right} ${mediaQueryData.padding.bottom}"); +// // debugPrint( +// // "viewPadding ${mediaQueryData.viewPadding.left} ${mediaQueryData.viewPadding.top} ${mediaQueryData.viewPadding.right} ${mediaQueryData.viewPadding.bottom}"); +// // debugPrint("chatViewConstraints x0: $x0 y0: $y0 x1: $x1 y1: $y1"); +// } +// } diff --git a/lib/pangea/widgets/igc/pangea_text_controller.dart b/lib/pangea/widgets/igc/pangea_text_controller.dart index 314c19ee1..63c5b3f94 100644 --- a/lib/pangea/widgets/igc/pangea_text_controller.dart +++ b/lib/pangea/widgets/igc/pangea_text_controller.dart @@ -114,8 +114,8 @@ class PangeaTextController extends TextEditingController { context: context, cardSize: matchIndex != -1 && choreographer.igc.igcTextData!.matches[matchIndex].isITStart - ? const Size(325, 260) - : const Size(325, 400), + ? const Size(350, 260) + : const Size(350, 400), cardToShow: cardToShow, transformTargetId: choreographer.inputTransformTargetKey, );