make popup dimensions dynamic
This commit is contained in:
parent
cc285232fe
commit
2bc421e6e7
8 changed files with 187 additions and 187 deletions
|
|
@ -74,8 +74,11 @@ class Choreographer {
|
|||
CanSendStatus.showPaywall) {
|
||||
OverlayUtil.showPositionedCard(
|
||||
context: context,
|
||||
cardToShow: const PaywallCard(),
|
||||
cardSize: const Size(325, 325),
|
||||
cardToShow: PaywallCard(
|
||||
chatController: chatController,
|
||||
),
|
||||
maxHeight: 325,
|
||||
maxWidth: 325,
|
||||
transformTargetId: inputTransformTargetKey,
|
||||
);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -124,7 +124,8 @@ class IgcController {
|
|||
),
|
||||
roomId: choreographer.roomId,
|
||||
),
|
||||
cardSize: match.isITStart ? const Size(350, 260) : const Size(400, 400),
|
||||
maxHeight: match.isITStart ? 260 : 400,
|
||||
maxWidth: match.isITStart ? 350 : 400,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -339,7 +339,8 @@ class ITChoices extends StatelessWidget {
|
|||
),
|
||||
choiceFeedback: choiceFeedback,
|
||||
),
|
||||
cardSize: const Size(300, 300),
|
||||
maxHeight: 300,
|
||||
maxWidth: 300,
|
||||
borderColor: borderColor,
|
||||
transformTargetId: controller.choreographer.itBarTransformTargetKey,
|
||||
backDropToDismiss: false,
|
||||
|
|
|
|||
|
|
@ -106,21 +106,18 @@ class InstructionsController {
|
|||
onClose: () => {_instructionsClosed[key.toString()] = true},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
key.body(context),
|
||||
style: botStyle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
key.body(context),
|
||||
style: botStyle,
|
||||
),
|
||||
),
|
||||
if (showToggle) InstructionsToggle(instructionsKey: key),
|
||||
],
|
||||
),
|
||||
cardSize: const Size(300.0, 300.0),
|
||||
maxHeight: 300,
|
||||
maxWidth: 300,
|
||||
transformTargetId: transformTargetKey,
|
||||
closePrevOverlay: false,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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,10 +20,8 @@ class OverlayUtil {
|
|||
required BuildContext context,
|
||||
required Widget child,
|
||||
required String transformTargetId,
|
||||
// Size? size,
|
||||
double? width,
|
||||
double? height,
|
||||
Offset? offset,
|
||||
backDropToDismiss = true,
|
||||
blurBackground = false,
|
||||
Color? borderColor,
|
||||
|
|
@ -63,13 +59,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,
|
||||
),
|
||||
),
|
||||
|
|
@ -89,8 +85,9 @@ class OverlayUtil {
|
|||
static showPositionedCard({
|
||||
required BuildContext context,
|
||||
required Widget cardToShow,
|
||||
required Size cardSize,
|
||||
required String transformTargetId,
|
||||
required double maxHeight,
|
||||
required double maxWidth,
|
||||
backDropToDismiss = true,
|
||||
Color? borderColor,
|
||||
bool closePrevOverlay = true,
|
||||
|
|
@ -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,
|
||||
|
|
@ -115,16 +107,15 @@ class OverlayUtil {
|
|||
child: OverlayContainer(
|
||||
cardToShow: cardToShow,
|
||||
borderColor: borderColor,
|
||||
maxHeight: maxHeight,
|
||||
maxWidth: maxWidth,
|
||||
),
|
||||
);
|
||||
|
||||
showOverlay(
|
||||
context: context,
|
||||
child: child,
|
||||
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");
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class OverlayContainer extends StatelessWidget {
|
||||
final Widget cardToShow;
|
||||
final Size cardSize;
|
||||
final Color? borderColor;
|
||||
final double maxHeight;
|
||||
final double maxWidth;
|
||||
|
||||
const OverlayContainer({
|
||||
super.key,
|
||||
required this.cardToShow,
|
||||
this.cardSize = const Size(300.0, 300.0),
|
||||
this.borderColor,
|
||||
required this.maxHeight,
|
||||
required this.maxWidth,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -28,14 +30,17 @@ class OverlayContainer extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: cardSize.width,
|
||||
maxHeight: cardSize.height,
|
||||
minWidth: cardSize.width,
|
||||
minHeight: cardSize.height,
|
||||
maxWidth: maxWidth,
|
||||
maxHeight: maxHeight,
|
||||
),
|
||||
//PTODO - position card above input/message
|
||||
// margin: const EdgeInsets.all(10),
|
||||
child: cardToShow,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [cardToShow],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,11 @@ class PangeaTextController extends TextEditingController {
|
|||
text.isNotEmpty) {
|
||||
OverlayUtil.showPositionedCard(
|
||||
context: context,
|
||||
cardToShow: const PaywallCard(),
|
||||
cardSize: const Size(325, 325),
|
||||
cardToShow: PaywallCard(
|
||||
chatController: choreographer.chatController,
|
||||
),
|
||||
maxHeight: 325,
|
||||
maxWidth: 325,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
);
|
||||
}
|
||||
|
|
@ -112,10 +115,11 @@ class PangeaTextController extends TextEditingController {
|
|||
if (cardToShow != null) {
|
||||
OverlayUtil.showPositionedCard(
|
||||
context: context,
|
||||
cardSize: matchIndex != -1 &&
|
||||
maxHeight: matchIndex != -1 &&
|
||||
choreographer.igc.igcTextData!.matches[matchIndex].isITStart
|
||||
? const Size(350, 260)
|
||||
: const Size(350, 400),
|
||||
? 260
|
||||
: 400,
|
||||
maxWidth: 350,
|
||||
cardToShow: cardToShow,
|
||||
transformTargetId: choreographer.inputTransformTargetKey,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -237,49 +237,47 @@ class WordMatchContent extends StatelessWidget {
|
|||
? controller.currentExpression
|
||||
: BotExpression.addled,
|
||||
),
|
||||
Expanded(
|
||||
child: Scrollbar(
|
||||
Scrollbar(
|
||||
controller: scrollController,
|
||||
thumbVisibility: true,
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
thumbVisibility: true,
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// const SizedBox(height: 10.0),
|
||||
// if (matchCopy.description != null)
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(),
|
||||
// child: Text(
|
||||
// matchCopy.description!,
|
||||
// style: BotStyle.text(context),
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 8),
|
||||
if (!controller.widget.scm.pangeaMatch!.isITStart)
|
||||
ChoicesArray(
|
||||
originalSpan:
|
||||
controller.widget.scm.pangeaMatch!.matchContent,
|
||||
isLoading: controller.fetchingData,
|
||||
choices:
|
||||
controller.widget.scm.pangeaMatch!.match.choices
|
||||
?.map(
|
||||
(e) => Choice(
|
||||
text: e.value,
|
||||
color: e.selected ? e.type.color : null,
|
||||
isGold: e.type.name == 'bestCorrection',
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onPressed: controller.onChoiceSelect,
|
||||
uniqueKeyForLayerLink: (int index) =>
|
||||
"wordMatch$index",
|
||||
selectedChoiceIndex: controller.selectedChoiceIndex,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
PromptAndFeedback(controller: controller),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// const SizedBox(height: 10.0),
|
||||
// if (matchCopy.description != null)
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(),
|
||||
// child: Text(
|
||||
// matchCopy.description!,
|
||||
// style: BotStyle.text(context),
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 8),
|
||||
if (!controller.widget.scm.pangeaMatch!.isITStart)
|
||||
ChoicesArray(
|
||||
originalSpan:
|
||||
controller.widget.scm.pangeaMatch!.matchContent,
|
||||
isLoading: controller.fetchingData,
|
||||
choices:
|
||||
controller.widget.scm.pangeaMatch!.match.choices
|
||||
?.map(
|
||||
(e) => Choice(
|
||||
text: e.value,
|
||||
color: e.selected ? e.type.color : null,
|
||||
isGold: e.type.name == 'bestCorrection',
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onPressed: controller.onChoiceSelect,
|
||||
uniqueKeyForLayerLink: (int index) =>
|
||||
"wordMatch$index",
|
||||
selectedChoiceIndex: controller.selectedChoiceIndex,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
PromptAndFeedback(controller: controller),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue