main.dart 4.3 KB

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