main.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:example/plugin/underscore_to_italic_key_event_handler.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/services.dart';
  6. import 'package:path_provider/path_provider.dart';
  7. import 'package:appflowy_editor/appflowy_editor.dart';
  8. import 'expandable_floating_action_button.dart';
  9. void main() {
  10. runApp(const MyApp());
  11. }
  12. class MyApp extends StatelessWidget {
  13. const MyApp({Key? key}) : super(key: key);
  14. @override
  15. Widget build(BuildContext context) {
  16. return MaterialApp(
  17. debugShowCheckedModeBanner: false,
  18. theme: ThemeData(
  19. primarySwatch: Colors.blue,
  20. ),
  21. home: const MyHomePage(title: 'AppFlowyEditor Example'),
  22. );
  23. }
  24. }
  25. class MyHomePage extends StatefulWidget {
  26. const MyHomePage({Key? key, required this.title}) : super(key: key);
  27. final String title;
  28. @override
  29. State<MyHomePage> createState() => _MyHomePageState();
  30. }
  31. class _MyHomePageState extends State<MyHomePage> {
  32. int _pageIndex = 0;
  33. late EditorState _editorState;
  34. Future<String>? _jsonString;
  35. @override
  36. Widget build(BuildContext context) {
  37. return Scaffold(
  38. extendBodyBehindAppBar: true,
  39. body: _buildEditor(context),
  40. floatingActionButton: _buildExpandableFab(),
  41. );
  42. }
  43. Widget _buildEditor(BuildContext context) {
  44. if (_jsonString != null) {
  45. return _buildEditorWithJsonString(_jsonString!);
  46. }
  47. if (_pageIndex == 0) {
  48. return _buildEditorWithJsonString(
  49. rootBundle.loadString('assets/example.json'),
  50. );
  51. } else if (_pageIndex == 1) {
  52. return _buildEditorWithJsonString(
  53. rootBundle.loadString('assets/big_document.json'),
  54. );
  55. } else if (_pageIndex == 2) {
  56. return _buildEditorWithJsonString(
  57. Future.value(
  58. jsonEncode(EditorState.empty().document.toJson()),
  59. ),
  60. );
  61. }
  62. throw UnimplementedError();
  63. }
  64. Widget _buildEditorWithJsonString(Future<String> jsonString) {
  65. return FutureBuilder<String>(
  66. future: jsonString,
  67. builder: (_, snapshot) {
  68. if (snapshot.hasData) {
  69. _editorState = EditorState(
  70. document: StateTree.fromJson(
  71. Map<String, Object>.from(
  72. json.decode(snapshot.data!),
  73. ),
  74. ),
  75. );
  76. _editorState.logConfiguration
  77. ..level = LogLevel.all
  78. ..handler = (message) {
  79. debugPrint(message);
  80. };
  81. return SizedBox(
  82. width: MediaQuery.of(context).size.width,
  83. child: AppFlowyEditor(
  84. editorState: _editorState,
  85. editorStyle: const EditorStyle.defaultStyle(),
  86. keyEventHandlers: [
  87. underscoreToItalicEvent,
  88. ],
  89. ),
  90. );
  91. } else {
  92. return const Center(
  93. child: CircularProgressIndicator(),
  94. );
  95. }
  96. },
  97. );
  98. }
  99. Widget _buildExpandableFab() {
  100. return ExpandableFab(
  101. distance: 112.0,
  102. children: [
  103. ActionButton(
  104. icon: const Icon(Icons.abc),
  105. onPressed: () => _switchToPage(0),
  106. ),
  107. ActionButton(
  108. icon: const Icon(Icons.abc),
  109. onPressed: () => _switchToPage(1),
  110. ),
  111. ActionButton(
  112. icon: const Icon(Icons.abc),
  113. onPressed: () => _switchToPage(2),
  114. ),
  115. ActionButton(
  116. icon: const Icon(Icons.print),
  117. onPressed: () => {_exportDocument(_editorState)}),
  118. ActionButton(
  119. icon: const Icon(Icons.import_export),
  120. onPressed: () => _importDocument(),
  121. ),
  122. ],
  123. );
  124. }
  125. void _exportDocument(EditorState editorState) async {
  126. final document = editorState.document.toJson();
  127. final json = jsonEncode(document);
  128. final directory = await getTemporaryDirectory();
  129. final path = directory.path;
  130. final file = File('$path/editor.json');
  131. await file.writeAsString(json);
  132. if (mounted) {
  133. ScaffoldMessenger.of(context).showSnackBar(
  134. SnackBar(
  135. content: Text('The document is saved to the ${file.path}'),
  136. ),
  137. );
  138. }
  139. }
  140. void _importDocument() async {
  141. final directory = await getTemporaryDirectory();
  142. final path = directory.path;
  143. final file = File('$path/editor.json');
  144. setState(() {
  145. _jsonString = file.readAsString();
  146. });
  147. }
  148. void _switchToPage(int pageIndex) {
  149. if (pageIndex != _pageIndex) {
  150. setState(() {
  151. _pageIndex = pageIndex;
  152. });
  153. }
  154. }
  155. }