feat: highlight selection when tap on the link menu

This commit is contained in:
Lucas.Xu 2022-08-29 12:02:47 +08:00
parent c07af9007c
commit dd9cac9c1d
5 changed files with 59 additions and 29 deletions

View File

@ -32,26 +32,29 @@ class EditorNodeWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: node.children
.map(
(child) =>
editorState.service.renderPluginService.buildPluginWidget(
child is TextNode
? NodeWidgetContext<TextNode>(
context: context,
node: child,
editorState: editorState,
)
: NodeWidgetContext<Node>(
context: context,
node: child,
editorState: editorState,
),
),
)
.toList(),
return Container(
color: Colors.red.withOpacity(0.1),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: node.children
.map(
(child) =>
editorState.service.renderPluginService.buildPluginWidget(
child is TextNode
? NodeWidgetContext<TextNode>(
context: context,
node: child,
editorState: editorState,
)
: NodeWidgetContext<Node>(
context: context,
node: child,
editorState: editorState,
),
),
)
.toList(),
),
);
}
}

View File

@ -9,6 +9,7 @@ class LinkMenu extends StatefulWidget {
required this.onOpenLink,
required this.onCopyLink,
required this.onRemoveLink,
required this.onFocusChange,
}) : super(key: key);
final String? linkText;
@ -16,6 +17,7 @@ class LinkMenu extends StatefulWidget {
final VoidCallback onOpenLink;
final VoidCallback onCopyLink;
final VoidCallback onRemoveLink;
final void Function(bool value) onFocusChange;
@override
State<LinkMenu> createState() => _LinkMenuState();
@ -29,11 +31,13 @@ class _LinkMenuState extends State<LinkMenu> {
void initState() {
super.initState();
_textEditingController.text = widget.linkText ?? '';
_focusNode.addListener(_onFocusChange);
}
@override
void dispose() {
_textEditingController.dispose();
_focusNode.removeListener(_onFocusChange);
super.dispose();
}
@ -157,4 +161,8 @@ class _LinkMenuState extends State<LinkMenu> {
onPressed: onPressed,
);
}
void _onFocusChange() {
widget.onFocusChange(_focusNode.hasFocus);
}
}

View File

@ -257,8 +257,11 @@ class _FlowyRichTextState extends State<FlowyRichText> with Selectable {
timer = Timer(const Duration(milliseconds: 200), () {
tapCount = 0;
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
showLinkMenu(context, widget.editorState,
customSelection: selection);
showLinkMenu(
context,
widget.editorState,
customSelection: selection,
);
});
});
};

View File

@ -158,6 +158,7 @@ ToolbarShowValidator _showInTextSelection = (editorState) {
OverlayEntry? _linkMenuOverlay;
EditorState? _editorState;
bool _changeSelectionInner = false;
void showLinkMenu(
BuildContext context,
EditorState editorState, {
@ -180,17 +181,17 @@ void showLinkMenu(
// We get the text node directly instead of judging details again.
final selection = customSelection ??
editorState.service.selectionService.currentSelection.value;
if (selection == null) {
final node = editorState.service.selectionService.currentSelectedNodes;
if (selection == null || node.isEmpty || node.first is! TextNode) {
return;
}
final index =
selection.isBackward ? selection.start.offset : selection.end.offset;
final length = (selection.start.offset - selection.end.offset).abs();
final node = editorState.service.selectionService.currentSelectedNodes.first
as TextNode;
final textNode = node.first as TextNode;
String? linkText;
if (node.allSatisfyLinkInSelection(selection)) {
linkText = node.getAttributeInSelection(selection, StyleKey.href);
if (textNode.allSatisfyLinkInSelection(selection)) {
linkText = textNode.getAttributeInSelection(selection, StyleKey.href);
}
_linkMenuOverlay = OverlayEntry(builder: (context) {
return Positioned(
@ -204,7 +205,7 @@ void showLinkMenu(
},
onSubmitted: (text) {
TransactionBuilder(editorState)
..formatText(node, index, length, {StyleKey.href: text})
..formatText(textNode, index, length, {StyleKey.href: text})
..commit();
_dismissLinkMenu();
},
@ -214,10 +215,17 @@ void showLinkMenu(
},
onRemoveLink: () {
TransactionBuilder(editorState)
..formatText(node, index, length, {StyleKey.href: null})
..formatText(textNode, index, length, {StyleKey.href: null})
..commit();
_dismissLinkMenu();
},
onFocusChange: (value) {
if (value && customSelection != null) {
_changeSelectionInner = true;
editorState.service.selectionService
.updateSelection(customSelection);
}
},
),
),
);
@ -230,6 +238,13 @@ void showLinkMenu(
}
void _dismissLinkMenu() {
if (_editorState?.service.selectionService.currentSelection.value == null) {
return;
}
if (_changeSelectionInner) {
_changeSelectionInner = false;
return;
}
_linkMenuOverlay?.remove();
_linkMenuOverlay = null;

View File

@ -15,6 +15,7 @@ void main() async {
onOpenLink: () {},
onCopyLink: () {},
onRemoveLink: () {},
onFocusChange: (value) {},
onSubmitted: (text) {
submittedText = text;
},