fix: paste in list (#5621)

* fix: support pasting in list

* test: add simple test

* chore: remove debugPrint
This commit is contained in:
Mathias Mogensen 2024-06-25 20:08:01 +02:00 committed by GitHub
parent c996c9c28e
commit a7f40b2adc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 95 additions and 38 deletions

View File

@ -1,9 +1,10 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
/// Copy. /// Copy.
/// ///

View File

@ -1,4 +1,6 @@
import 'package:appflowy/plugins/document/application/prelude.dart'; import 'package:flutter/material.dart';
import 'package:appflowy/plugins/document/application/document_bloc.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/paste_from_html.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/paste_from_html.dart';
@ -8,12 +10,9 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_p
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:string_validator/string_validator.dart'; import 'package:string_validator/string_validator.dart';
/// Paste.
///
/// - support /// - support
/// - desktop /// - desktop
/// - web /// - web
@ -43,8 +42,7 @@ CommandShortcutEventHandler _pasteCommandHandler = (editorState) {
final image = data.image; final image = data.image;
// paste as link preview // paste as link preview
final result = await _pasteAsLinkPreview(editorState, plainText); if (await _pasteAsLinkPreview(editorState, plainText)) {
if (result) {
return; return;
} }
@ -57,16 +55,14 @@ CommandShortcutEventHandler _pasteCommandHandler = (editorState) {
// try to paste the content in order, if any of them is failed, then try the next one // try to paste the content in order, if any of them is failed, then try the next one
if (inAppJson != null && inAppJson.isNotEmpty) { if (inAppJson != null && inAppJson.isNotEmpty) {
await editorState.deleteSelectionIfNeeded(); await editorState.deleteSelectionIfNeeded();
final result = await editorState.pasteInAppJson(inAppJson); if (await editorState.pasteInAppJson(inAppJson)) {
if (result) {
return; return;
} }
} }
if (html != null && html.isNotEmpty) { if (html != null && html.isNotEmpty) {
await editorState.deleteSelectionIfNeeded(); await editorState.deleteSelectionIfNeeded();
final result = await editorState.pasteHtml(html); if (await editorState.pasteHtml(html)) {
if (result) {
return; return;
} }
} }

View File

@ -1,5 +1,11 @@
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
final _listTypes = [
BulletedListBlockKeys.type,
TodoListBlockKeys.type,
NumberedListBlockKeys.type,
];
extension PasteNodes on EditorState { extension PasteNodes on EditorState {
Future<void> pasteSingleLineNode(Node insertedNode) async { Future<void> pasteSingleLineNode(Node insertedNode) async {
final selection = await deleteSelectionIfNeeded(); final selection = await deleteSelectionIfNeeded();
@ -28,6 +34,19 @@ extension PasteNodes on EditorState {
offset: offset, offset: offset,
), ),
); );
} else if (_listTypes.contains(node.type)) {
final convertedNode = insertedNode.copyWith(type: node.type);
final path = selection.start.path;
transaction
..insertNode(path, convertedNode)
..deleteNodesAtPath(path);
// Set the afterSelection to the last child of the inserted node
final lastChildPath = calculatePath(path, [convertedNode]);
final lastChildOffset = calculateLength([convertedNode]);
transaction.afterSelection = Selection.collapsed(
Position(path: lastChildPath, offset: lastChildOffset),
);
} else if (insertedDelta != null) { } else if (insertedDelta != null) {
// if the node is not empty, insert the delta from inserted node after the selection. // if the node is not empty, insert the delta from inserted node after the selection.
transaction.insertTextDelta(node, selection.endIndex, insertedDelta); transaction.insertTextDelta(node, selection.endIndex, insertedDelta);