Merge pull request #1550 from LucasXu0/fix_windows_copy_paste

fix: Clipboard does not work in Windows #1406
This commit is contained in:
Lucas.Xu 2022-12-08 16:13:01 +08:00 committed by GitHub
commit a507fb8ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 14 deletions

View File

@ -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<void> setData({
String? text,
String? html,
}) async {
// https://github.com/BringingFire/rich_clipboard/issues/13
// Wrapping a `<html><body>` tag for html in Windows,
// otherwise it will raise an exception
if (Platform.isWindows && html != null) {
if (!html.startsWith('<html><body>')) {
html = '<html><body>$html</body></html>';
}
}
return RichClipboard.setData(
RichClipboardData(
text: text,
html: html,
),
);
}
static Future<AppFlowyClipboardData> getData() async {
final data = await RichClipboard.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('<!--StartFragment-->', '')
.replaceAll('<!--EndFragment-->', '');
}
return AppFlowyClipboardData(
text: text,
html: html,
);
}
}

View File

@ -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<Node> {
width: width,
alignment: _textToAlignment(align),
onCopy: () {
RichClipboard.setData(RichClipboardData(text: src));
AppFlowyClipboard.setData(text: src);
},
onDelete: () {
final transaction = context.editorState.transaction

View File

@ -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: () {

View File

@ -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;