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 {
|
class AnchoredSuggestionLayoutResult {
|
||||||
final Offset offset;
|
|
||||||
final double availableHeight;
|
final double availableHeight;
|
||||||
final double? top;
|
final double left;
|
||||||
final double? bottom;
|
final double bottom;
|
||||||
|
|
||||||
const AnchoredSuggestionLayoutResult({
|
const AnchoredSuggestionLayoutResult({
|
||||||
required this.offset,
|
required this.left,
|
||||||
|
required this.bottom,
|
||||||
required this.availableHeight,
|
required this.availableHeight,
|
||||||
this.top,
|
|
||||||
this.bottom,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+69
-16
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/animation.dart';
|
import 'package:flutter/animation.dart';
|
||||||
import 'package:scribe/scribe.dart';
|
import 'package:scribe/scribe.dart';
|
||||||
|
|
||||||
@@ -145,10 +143,11 @@ class AnchoredModalLayoutCalculator {
|
|||||||
required Size screenSize,
|
required Size screenSize,
|
||||||
required Offset anchorPosition,
|
required Offset anchorPosition,
|
||||||
required Size anchorSize,
|
required Size anchorSize,
|
||||||
required double modalMaxHeight,
|
required Size menuSize,
|
||||||
ModalPlacement? preferredPlacement,
|
ModalPlacement? preferredPlacement,
|
||||||
double gap = 8,
|
double gap = 8,
|
||||||
double padding = AIScribeSizes.screenEdgePadding,
|
double verticalOffset = 6,
|
||||||
|
double padding = 8,
|
||||||
}) {
|
}) {
|
||||||
final isTop = preferredPlacement == ModalPlacement.top;
|
final isTop = preferredPlacement == ModalPlacement.top;
|
||||||
|
|
||||||
@@ -157,25 +156,79 @@ class AnchoredModalLayoutCalculator {
|
|||||||
final positionBottom = screenSize.height - anchorPosition.dy + gap;
|
final positionBottom = screenSize.height - anchorPosition.dy + gap;
|
||||||
|
|
||||||
return AnchoredSuggestionLayoutResult(
|
return AnchoredSuggestionLayoutResult(
|
||||||
offset: Offset(
|
|
||||||
anchorPosition.dx,
|
|
||||||
positionBottom,
|
|
||||||
),
|
|
||||||
availableHeight: availableHeight,
|
availableHeight: availableHeight,
|
||||||
|
left: anchorPosition.dx,
|
||||||
bottom: positionBottom,
|
bottom: positionBottom,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final spaceBelow = screenSize.height - anchorPosition.dy - padding - gap;
|
late ModalPlacement placement;
|
||||||
final positionTop = anchorPosition.dx + anchorSize.width + gap;
|
|
||||||
|
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(
|
return AnchoredSuggestionLayoutResult(
|
||||||
offset: Offset(
|
availableHeight: menuSize.height,
|
||||||
positionTop,
|
left: left,
|
||||||
anchorPosition.dy,
|
bottom: bottom,
|
||||||
),
|
|
||||||
availableHeight: min(spaceBelow, modalMaxHeight),
|
|
||||||
top: anchorPosition.dy,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,8 +104,9 @@ class _AiScribeSuggestionWidgetState extends State<AiScribeSuggestionWidget> {
|
|||||||
screenSize: screenSize,
|
screenSize: screenSize,
|
||||||
anchorPosition: widget.buttonPosition!,
|
anchorPosition: widget.buttonPosition!,
|
||||||
anchorSize: widget.buttonSize!,
|
anchorSize: widget.buttonSize!,
|
||||||
modalMaxHeight: modalMaxHeight,
|
menuSize: Size(modalWidth, modalMaxHeight),
|
||||||
preferredPlacement: widget.preferredPlacement,
|
preferredPlacement: widget.preferredPlacement,
|
||||||
|
padding: AIScribeSizes.screenEdgePadding,
|
||||||
);
|
);
|
||||||
|
|
||||||
return PointerInterceptor(
|
return PointerInterceptor(
|
||||||
@@ -118,8 +119,7 @@ class _AiScribeSuggestionWidgetState extends State<AiScribeSuggestionWidget> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
PositionedDirectional(
|
PositionedDirectional(
|
||||||
start: layout.offset.dx,
|
start: layout.left,
|
||||||
top: layout.top,
|
|
||||||
bottom: layout.bottom,
|
bottom: layout.bottom,
|
||||||
child: _buildModalContainer(
|
child: _buildModalContainer(
|
||||||
width: modalWidth,
|
width: modalWidth,
|
||||||
|
|||||||
Reference in New Issue
Block a user