From 12b549bad2a11ba35eefc8583de6aaf7b4844117 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 8 Dec 2022 15:19:21 +0800 Subject: [PATCH 1/3] fix: Clipboard does not work in Windows #1406 --- .../lib/src/infra/clipboard.dart | 54 +++++++++++++++++++ .../src/render/image/image_node_builder.dart | 4 +- .../lib/src/render/toolbar/toolbar_item.dart | 4 +- .../copy_paste_handler.dart | 26 +++++---- 4 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart new file mode 100644 index 0000000000..eec6c81f29 --- /dev/null +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart @@ -0,0 +1,54 @@ +import 'dart:io' show Platform; + +import 'package:rich_clipboard/rich_clipboard.dart'; + +class AppFlowyClipboardData { + const AppFlowyClipboardData({ + required this.text, + required this.html, + }); + final String? text; + final String? html; +} + +class AppFlowyClipboard { + static Future setData({ + String? text, + String? html, + }) async { + // https://github.com/BringingFire/rich_clipboard/issues/13 + // Wrapping a `` tag for html in Windows, + // otherwise it will raise an exception + if (Platform.isWindows && html != null) { + if (!html.startsWith('')) { + html = '$html'; + } + } + + return RichClipboard.setData( + RichClipboardData( + text: text, + html: html, + ), + ); + } + + static Future getData() async { + final data = await AppFlowyClipboard.getData(); + final text = data.text; + var html = data.html; + + // https://github.com/BringingFire/rich_clipboard/issues/13 + // Remove all the fragment symbol in Windows. + if (Platform.isWindows && html != null) { + html = html + .replaceAll('', '') + .replaceAll('', ''); + } + + return AppFlowyClipboardData( + text: text, + html: html, + ); + } +} diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_builder.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_builder.dart index 2c84869fbf..56115af39a 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_builder.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_builder.dart @@ -1,7 +1,7 @@ import 'package:appflowy_editor/src/core/document/node.dart'; +import 'package:appflowy_editor/src/infra/clipboard.dart'; import 'package:appflowy_editor/src/service/render_plugin_service.dart'; import 'package:flutter/material.dart'; -import 'package:rich_clipboard/rich_clipboard.dart'; import 'image_node_widget.dart'; @@ -21,7 +21,7 @@ class ImageNodeBuilder extends NodeWidgetBuilder { width: width, alignment: _textToAlignment(align), onCopy: () { - RichClipboard.setData(RichClipboardData(text: src)); + AppFlowyClipboard.setData(text: src); }, onDelete: () { final transaction = context.editorState.transaction diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart index b6051f4877..28c0fdeafb 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart @@ -2,6 +2,7 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/src/commands/text/text_commands.dart'; import 'package:appflowy_editor/src/extensions/url_launcher_extension.dart'; import 'package:appflowy_editor/src/flutter/overlay.dart'; +import 'package:appflowy_editor/src/infra/clipboard.dart'; import 'package:appflowy_editor/src/infra/flowy_svg.dart'; import 'package:appflowy_editor/src/render/link_menu/link_menu.dart'; import 'package:appflowy_editor/src/extensions/text_node_extensions.dart'; @@ -9,7 +10,6 @@ import 'package:appflowy_editor/src/extensions/editor_state_extensions.dart'; import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart'; import 'package:flutter/material.dart' hide Overlay, OverlayEntry; -import 'package:rich_clipboard/rich_clipboard.dart'; typedef ToolbarItemEventHandler = void Function( EditorState editorState, BuildContext context); @@ -363,7 +363,7 @@ void showLinkMenu( _dismissLinkMenu(); }, onCopyLink: () { - RichClipboard.setData(RichClipboardData(text: linkText)); + AppFlowyClipboard.setData(text: linkText); _dismissLinkMenu(); }, onRemoveLink: () { diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart index 3e385fe6d9..0b0c9ec914 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart @@ -1,9 +1,9 @@ import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:appflowy_editor/src/infra/clipboard.dart'; import 'package:appflowy_editor/src/infra/html_converter.dart'; import 'package:appflowy_editor/src/core/document/node_iterator.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/number_list_helper.dart'; import 'package:flutter/material.dart'; -import 'package:rich_clipboard/rich_clipboard.dart'; int _textLengthOfNode(Node node) { if (node is TextNode) { @@ -38,14 +38,15 @@ void _handleCopy(EditorState editorState) async { startOffset: selection.start.offset, endOffset: selection.end.offset) .toHTMLString(); + final textString = textNode.toPlainText().substring( + selection.startIndex, + selection.endIndex, + ); Log.keyboard.debug('copy html: $htmlString'); - RichClipboard.setData(RichClipboardData( + AppFlowyClipboard.setData( + text: textString, html: htmlString, - text: textNode.toPlainText().substring( - selection.startIndex, - selection.endIndex, - ), - )); + ); } else { Log.keyboard.debug('unimplemented: copy non-text'); } @@ -79,7 +80,10 @@ void _handleCopy(EditorState editorState) async { } text += '\n'; } - RichClipboard.setData(RichClipboardData(html: html, text: text)); + AppFlowyClipboard.setData( + text: text, + html: html, + ); } void _pasteHTML(EditorState editorState, String html) { @@ -186,7 +190,7 @@ void _pasteMultipleLinesInText( } void _handlePaste(EditorState editorState) async { - final data = await RichClipboard.getData(); + final data = await AppFlowyClipboard.getData(); if (editorState.cursorSelection?.isCollapsed ?? false) { _pastRichClipboard(editorState, data); @@ -200,7 +204,7 @@ void _handlePaste(EditorState editorState) async { }); } -void _pastRichClipboard(EditorState editorState, RichClipboardData data) { +void _pastRichClipboard(EditorState editorState, AppFlowyClipboardData data) { if (data.html != null) { _pasteHTML(editorState, data.html!); return; @@ -357,6 +361,8 @@ void _deleteSelectedContent(EditorState editorState) { editorState.apply(tb); } +void _setDataToClipboard({String? html, String? text}) {} + ShortcutEventHandler copyEventHandler = (editorState, event) { _handleCopy(editorState); return KeyEventResult.handled; From 1de5b274c3317ecaa75c5a31dcddb557f2f9ade5 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 8 Dec 2022 15:29:59 +0800 Subject: [PATCH 2/3] chore: fix flutter analyze --- .../service/internal_key_event_handlers/copy_paste_handler.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart index 0b0c9ec914..47b8c3967c 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart @@ -361,8 +361,6 @@ void _deleteSelectedContent(EditorState editorState) { editorState.apply(tb); } -void _setDataToClipboard({String? html, String? text}) {} - ShortcutEventHandler copyEventHandler = (editorState, event) { _handleCopy(editorState); return KeyEventResult.handled; From 4db5b7a544b328244b30351e5e3956140ce61005 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 8 Dec 2022 15:50:43 +0800 Subject: [PATCH 3/3] chore: typo --- .../packages/appflowy_editor/lib/src/infra/clipboard.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart index eec6c81f29..d7f692f2fe 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/clipboard.dart @@ -34,7 +34,7 @@ class AppFlowyClipboard { } static Future getData() async { - final data = await AppFlowyClipboard.getData(); + final data = await RichClipboard.getData(); final text = data.text; var html = data.html;