2022-11-09 11:37:26 +08:00
|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
|
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
|
|
class SimpleEditor extends StatelessWidget {
|
|
|
|
|
const SimpleEditor({
|
|
|
|
|
super.key,
|
|
|
|
|
required this.jsonString,
|
|
|
|
|
required this.onEditorStateChange,
|
2023-06-23 18:36:33 +08:00
|
|
|
this.editorStyle,
|
2022-11-09 11:37:26 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final Future<String> jsonString;
|
2023-06-23 18:36:33 +08:00
|
|
|
final EditorStyle? editorStyle;
|
2022-11-09 11:37:26 +08:00
|
|
|
final void Function(EditorState editorState) onEditorStateChange;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return FutureBuilder<String>(
|
|
|
|
|
future: jsonString,
|
|
|
|
|
builder: (context, snapshot) {
|
|
|
|
|
if (snapshot.hasData &&
|
|
|
|
|
snapshot.connectionState == ConnectionState.done) {
|
|
|
|
|
final editorState = EditorState(
|
|
|
|
|
document: Document.fromJson(
|
|
|
|
|
Map<String, Object>.from(
|
|
|
|
|
json.decode(snapshot.data!),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
2022-12-20 09:37:18 +08:00
|
|
|
editorState.logConfiguration
|
|
|
|
|
..handler = debugPrint
|
2023-06-23 18:36:33 +08:00
|
|
|
..level = LogLevel.off;
|
2022-11-09 11:37:26 +08:00
|
|
|
onEditorStateChange(editorState);
|
2023-04-28 13:33:13 +08:00
|
|
|
final scrollController = ScrollController();
|
2023-04-25 19:58:48 +08:00
|
|
|
if (PlatformExtension.isDesktopOrWeb) {
|
|
|
|
|
return FloatingToolbar(
|
2023-04-28 16:25:51 +08:00
|
|
|
items: [
|
|
|
|
|
paragraphItem,
|
2023-04-29 16:39:32 +08:00
|
|
|
...headingItems,
|
2023-05-02 18:44:52 +08:00
|
|
|
...markdownFormatItems,
|
2023-04-29 11:22:39 +08:00
|
|
|
quoteItem,
|
|
|
|
|
bulletedListItem,
|
|
|
|
|
numberedListItem,
|
|
|
|
|
linkItem,
|
2023-05-10 22:26:52 -05:00
|
|
|
textColorItem,
|
|
|
|
|
highlightColorItem
|
2023-04-28 16:25:51 +08:00
|
|
|
],
|
2023-04-28 13:33:13 +08:00
|
|
|
editorState: editorState,
|
|
|
|
|
scrollController: scrollController,
|
2023-06-23 18:36:33 +08:00
|
|
|
child: _buildDesktopEditor(
|
2023-04-28 13:33:13 +08:00
|
|
|
context,
|
|
|
|
|
editorState,
|
|
|
|
|
scrollController,
|
|
|
|
|
),
|
|
|
|
|
);
|
2023-06-13 01:01:08 -05:00
|
|
|
} else if (PlatformExtension.isMobile) {
|
2023-04-25 19:58:48 +08:00
|
|
|
return Column(
|
|
|
|
|
children: [
|
2023-04-28 13:33:13 +08:00
|
|
|
Expanded(
|
2023-05-20 05:43:38 -05:00
|
|
|
child: _buildMobileEditor(
|
|
|
|
|
context,
|
|
|
|
|
editorState,
|
|
|
|
|
scrollController,
|
|
|
|
|
),
|
2023-04-28 13:33:13 +08:00
|
|
|
),
|
2023-06-13 01:01:08 -05:00
|
|
|
MobileToolbar(
|
|
|
|
|
editorState: editorState,
|
|
|
|
|
toolbarItems: [
|
|
|
|
|
textDecorationMobileToolbarItem,
|
2023-06-25 02:06:52 -05:00
|
|
|
textAndBackgroundColorMobileToolbarItem,
|
2023-06-13 01:01:08 -05:00
|
|
|
headingMobileToolbarItem,
|
|
|
|
|
todoListMobileToolbarItem,
|
|
|
|
|
listMobileToolbarItem,
|
|
|
|
|
linkMobileToolbarItem,
|
|
|
|
|
quoteMobileToolbarItem,
|
2023-07-03 21:09:44 -05:00
|
|
|
dividerMobileToolbarItem,
|
2023-06-13 01:01:08 -05:00
|
|
|
codeMobileToolbarItem,
|
|
|
|
|
],
|
2023-06-25 02:06:52 -05:00
|
|
|
textColorOptions: [
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.grey.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorGray,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.brown.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorBrown,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.yellow.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorYellow,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.green.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorGreen,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.blue.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorBlue,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.purple.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorPurple,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.pink.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorPink,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.red.toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations.current.fontColorRed,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
backgroundColorOptions: [
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.grey.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorGray,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.brown.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorBrown,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.yellow.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorYellow,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.green.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorGreen,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.blue.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorBlue,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.purple.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorPurple,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.pink.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorPink,
|
|
|
|
|
),
|
|
|
|
|
ColorOption(
|
|
|
|
|
colorHex: Colors.red.withOpacity(0.3).toHex(),
|
|
|
|
|
name: AppFlowyEditorLocalizations
|
|
|
|
|
.current.backgroundColorRed,
|
|
|
|
|
),
|
|
|
|
|
],
|
2023-06-13 01:01:08 -05:00
|
|
|
),
|
2023-04-25 19:58:48 +08:00
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-11-09 11:37:26 +08:00
|
|
|
}
|
2023-06-13 01:01:08 -05:00
|
|
|
return const Center(
|
|
|
|
|
child: CircularProgressIndicator(),
|
|
|
|
|
);
|
2022-11-09 11:37:26 +08:00
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
2023-04-20 13:45:46 +08:00
|
|
|
|
2023-05-20 05:43:38 -05:00
|
|
|
Widget _buildMobileEditor(
|
|
|
|
|
BuildContext context,
|
|
|
|
|
EditorState editorState,
|
|
|
|
|
ScrollController? scrollController,
|
|
|
|
|
) {
|
2023-06-01 15:04:34 +08:00
|
|
|
return AppFlowyEditor.standard(
|
2023-05-20 05:43:38 -05:00
|
|
|
editorStyle: const EditorStyle.mobile(),
|
|
|
|
|
editorState: editorState,
|
|
|
|
|
scrollController: scrollController,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-23 18:36:33 +08:00
|
|
|
Widget _buildDesktopEditor(
|
2023-04-28 13:33:13 +08:00
|
|
|
BuildContext context,
|
|
|
|
|
EditorState editorState,
|
|
|
|
|
ScrollController? scrollController,
|
|
|
|
|
) {
|
2023-06-30 13:40:18 +08:00
|
|
|
final customBlockComponentBuilders = {
|
|
|
|
|
...standardBlockComponentBuilderMap,
|
|
|
|
|
ImageBlockKeys.type: ImageBlockComponentBuilder(
|
|
|
|
|
showMenu: true,
|
|
|
|
|
menuBuilder: (node, _) {
|
|
|
|
|
return const Positioned(
|
|
|
|
|
right: 10,
|
|
|
|
|
child: Text('Sample Menu'),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
};
|
|
|
|
|
return AppFlowyEditor.custom(
|
2023-04-20 13:45:46 +08:00
|
|
|
editorState: editorState,
|
2023-04-28 13:33:13 +08:00
|
|
|
scrollController: scrollController,
|
2023-06-30 13:40:18 +08:00
|
|
|
blockComponentBuilders: customBlockComponentBuilders,
|
|
|
|
|
commandShortcutEvents: standardCommandShortcutEvents,
|
|
|
|
|
characterShortcutEvents: standardCharacterShortcutEvents,
|
2023-04-20 13:45:46 +08:00
|
|
|
);
|
|
|
|
|
}
|
2022-11-09 11:37:26 +08:00
|
|
|
}
|