feat(ai-scribe): Fix alignment of prompt when AI button at very right of composer or response have long result but at the bottom of composer
This commit is contained in:
+4
-8
@@ -1,15 +1,11 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class AnchoredSuggestionLayoutResult {
|
||||
final Offset offset;
|
||||
final double availableHeight;
|
||||
final double? top;
|
||||
final double? bottom;
|
||||
final double left;
|
||||
final double bottom;
|
||||
|
||||
const AnchoredSuggestionLayoutResult({
|
||||
required this.offset,
|
||||
required this.left,
|
||||
required this.bottom,
|
||||
required this.availableHeight,
|
||||
this.top,
|
||||
this.bottom,
|
||||
});
|
||||
}
|
||||
|
||||
+69
-16
@@ -1,5 +1,3 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/animation.dart';
|
||||
import 'package:scribe/scribe.dart';
|
||||
|
||||
@@ -145,10 +143,11 @@ class AnchoredModalLayoutCalculator {
|
||||
required Size screenSize,
|
||||
required Offset anchorPosition,
|
||||
required Size anchorSize,
|
||||
required double modalMaxHeight,
|
||||
required Size menuSize,
|
||||
ModalPlacement? preferredPlacement,
|
||||
double gap = 8,
|
||||
double padding = AIScribeSizes.screenEdgePadding,
|
||||
double verticalOffset = 6,
|
||||
double padding = 8,
|
||||
}) {
|
||||
final isTop = preferredPlacement == ModalPlacement.top;
|
||||
|
||||
@@ -157,25 +156,79 @@ class AnchoredModalLayoutCalculator {
|
||||
final positionBottom = screenSize.height - anchorPosition.dy + gap;
|
||||
|
||||
return AnchoredSuggestionLayoutResult(
|
||||
offset: Offset(
|
||||
anchorPosition.dx,
|
||||
positionBottom,
|
||||
),
|
||||
availableHeight: availableHeight,
|
||||
left: anchorPosition.dx,
|
||||
bottom: positionBottom,
|
||||
);
|
||||
}
|
||||
|
||||
final spaceBelow = screenSize.height - anchorPosition.dy - padding - gap;
|
||||
final positionTop = anchorPosition.dx + anchorSize.width + gap;
|
||||
late ModalPlacement placement;
|
||||
|
||||
if (preferredPlacement != null &&
|
||||
_canPlace(
|
||||
placement: preferredPlacement,
|
||||
screen: screenSize,
|
||||
anchor: anchorPosition,
|
||||
anchorSize: anchorSize,
|
||||
menu: menuSize,
|
||||
gap: gap,
|
||||
)) {
|
||||
placement = preferredPlacement;
|
||||
} else {
|
||||
final fallbackOrder = [
|
||||
ModalPlacement.right,
|
||||
ModalPlacement.bottom,
|
||||
ModalPlacement.top,
|
||||
ModalPlacement.left,
|
||||
];
|
||||
|
||||
placement = fallbackOrder.firstWhere(
|
||||
(p) => _canPlace(
|
||||
placement: p,
|
||||
screen: screenSize,
|
||||
anchor: anchorPosition,
|
||||
anchorSize: anchorSize,
|
||||
menu: menuSize,
|
||||
gap: gap,
|
||||
),
|
||||
orElse: () => ModalPlacement.right,
|
||||
);
|
||||
}
|
||||
|
||||
late double left;
|
||||
late double bottom;
|
||||
|
||||
switch (placement) {
|
||||
case ModalPlacement.right:
|
||||
left = anchorPosition.dx + anchorSize.width + gap;
|
||||
bottom = anchorPosition.dy + verticalOffset;
|
||||
break;
|
||||
|
||||
case ModalPlacement.bottom:
|
||||
left = anchorPosition.dx;
|
||||
bottom = anchorPosition.dy + anchorSize.height + gap + verticalOffset;
|
||||
break;
|
||||
|
||||
case ModalPlacement.top:
|
||||
left = anchorPosition.dx;
|
||||
bottom = anchorPosition.dy - menuSize.height - gap + verticalOffset;
|
||||
break;
|
||||
case ModalPlacement.left:
|
||||
left = anchorPosition.dx - menuSize.width - gap;
|
||||
bottom = anchorPosition.dy + verticalOffset;
|
||||
break;
|
||||
}
|
||||
|
||||
left = left.clamp(padding, screenSize.width - menuSize.width - padding);
|
||||
bottom = bottom.clamp(
|
||||
padding,
|
||||
screenSize.height - menuSize.height - padding,
|
||||
);
|
||||
|
||||
return AnchoredSuggestionLayoutResult(
|
||||
offset: Offset(
|
||||
positionTop,
|
||||
anchorPosition.dy,
|
||||
),
|
||||
availableHeight: min(spaceBelow, modalMaxHeight),
|
||||
top: anchorPosition.dy,
|
||||
availableHeight: menuSize.height,
|
||||
left: left,
|
||||
bottom: bottom,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,8 +104,9 @@ class _AiScribeSuggestionWidgetState extends State<AiScribeSuggestionWidget> {
|
||||
screenSize: screenSize,
|
||||
anchorPosition: widget.buttonPosition!,
|
||||
anchorSize: widget.buttonSize!,
|
||||
modalMaxHeight: modalMaxHeight,
|
||||
menuSize: Size(modalWidth, modalMaxHeight),
|
||||
preferredPlacement: widget.preferredPlacement,
|
||||
padding: AIScribeSizes.screenEdgePadding,
|
||||
);
|
||||
|
||||
return PointerInterceptor(
|
||||
@@ -118,8 +119,7 @@ class _AiScribeSuggestionWidgetState extends State<AiScribeSuggestionWidget> {
|
||||
),
|
||||
),
|
||||
PositionedDirectional(
|
||||
start: layout.offset.dx,
|
||||
top: layout.top,
|
||||
start: layout.left,
|
||||
bottom: layout.bottom,
|
||||
child: _buildModalContainer(
|
||||
width: modalWidth,
|
||||
|
||||
Reference in New Issue
Block a user