mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: highlight selection when tap on the link menu
This commit is contained in:
parent
c07af9007c
commit
dd9cac9c1d
@ -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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -15,6 +15,7 @@ void main() async {
|
||||
onOpenLink: () {},
|
||||
onCopyLink: () {},
|
||||
onRemoveLink: () {},
|
||||
onFocusChange: (value) {},
|
||||
onSubmitted: (text) {
|
||||
submittedText = text;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user