appflowy-editor/example/lib/pages/editor.dart
2023-09-11 15:03:14 +08:00

163 lines
4.8 KiB
Dart

import 'dart:convert';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
class Editor extends StatelessWidget {
const Editor({
super.key,
required this.jsonString,
required this.onEditorStateChange,
this.editorStyle,
});
final Future<String> jsonString;
final EditorStyle? editorStyle;
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!),
),
),
);
editorState.logConfiguration
..handler = debugPrint
..level = LogLevel.off;
editorState.transactionStream.listen((event) {
if (event.$1 == TransactionTime.after) {
onEditorStateChange(editorState);
}
});
final editorScrollController = EditorScrollController(
editorState: editorState,
shrinkWrap: false,
);
if (PlatformExtension.isDesktopOrWeb) {
return FloatingToolbar(
items: [
paragraphItem,
...headingItems,
...markdownFormatItems,
quoteItem,
bulletedListItem,
numberedListItem,
linkItem,
buildTextColorItem(),
buildHighlightColorItem(),
...textDirectionItems,
...alignmentItems,
],
editorState: editorState,
editorScrollController: editorScrollController,
child: _buildDesktopEditor(
context,
editorState,
editorScrollController,
),
);
} else if (PlatformExtension.isMobile) {
return Column(
children: [
Expanded(
child: _buildMobileEditor(
context,
editorState,
editorScrollController,
),
),
MobileToolbar(
editorState: editorState,
toolbarItems: [
textDecorationMobileToolbarItem,
buildTextAndBackgroundColorMobileToolbarItem(),
headingMobileToolbarItem,
todoListMobileToolbarItem,
listMobileToolbarItem,
linkMobileToolbarItem,
quoteMobileToolbarItem,
dividerMobileToolbarItem,
codeMobileToolbarItem,
],
),
],
);
}
}
return const Center(
child: CircularProgressIndicator(),
);
},
);
}
Widget _buildMobileEditor(
BuildContext context,
EditorState editorState,
EditorScrollController? editorScrollController,
) {
return AppFlowyEditor(
editorStyle: const EditorStyle.mobile(),
editorState: editorState,
editorScrollController: editorScrollController,
);
}
Widget _buildDesktopEditor(
BuildContext context,
EditorState editorState,
EditorScrollController? editorScrollController,
) {
final customBlockComponentBuilders = {
...standardBlockComponentBuilderMap,
ImageBlockKeys.type: ImageBlockComponentBuilder(
showMenu: true,
menuBuilder: (node, _) {
return const Positioned(
right: 10,
child: Text('Sample Menu'),
);
},
)
};
return AppFlowyEditor(
editorState: editorState,
shrinkWrap: true,
editorScrollController: editorScrollController,
blockComponentBuilders: customBlockComponentBuilders,
commandShortcutEvents: [
customToggleHighlightCommand(
style: ToggleColorsStyle(
highlightColor: Theme.of(context).highlightColor,
),
),
...[
...standardCommandShortcutEvents
..removeWhere(
(el) => el == toggleHighlightCommand,
),
],
...findAndReplaceCommands(
context: context,
localizations: FindReplaceLocalizations(
find: 'Find',
previousMatch: 'Previous match',
nextMatch: 'Next match',
close: 'Close',
replace: 'Replace',
replaceAll: 'Replace all',
),
),
],
characterShortcutEvents: standardCharacterShortcutEvents,
);
}
}