Skip to content

Commit

Permalink
fix: link menu overflow in right (#478)
Browse files Browse the repository at this point in the history
* fix: link menu overflow in right

* fix: abstract logic

* chore: add type, add comment, mark as private
  • Loading branch information
sun-jiao authored Sep 20, 2023
1 parent 189a41f commit fa207e5
Showing 1 changed file with 60 additions and 17 deletions.
77 changes: 60 additions & 17 deletions lib/src/editor/toolbar/desktop/items/link/link_toolbar_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/toolbar/desktop/items/link/link_menu.dart';
import 'package:flutter/material.dart';

const _menuWidth = 300;
const _hasTextHeight = 244;
const _noTextHeight = 150;

final linkItem = ToolbarItem(
id: 'editor.link',
group: 4,
Expand Down Expand Up @@ -35,7 +39,6 @@ void showLinkMenu(
) {
// Since link format is only available for single line selection,
// the first rect(also the only rect) is used as the starting reference point for the [overlay] position
final rect = editorState.selectionRects().first;

// get link address if the selection is already a link
String? linkText;
Expand All @@ -46,22 +49,7 @@ void showLinkMenu(
);
}

// should abstract this logic to a method
// ----
final left = rect.left + 10;
double? top;
double? bottom;
final offset = rect.center;
final editorOffset = editorState.renderBox!.localToGlobal(Offset.zero);
final editorHeight = editorState.renderBox!.size.height;
final threshold =
editorOffset.dy + editorHeight - (linkText != null ? 244 : 150);
if (offset.dy > threshold) {
bottom = editorOffset.dy + editorHeight - rect.top - 5;
} else {
top = rect.bottom + 5;
}
// ----
final (left, top, right, bottom) = _getPosition(editorState, linkText);

// get node, index and length for formatting text when the link is removed
final node = editorState.getNodeAtPath(selection.end.path);
Expand All @@ -84,6 +72,7 @@ void showLinkMenu(
top: top,
bottom: bottom,
left: left,
right: right,
dismissCallback: () => keepEditorFocusNotifier.value -= 1,
builder: (context) {
return LinkMenu(
Expand Down Expand Up @@ -120,3 +109,57 @@ void showLinkMenu(

Overlay.of(context).insert(overlay!);
}

// get a proper position for link menu
(double? left, double? top, double? right, double? bottom) _getPosition(
EditorState editorState,
String? linkText,
) {
final rect = editorState.selectionRects().first;

double? left, right, top, bottom;
final offset = rect.center;
final editorOffset = editorState.renderBox!.localToGlobal(Offset.zero);
final editorWidth = editorState.renderBox!.size.width;
(left, right) = _getStartEnd(
editorWidth,
offset.dx,
editorOffset.dx,
_menuWidth,
rect.left,
rect.right,
);

final editorHeight = editorState.renderBox!.size.height;
(top, bottom) = _getStartEnd(
editorHeight,
offset.dy,
editorOffset.dy,
linkText != null ? _hasTextHeight : _noTextHeight,
rect.top,
rect.bottom,
);

return (left, top, right, bottom);
}

// This method calculates the start and end position for a specific
// direction (either horizontal or vertical) in the layout.
(double? start, double? end) _getStartEnd(
double editorLength,
double offsetD,
double editorOffsetD,
int menuLength,
double rectStart,
double rectEnd,
) {
final threshold = editorOffsetD + editorLength - _menuWidth;
double? start, end;
if (offsetD > threshold) {
end = editorOffsetD + editorLength - rectStart - 5;
} else {
start = rectEnd + 5;
}

return (start, end);
}

0 comments on commit fa207e5

Please sign in to comment.