feat: add commands and update checkbox logic

This commit is contained in:
Lucas.Xu 2022-09-28 11:21:42 +08:00
parent b578067092
commit 6230d0ad9f
5 changed files with 124 additions and 14 deletions

View File

@ -0,0 +1,62 @@
import 'package:appflowy_editor/src/commands/format_text.dart';
import 'package:appflowy_editor/src/document/attributes.dart';
import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/document/path.dart';
import 'package:appflowy_editor/src/editor_state.dart';
Future<void> formatBuiltInTextAttributes(
EditorState editorState,
String key,
Attributes attributes, {
Path? path,
TextNode? textNode,
}) async {
if (BuiltInAttributeKey.globalStyleKeys.contains(key)) {
assert(!(path != null && textNode != null));
assert(!(path == null && textNode == null));
TextNode formattedTextNode;
if (textNode != null) {
formattedTextNode = textNode;
} else if (path != null) {
formattedTextNode = editorState.document.nodeAtPath(path) as TextNode;
} else {
throw Exception('path and textNode cannot be null at the same time');
}
// remove all the existing style
final newAttributes = formattedTextNode.attributes
..removeWhere((key, value) {
if (BuiltInAttributeKey.globalStyleKeys.contains(key)) {
return true;
}
return false;
})
..addAll(attributes)
..addAll({
BuiltInAttributeKey.subtype: key,
});
return updateTextNodeAttributes(
editorState,
newAttributes,
textNode: textNode,
);
}
}
Future<void> formatTextToCheckbox(
EditorState editorState,
bool check, {
Path? path,
TextNode? textNode,
}) async {
return formatBuiltInTextAttributes(
editorState,
BuiltInAttributeKey.checkbox,
{
BuiltInAttributeKey.checkbox: check,
},
path: path,
textNode: textNode,
);
}

View File

@ -0,0 +1,34 @@
import 'package:appflowy_editor/src/document/attributes.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/document/path.dart';
import 'package:appflowy_editor/src/editor_state.dart';
import 'package:appflowy_editor/src/operation/transaction_builder.dart';
import 'package:flutter/widgets.dart';
Future<void> updateTextNodeAttributes(
EditorState editorState,
Attributes attributes, {
Path? path,
TextNode? textNode,
}) async {
assert(!(path != null && textNode != null));
assert(!(path == null && textNode == null));
TextNode formattedTextNode;
if (textNode != null) {
formattedTextNode = textNode;
} else if (path != null) {
formattedTextNode = editorState.document.nodeAtPath(path) as TextNode;
} else {
throw Exception('path and textNode cannot be null at the same time');
}
TransactionBuilder(editorState)
..updateNode(formattedTextNode, attributes)
..commit();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
print('AAAAAAAAAAAAAA');
return;
});
}

View File

@ -1,15 +1,8 @@
import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/editor_state.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/commands/format_built_in_text.dart';
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
import 'package:appflowy_editor/src/render/rich_text/built_in_text_widget.dart';
import 'package:appflowy_editor/src/render/rich_text/default_selectable.dart';
import 'package:appflowy_editor/src/render/rich_text/flowy_rich_text.dart';
import 'package:appflowy_editor/src/render/selection/selectable.dart';
import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
import 'package:appflowy_editor/src/service/render_plugin_service.dart';
import 'package:appflowy_editor/src/extensions/attributes_extension.dart';
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
import 'package:flutter/material.dart';
@ -82,7 +75,11 @@ class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
name: check ? 'check' : 'uncheck',
),
onTap: () {
formatCheckbox(widget.editorState, !check);
formatTextToCheckbox(
widget.editorState,
!check,
textNode: widget.textNode,
);
},
),
Flexible(

View File

@ -18,6 +18,8 @@ import 'package:appflowy_editor/src/extensions/attributes_extension.dart';
import 'package:appflowy_editor/src/render/selection/selectable.dart';
import 'package:appflowy_editor/src/render/toolbar/toolbar_item.dart';
const _kRichTextDebugMode = false;
typedef FlowyTextSpanDecorator = TextSpan Function(TextSpan textSpan);
class FlowyRichText extends StatefulWidget {
@ -261,6 +263,17 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
),
);
}
if (_kRichTextDebugMode) {
textSpans.add(
TextSpan(
text: '${widget.textNode.path}',
style: const TextStyle(
backgroundColor: Colors.red,
fontSize: 16.0,
),
),
);
}
return TextSpan(
children: textSpans,
);

View File

@ -103,13 +103,17 @@ bool formatTextNodes(EditorState editorState, Attributes attributes) {
final builder = TransactionBuilder(editorState);
for (final textNode in textNodes) {
var newAttributes = {...textNode.attributes};
for (final globalStyleKey in BuiltInAttributeKey.globalStyleKeys) {
if (newAttributes.keys.contains(globalStyleKey)) {
newAttributes[globalStyleKey] = null;
}
}
newAttributes.addAll(attributes);
builder
..updateNode(
textNode,
Attributes.fromIterable(
BuiltInAttributeKey.globalStyleKeys,
value: (_) => null,
)..addAll(attributes),
newAttributes,
)
..afterSelection = Selection.collapsed(
Position(