mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: unable to paste texts contains section or font tag (#3379)
This commit is contained in:
parent
043c68a333
commit
5f4e3ecc76
File diff suppressed because one or more lines are too long
@ -5,7 +5,6 @@ import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
|||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
import 'package:flowy_infra/theme_extension.dart';
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -243,7 +242,7 @@ class ColorOptionAction extends PopoverActionCell {
|
|||||||
}
|
}
|
||||||
final bgColor =
|
final bgColor =
|
||||||
node.attributes[blockComponentBackgroundColor] as String?;
|
node.attributes[blockComponentBackgroundColor] as String?;
|
||||||
final selectedColor = bgColor?.toColor();
|
final selectedColor = bgColor?.tryToColor();
|
||||||
// get default background color from themeExtension
|
// get default background color from themeExtension
|
||||||
final defaultColor = AFThemeExtension.of(context).calloutBGColor;
|
final defaultColor = AFThemeExtension.of(context).calloutBGColor;
|
||||||
final colors = [
|
final colors = [
|
||||||
|
@ -139,7 +139,7 @@ class _CalloutBlockComponentWidgetState
|
|||||||
Color get backgroundColor {
|
Color get backgroundColor {
|
||||||
final colorString =
|
final colorString =
|
||||||
node.attributes[CalloutBlockKeys.backgroundColor] as String;
|
node.attributes[CalloutBlockKeys.backgroundColor] as String;
|
||||||
return colorString.toColor() ?? Colors.transparent;
|
return colorString.tryToColor() ?? Colors.transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the emoji of the note block from the node's attributes or default to '📌'
|
// get the emoji of the note block from the node's attributes or default to '📌'
|
||||||
|
@ -43,16 +43,32 @@ CommandShortcutEventHandler _pasteCommandHandler = (editorState) {
|
|||||||
// 3. image
|
// 3. image
|
||||||
// 4. plain text
|
// 4. plain text
|
||||||
|
|
||||||
|
// 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();
|
||||||
await editorState.pasteInAppJson(inAppJson);
|
final result = await editorState.pasteInAppJson(inAppJson);
|
||||||
} else if (html != null && html.isNotEmpty) {
|
if (result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (html != null && html.isNotEmpty) {
|
||||||
await editorState.deleteSelectionIfNeeded();
|
await editorState.deleteSelectionIfNeeded();
|
||||||
await editorState.pasteHtml(html);
|
final result = await editorState.pasteHtml(html);
|
||||||
} else if (image != null && image.$2?.isNotEmpty == true) {
|
if (result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image != null && image.$2?.isNotEmpty == true) {
|
||||||
await editorState.deleteSelectionIfNeeded();
|
await editorState.deleteSelectionIfNeeded();
|
||||||
await editorState.pasteImage(image.$1, image.$2!);
|
final result = await editorState.pasteImage(image.$1, image.$2!);
|
||||||
} else if (plainText != null && plainText.isNotEmpty) {
|
if (result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plainText != null && plainText.isNotEmpty) {
|
||||||
await editorState.pastePlainText(plainText);
|
await editorState.pastePlainText(plainText);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
@ -2,7 +2,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_p
|
|||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
|
||||||
extension PasteFromHtml on EditorState {
|
extension PasteFromHtml on EditorState {
|
||||||
Future<void> pasteHtml(String html) async {
|
Future<bool> pasteHtml(String html) async {
|
||||||
final nodes = htmlToDocument(html).root.children.toList();
|
final nodes = htmlToDocument(html).root.children.toList();
|
||||||
// remove the front and back empty line
|
// remove the front and back empty line
|
||||||
while (nodes.isNotEmpty && nodes.first.delta?.isEmpty == true) {
|
while (nodes.isNotEmpty && nodes.first.delta?.isEmpty == true) {
|
||||||
@ -11,13 +11,15 @@ extension PasteFromHtml on EditorState {
|
|||||||
while (nodes.isNotEmpty && nodes.last.delta?.isEmpty == true) {
|
while (nodes.isNotEmpty && nodes.last.delta?.isEmpty == true) {
|
||||||
nodes.removeLast();
|
nodes.removeLast();
|
||||||
}
|
}
|
||||||
|
// if there's no nodes being converted successfully, return false
|
||||||
if (nodes.isEmpty) {
|
if (nodes.isEmpty) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (nodes.length == 1) {
|
if (nodes.length == 1) {
|
||||||
await pasteSingleLineNode(nodes.first);
|
await pasteSingleLineNode(nodes.first);
|
||||||
} else {
|
} else {
|
||||||
await pasteMultiLineNodes(nodes.toList());
|
await pasteMultiLineNodes(nodes.toList());
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,9 @@ extension PasteFromImage on EditorState {
|
|||||||
'gif',
|
'gif',
|
||||||
];
|
];
|
||||||
|
|
||||||
Future<void> pasteImage(String format, Uint8List imageBytes) async {
|
Future<bool> pasteImage(String format, Uint8List imageBytes) async {
|
||||||
if (!supportedImageFormats.contains(format)) {
|
if (!supportedImageFormats.contains(format)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final path = await getIt<ApplicationDataStorage>().getPath();
|
final path = await getIt<ApplicationDataStorage>().getPath();
|
||||||
@ -37,8 +37,10 @@ extension PasteFromImage on EditorState {
|
|||||||
);
|
);
|
||||||
await File(copyToPath).writeAsBytes(imageBytes);
|
await File(copyToPath).writeAsBytes(imageBytes);
|
||||||
await insertImageNode(copyToPath);
|
await insertImageNode(copyToPath);
|
||||||
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error('cannot copy image file', e);
|
Log.error('cannot copy image file', e);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,23 @@ import 'package:appflowy_backend/log.dart';
|
|||||||
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
|
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
|
||||||
|
|
||||||
extension PasteFromInAppJson on EditorState {
|
extension PasteFromInAppJson on EditorState {
|
||||||
Future<void> pasteInAppJson(String inAppJson) async {
|
Future<bool> pasteInAppJson(String inAppJson) async {
|
||||||
try {
|
try {
|
||||||
final nodes = Document.fromJson(jsonDecode(inAppJson)).root.children;
|
final nodes = Document.fromJson(jsonDecode(inAppJson)).root.children;
|
||||||
if (nodes.isEmpty) {
|
if (nodes.isEmpty) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (nodes.length == 1) {
|
if (nodes.length == 1) {
|
||||||
await pasteSingleLineNode(nodes.first);
|
await pasteSingleLineNode(nodes.first);
|
||||||
} else {
|
} else {
|
||||||
await pasteMultiLineNodes(nodes.toList());
|
await pasteMultiLineNodes(nodes.toList());
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error(
|
Log.error(
|
||||||
'Failed to paste in app json: $inAppJson, error: $e',
|
'Failed to paste in app json: $inAppJson, error: $e',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import 'package:appflowy/generated/locale_keys.g.dart';
|
|||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
import 'package:flowy_infra/theme_extension.dart';
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
@ -536,7 +535,7 @@ class ColorItem extends StatelessWidget {
|
|||||||
dimension: 25,
|
dimension: 25,
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: option.colorHex.toColor(),
|
color: option.colorHex.tryToColor(),
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: isChecked
|
child: isChecked
|
||||||
@ -548,7 +547,7 @@ class ColorItem extends StatelessWidget {
|
|||||||
color: Theme.of(context).cardColor,
|
color: Theme.of(context).cardColor,
|
||||||
width: 3.0,
|
width: 3.0,
|
||||||
),
|
),
|
||||||
color: option.colorHex.toColor(),
|
color: option.colorHex.tryToColor(),
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -367,7 +367,7 @@ class DocumentCoverState extends State<DocumentCover> {
|
|||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
);
|
);
|
||||||
case CoverType.color:
|
case CoverType.color:
|
||||||
final color = widget.coverDetails?.toColor() ?? Colors.white;
|
final color = widget.coverDetails?.tryToColor() ?? Colors.white;
|
||||||
return Container(color: color);
|
return Container(color: color);
|
||||||
case CoverType.none:
|
case CoverType.none:
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
|
@ -84,7 +84,7 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
|
|||||||
if (colorString == null) {
|
if (colorString == null) {
|
||||||
return Colors.transparent;
|
return Colors.transparent;
|
||||||
}
|
}
|
||||||
return colorString.toColor() ?? Colors.transparent;
|
return colorString.tryToColor() ?? Colors.transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
late EditorState editorState = context.read<EditorState>();
|
late EditorState editorState = context.read<EditorState>();
|
||||||
|
@ -112,7 +112,7 @@ class TableColorOptionAction extends PopoverActionCell {
|
|||||||
? TableCellBlockKeys.colBackgroundColor
|
? TableCellBlockKeys.colBackgroundColor
|
||||||
: TableCellBlockKeys.rowBackgroundColor;
|
: TableCellBlockKeys.rowBackgroundColor;
|
||||||
final bgColor = cell?.attributes[key] as String?;
|
final bgColor = cell?.attributes[key] as String?;
|
||||||
final selectedColor = bgColor?.toColor();
|
final selectedColor = bgColor?.tryToColor();
|
||||||
// get default background color from themeExtension
|
// get default background color from themeExtension
|
||||||
final defaultColor = AFThemeExtension.of(context).tableCellBGColor;
|
final defaultColor = AFThemeExtension.of(context).tableCellBGColor;
|
||||||
final colors = [
|
final colors = [
|
||||||
|
@ -54,8 +54,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "4a92c88"
|
ref: "6d68f90"
|
||||||
resolved-ref: "4a92c88b6611af95909e4618be3970cc20f6d930"
|
resolved-ref: "6d68f9003fa023d215dc5f20e8900f985c2cdaa1"
|
||||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||||
source: git
|
source: git
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
@ -48,7 +48,7 @@ dependencies:
|
|||||||
appflowy_editor:
|
appflowy_editor:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||||
ref: 4a92c88
|
ref: 6d68f90
|
||||||
appflowy_popover:
|
appflowy_popover:
|
||||||
path: packages/appflowy_popover
|
path: packages/appflowy_popover
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user