fix: node change notifier doesn't work

This commit is contained in:
Lucas.Xu 2022-07-29 23:16:56 +08:00
parent c4b3c54a7c
commit 55d46edeaf
5 changed files with 54 additions and 87 deletions

View File

@ -55,6 +55,7 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> {
late EditorState _editorState;
final editorKey = GlobalKey();
int page = 0;
@override
@ -116,6 +117,7 @@ class _MyHomePageState extends State<MyHomePage> {
document: document,
);
return FlowyEditor(
key: editorKey,
editorState: _editorState,
keyEventHandlers: const [],
customBuilders: {

View File

@ -12,7 +12,6 @@ import 'package:flowy_editor/render/selection/floating_shortcut_widget.dart';
import 'package:flowy_editor/service/input_service.dart';
import 'package:flowy_editor/service/internal_key_event_handlers/arrow_keys_handler.dart';
import 'package:flowy_editor/service/internal_key_event_handlers/delete_nodes_handler.dart';
import 'package:flowy_editor/service/internal_key_event_handlers/delete_single_text_node_handler.dart';
import 'package:flowy_editor/service/internal_key_event_handlers/enter_in_edge_of_text_node_handler.dart';
import 'package:flowy_editor/service/internal_key_event_handlers/shortcut_handler.dart';
import 'package:flowy_editor/service/keyboard_service.dart';
@ -33,7 +32,6 @@ NodeWidgetBuilders defaultBuilders = {
List<FlowyKeyEventHandler> defaultKeyEventHandler = [
slashShortcutHandler,
flowyDeleteNodesHandler,
deleteSingleTextNodeHandler,
arrowKeysHandler,
enterInEdgeOfTextNodeHandler,
];

View File

@ -94,6 +94,7 @@ class _FlowyInputState extends State<FlowyInput>
// TODO: implement the detail
for (final delta in deltas) {
if (delta is TextEditingDeltaInsertion) {
_applyInsert(delta);
} else if (delta is TextEditingDeltaDeletion) {
} else if (delta is TextEditingDeltaReplacement) {
} else if (delta is TextEditingDeltaNonTextUpdate) {
@ -103,6 +104,27 @@ class _FlowyInputState extends State<FlowyInput>
}
}
void _applyInsert(TextEditingDeltaInsertion delta) {
final selectionService = _editorState.service.selectionService;
final currentSelection = selectionService.currentSelection;
if (currentSelection == null) {
return;
}
if (currentSelection.isSingle) {
final textNode =
selectionService.currentSelectedNodes.value.first as TextNode;
TransactionBuilder(_editorState)
..insertText(
textNode,
delta.insertionOffset,
delta.textInserted,
)
..commit();
} else {
// TODO: implement
}
}
@override
void close() {
_textInputConnection?.close();

View File

@ -1,69 +0,0 @@
import 'package:flowy_editor/document/node.dart';
import 'package:flowy_editor/operation/transaction_builder.dart';
import 'package:flowy_editor/render/selection/selectable.dart';
import 'package:flowy_editor/service/keyboard_service.dart';
import 'package:flowy_editor/extensions/object_extensions.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
// TODO: need to be refactored, just a example code.
FlowyKeyEventHandler deleteSingleTextNodeHandler = (editorState, event) {
if (event.logicalKey != LogicalKeyboardKey.backspace) {
return KeyEventResult.ignored;
}
// final selectionNodes = editorState.selectedNodes;
// if (selectionNodes.length == 1 && selectionNodes.first is TextNode) {
// final node = selectionNodes.first.unwrapOrNull<TextNode>();
// final selectable = node?.key?.currentState?.unwrapOrNull<Selectable>();
// if (selectable != null) {
// final textSelection = selectable.getCurrentTextSelection();
// if (textSelection != null) {
// if (textSelection.isCollapsed) {
// /// Three cases:
// /// Delete the zero character,
// /// 1. if there is still text node in front of it, then merge them.
// /// 2. if not, just ignore
// /// Delete the non-zero character,
// /// 3. delete the single character.
// if (textSelection.baseOffset == 0) {
// if (node?.previous != null && node?.previous is TextNode) {
// final previous = node!.previous! as TextNode;
// final newTextSelection = TextSelection.collapsed(
// offset: previous.toRawString().length);
// final selectionService = editorState.service.selectionService;
// final previousSelectable =
// previous.key?.currentState?.unwrapOrNull<Selectable>();
// final newOfset = previousSelectable
// ?.getOffsetByTextSelection(newTextSelection);
// if (newOfset != null) {
// // selectionService.updateCursor(newOfset);
// }
// // merge
// TransactionBuilder(editorState)
// ..deleteNode(node)
// ..insertText(
// previous, previous.toRawString().length, node.toRawString())
// ..commit();
// return KeyEventResult.handled;
// } else {
// return KeyEventResult.ignored;
// }
// } else {
// TransactionBuilder(editorState)
// ..deleteText(node!, textSelection.baseOffset - 1, 1)
// ..commit();
// final newTextSelection =
// TextSelection.collapsed(offset: textSelection.baseOffset - 1);
// final selectionService = editorState.service.selectionService;
// final newOfset =
// selectable.getOffsetByTextSelection(newTextSelection);
// // selectionService.updateCursor(newOfset);
// return KeyEventResult.handled;
// }
// }
// }
// }
// }
return KeyEventResult.ignored;
};

View File

@ -75,10 +75,7 @@ class FlowyRenderPlugin extends FlowyRenderPluginService {
if (builder != null && builder.nodeValidator(node)) {
final key = GlobalKey(debugLabel: name);
node.key = key;
return _wrap(
builder.build(context),
context,
);
return _autoUpdateNodeWidget(builder, context);
} else {
assert(false, 'Could not query the builder with this $name');
// TODO: return a placeholder widget with tips.
@ -87,14 +84,14 @@ class FlowyRenderPlugin extends FlowyRenderPluginService {
}
@override
void register(String name, NodeWidgetBuilder<Node> builder) {
void register(String name, NodeWidgetBuilder builder) {
debugPrint('[Plugins] registering $name...');
_validatePlugin(name);
_builders[name] = builder;
}
@override
void registerAll(Map<String, NodeWidgetBuilder<Node>> builders) {
void registerAll(Map<String, NodeWidgetBuilder> builders) {
builders.forEach(register);
}
@ -104,18 +101,35 @@ class FlowyRenderPlugin extends FlowyRenderPluginService {
_builders.remove(name);
}
Widget _wrap(Widget widget, NodeWidgetContext context) {
Widget _autoUpdateNodeWidget(
NodeWidgetBuilder builder, NodeWidgetContext context) {
Widget notifier;
if (context.node is TextNode) {
notifier = ChangeNotifierProvider.value(
value: context.node as TextNode,
builder: (_, child) {
return Consumer<TextNode>(
builder: ((_, value, child) {
debugPrint('Text Node is rebuilding...');
return builder.build(context);
}),
);
});
} else {
notifier = ChangeNotifierProvider.value(
value: context.node,
builder: (_, child) {
return Consumer<Node>(
builder: ((_, value, child) {
debugPrint('Node is rebuilding...');
return builder.build(context);
}),
);
});
}
return CompositedTransformTarget(
link: context.node.layerLink,
child: ChangeNotifierProvider<Node>.value(
value: context.node,
builder: (context, child) => Consumer(
builder: ((context, value, child) {
debugPrint('Node is rebuilding...');
return widget;
}),
),
),
child: notifier,
);
}