2023-01-07 09:38:38 +08:00
|
|
|
import 'dart:async';
|
2022-11-09 11:37:26 +08:00
|
|
|
import 'dart:convert';
|
2022-11-09 11:50:08 +08:00
|
|
|
import 'dart:io';
|
2023-09-11 15:03:14 +08:00
|
|
|
import 'dart:math';
|
2022-11-09 11:37:26 +08:00
|
|
|
|
2024-02-21 14:41:55 +07:00
|
|
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
2024-04-11 10:48:12 +08:00
|
|
|
import 'package:example/pages/auto_complete_editor.dart';
|
2024-10-14 09:58:24 +08:00
|
|
|
import 'package:example/pages/auto_expand_editor.dart';
|
2024-03-19 16:38:14 +07:00
|
|
|
import 'package:example/pages/collab_editor.dart';
|
2024-03-27 17:01:34 +08:00
|
|
|
import 'package:example/pages/collab_selection_editor.dart';
|
2023-07-07 16:07:47 +08:00
|
|
|
import 'package:example/pages/customize_theme_for_editor.dart';
|
2024-09-12 20:46:55 +08:00
|
|
|
import 'package:example/pages/drag_to_reorder_editor.dart';
|
2023-07-07 16:07:47 +08:00
|
|
|
import 'package:example/pages/editor.dart';
|
2023-10-17 17:38:27 +08:00
|
|
|
import 'package:example/pages/editor_list.dart';
|
2024-03-07 09:47:23 +08:00
|
|
|
import 'package:example/pages/fixed_toolbar_editor.dart';
|
2023-09-27 09:18:23 +08:00
|
|
|
import 'package:example/pages/focus_example_for_editor.dart';
|
2024-07-04 09:53:25 +08:00
|
|
|
import 'package:example/pages/markdown_editor.dart';
|
2022-11-09 11:50:08 +08:00
|
|
|
import 'package:file_picker/file_picker.dart';
|
2024-02-21 14:41:55 +07:00
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter/services.dart';
|
2023-10-10 00:42:51 -07:00
|
|
|
import 'package:path_provider/path_provider.dart';
|
2024-07-04 05:57:43 +02:00
|
|
|
import 'package:printing/printing.dart';
|
2022-11-09 11:50:08 +08:00
|
|
|
import 'package:universal_html/html.dart' as html;
|
2024-09-11 17:51:53 +08:00
|
|
|
import 'package:universal_platform/universal_platform.dart';
|
2022-11-09 11:37:26 +08:00
|
|
|
|
2022-11-09 14:36:55 +08:00
|
|
|
enum ExportFileType {
|
2023-07-03 19:19:32 +08:00
|
|
|
documentJson,
|
2022-11-09 14:36:55 +08:00
|
|
|
markdown,
|
2024-07-04 05:57:43 +02:00
|
|
|
pdf,
|
2023-01-05 17:08:43 +08:00
|
|
|
delta,
|
2022-11-09 14:36:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension on ExportFileType {
|
|
|
|
|
String get extension {
|
|
|
|
|
switch (this) {
|
2023-07-03 19:19:32 +08:00
|
|
|
case ExportFileType.documentJson:
|
2023-01-05 17:08:43 +08:00
|
|
|
case ExportFileType.delta:
|
2022-11-09 14:36:55 +08:00
|
|
|
return 'json';
|
|
|
|
|
case ExportFileType.markdown:
|
|
|
|
|
return 'md';
|
2024-07-04 05:57:43 +02:00
|
|
|
case ExportFileType.pdf:
|
|
|
|
|
return 'pdf';
|
2022-11-09 14:36:55 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-09 11:37:26 +08:00
|
|
|
class HomePage extends StatefulWidget {
|
2023-11-08 13:46:33 +08:00
|
|
|
const HomePage({super.key});
|
2022-11-09 11:37:26 +08:00
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<HomePage> createState() => _HomePageState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _HomePageState extends State<HomePage> {
|
|
|
|
|
final _scaffoldKey = GlobalKey<ScaffoldState>();
|
2023-07-07 16:07:47 +08:00
|
|
|
|
2022-11-09 11:37:26 +08:00
|
|
|
late WidgetBuilder _widgetBuilder;
|
|
|
|
|
late EditorState _editorState;
|
2022-11-09 15:36:30 +08:00
|
|
|
late Future<String> _jsonString;
|
2022-11-09 11:37:26 +08:00
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
super.initState();
|
|
|
|
|
|
2024-09-11 17:51:53 +08:00
|
|
|
_jsonString = UniversalPlatform.isDesktopOrWeb
|
2023-09-20 11:17:39 +08:00
|
|
|
? rootBundle.loadString('assets/example.json')
|
|
|
|
|
: rootBundle.loadString('assets/mobile_example.json');
|
2023-09-11 15:03:14 +08:00
|
|
|
|
2023-07-07 16:07:47 +08:00
|
|
|
_widgetBuilder = (context) => Editor(
|
2022-11-09 15:36:30 +08:00
|
|
|
jsonString: _jsonString,
|
|
|
|
|
onEditorStateChange: (editorState) {
|
|
|
|
|
_editorState = editorState;
|
|
|
|
|
},
|
|
|
|
|
);
|
2022-11-09 11:37:26 +08:00
|
|
|
}
|
|
|
|
|
|
2023-06-30 13:40:18 +08:00
|
|
|
@override
|
|
|
|
|
void reassemble() {
|
|
|
|
|
super.reassemble();
|
|
|
|
|
|
2023-07-07 16:07:47 +08:00
|
|
|
_widgetBuilder = (context) => Editor(
|
2023-07-03 15:03:19 +02:00
|
|
|
jsonString: _jsonString,
|
|
|
|
|
onEditorStateChange: (editorState) {
|
|
|
|
|
_editorState = editorState;
|
|
|
|
|
_jsonString = Future.value(
|
|
|
|
|
jsonEncode(_editorState.document.toJson()),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
2023-06-30 13:40:18 +08:00
|
|
|
}
|
|
|
|
|
|
2022-11-09 11:37:26 +08:00
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Scaffold(
|
|
|
|
|
key: _scaffoldKey,
|
2024-09-11 17:51:53 +08:00
|
|
|
extendBodyBehindAppBar: UniversalPlatform.isDesktopOrWeb,
|
2022-11-09 11:37:26 +08:00
|
|
|
drawer: _buildDrawer(context),
|
2023-06-20 10:26:22 +08:00
|
|
|
appBar: AppBar(
|
2023-09-18 22:05:17 +08:00
|
|
|
backgroundColor: const Color.fromARGB(255, 134, 46, 247),
|
|
|
|
|
foregroundColor: Colors.white,
|
2023-07-03 15:03:19 +02:00
|
|
|
surfaceTintColor: Colors.transparent,
|
2023-06-23 18:36:33 +08:00
|
|
|
title: const Text('AppFlowy Editor'),
|
2023-06-20 10:26:22 +08:00
|
|
|
),
|
2024-06-11 10:15:15 +08:00
|
|
|
body: SafeArea(
|
|
|
|
|
maintainBottomViewPadding: true,
|
|
|
|
|
child: _widgetBuilder(context),
|
|
|
|
|
),
|
2022-11-09 11:37:26 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildDrawer(BuildContext context) {
|
|
|
|
|
return Drawer(
|
|
|
|
|
child: ListView(
|
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
|
children: [
|
|
|
|
|
DrawerHeader(
|
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
|
margin: EdgeInsets.zero,
|
|
|
|
|
child: Image.asset(
|
2023-09-18 22:05:17 +08:00
|
|
|
'assets/images/icon.jpeg',
|
2022-11-09 11:37:26 +08:00
|
|
|
fit: BoxFit.fill,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
// AppFlowy Editor Demo
|
|
|
|
|
_buildSeparator(context, 'AppFlowy Editor Demo'),
|
|
|
|
|
_buildListTile(context, 'With Example.json', () {
|
2024-09-11 17:51:53 +08:00
|
|
|
final jsonString = UniversalPlatform.isDesktopOrWeb
|
2023-09-20 11:17:39 +08:00
|
|
|
? rootBundle.loadString('assets/example.json')
|
|
|
|
|
: rootBundle.loadString('assets/mobile_example.json');
|
2022-11-09 11:50:08 +08:00
|
|
|
_loadEditor(context, jsonString);
|
2022-11-09 11:37:26 +08:00
|
|
|
}),
|
2023-09-11 15:03:14 +08:00
|
|
|
_buildListTile(context, 'With Large Document (10000+ lines)', () {
|
|
|
|
|
final nodes = List.generate(
|
|
|
|
|
10000,
|
|
|
|
|
(index) =>
|
|
|
|
|
paragraphNode(text: '$index ${generateRandomString(50)}'),
|
|
|
|
|
);
|
|
|
|
|
final editorState = EditorState(
|
|
|
|
|
document: Document(root: pageNode(children: nodes)),
|
|
|
|
|
);
|
|
|
|
|
final jsonString = Future.value(
|
|
|
|
|
jsonEncode(editorState.document.toJson()),
|
|
|
|
|
);
|
|
|
|
|
_loadEditor(context, jsonString);
|
|
|
|
|
}),
|
2023-05-31 16:05:49 +08:00
|
|
|
_buildListTile(context, 'With Example.html', () async {
|
|
|
|
|
final htmlString =
|
|
|
|
|
await rootBundle.loadString('assets/example.html');
|
|
|
|
|
final html = htmlToDocument(htmlString);
|
|
|
|
|
final jsonString = Future<String>.value(
|
|
|
|
|
jsonEncode(
|
|
|
|
|
html.toJson(),
|
|
|
|
|
).toString(),
|
|
|
|
|
);
|
2024-02-28 10:03:29 +07:00
|
|
|
if (context.mounted) {
|
2023-06-23 18:36:33 +08:00
|
|
|
_loadEditor(context, jsonString);
|
|
|
|
|
}
|
2023-05-31 16:05:49 +08:00
|
|
|
}),
|
2022-11-09 11:37:26 +08:00
|
|
|
_buildListTile(context, 'With Empty Document', () {
|
|
|
|
|
final jsonString = Future<String>.value(
|
2023-05-31 11:44:37 +08:00
|
|
|
jsonEncode(
|
|
|
|
|
EditorState.blank(withInitialText: true).document.toJson(),
|
|
|
|
|
).toString(),
|
2022-11-09 11:37:26 +08:00
|
|
|
);
|
2022-11-09 11:50:08 +08:00
|
|
|
_loadEditor(context, jsonString);
|
2022-11-09 11:37:26 +08:00
|
|
|
}),
|
|
|
|
|
|
2023-07-07 16:07:47 +08:00
|
|
|
// Theme Demo
|
2023-09-27 09:18:23 +08:00
|
|
|
_buildSeparator(context, 'Showcases'),
|
2024-09-12 20:46:55 +08:00
|
|
|
_buildListTile(context, 'Drag to reorder', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const DragToReorderEditor(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2024-07-04 09:53:25 +08:00
|
|
|
_buildListTile(context, 'Markdown Editor', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const MarkdownEditor(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2024-04-11 10:48:12 +08:00
|
|
|
_buildListTile(context, 'Auto complete Editor', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const AutoCompleteEditor(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2024-03-19 16:38:14 +07:00
|
|
|
_buildListTile(context, 'Collab Editor', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const CollabEditor(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2024-03-27 17:01:34 +08:00
|
|
|
_buildListTile(context, 'Collab Selection', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const CollabSelectionEditor(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2023-07-07 16:07:47 +08:00
|
|
|
_buildListTile(context, 'Custom Theme', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const CustomizeThemeForEditor(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2023-09-20 11:17:39 +08:00
|
|
|
_buildListTile(context, 'RTL', () {
|
|
|
|
|
final jsonString = rootBundle.loadString(
|
|
|
|
|
'assets/arabic_example.json',
|
|
|
|
|
);
|
|
|
|
|
_loadEditor(
|
|
|
|
|
context,
|
|
|
|
|
jsonString,
|
|
|
|
|
textDirection: TextDirection.rtl,
|
|
|
|
|
);
|
|
|
|
|
}),
|
2023-09-27 09:18:23 +08:00
|
|
|
_buildListTile(context, 'Focus Example', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const FocusExampleForEditor(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2023-10-17 17:38:27 +08:00
|
|
|
_buildListTile(context, 'Editor List', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const EditorList(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2024-03-07 09:47:23 +08:00
|
|
|
_buildListTile(context, 'Fixed Toolbar', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => const FixedToolbarExample(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
2023-07-07 16:07:47 +08:00
|
|
|
|
2024-10-14 09:58:24 +08:00
|
|
|
_buildListTile(context, 'Auto Expand Editor', () {
|
|
|
|
|
Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (context) => AutoExpandEditor(
|
|
|
|
|
editorState: EditorState.blank(),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
|
2022-11-09 11:37:26 +08:00
|
|
|
// Encoder Demo
|
2023-07-03 19:19:32 +08:00
|
|
|
_buildSeparator(context, 'Export To X Demo'),
|
2022-11-09 11:50:08 +08:00
|
|
|
_buildListTile(context, 'Export To JSON', () {
|
2023-07-03 19:19:32 +08:00
|
|
|
_exportFile(_editorState, ExportFileType.documentJson);
|
2022-11-09 14:36:55 +08:00
|
|
|
}),
|
|
|
|
|
_buildListTile(context, 'Export to Markdown', () {
|
|
|
|
|
_exportFile(_editorState, ExportFileType.markdown);
|
2022-11-09 11:50:08 +08:00
|
|
|
}),
|
2022-11-09 11:37:26 +08:00
|
|
|
|
2024-07-04 05:57:43 +02:00
|
|
|
_buildListTile(context, 'Export to PDF', () {
|
|
|
|
|
_exportFile(_editorState, ExportFileType.pdf);
|
|
|
|
|
}),
|
|
|
|
|
|
2022-11-09 11:37:26 +08:00
|
|
|
// Decoder Demo
|
2023-07-03 19:19:32 +08:00
|
|
|
_buildSeparator(context, 'Import From X Demo'),
|
|
|
|
|
_buildListTile(context, 'Import From Document JSON', () {
|
|
|
|
|
_importFile(ExportFileType.documentJson);
|
2022-11-09 15:06:36 +08:00
|
|
|
}),
|
|
|
|
|
_buildListTile(context, 'Import From Markdown', () {
|
|
|
|
|
_importFile(ExportFileType.markdown);
|
|
|
|
|
}),
|
2023-01-05 17:08:43 +08:00
|
|
|
_buildListTile(context, 'Import From Quill Delta', () {
|
|
|
|
|
_importFile(ExportFileType.delta);
|
|
|
|
|
}),
|
2022-11-09 11:37:26 +08:00
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildListTile(
|
|
|
|
|
BuildContext context,
|
|
|
|
|
String text,
|
|
|
|
|
VoidCallback? onTap,
|
|
|
|
|
) {
|
|
|
|
|
return ListTile(
|
|
|
|
|
dense: true,
|
|
|
|
|
contentPadding: const EdgeInsets.only(left: 16),
|
|
|
|
|
title: Text(
|
|
|
|
|
text,
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
color: Colors.blue,
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
onTap: () {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
onTap?.call();
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildSeparator(BuildContext context, String text) {
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: const EdgeInsets.only(left: 16, top: 16, bottom: 4),
|
|
|
|
|
child: Text(
|
|
|
|
|
text,
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
color: Colors.grey,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-07 09:38:38 +08:00
|
|
|
Future<void> _loadEditor(
|
|
|
|
|
BuildContext context,
|
2023-09-20 11:17:39 +08:00
|
|
|
Future<String> jsonString, {
|
|
|
|
|
TextDirection textDirection = TextDirection.ltr,
|
|
|
|
|
}) async {
|
2023-01-07 09:38:38 +08:00
|
|
|
final completer = Completer<void>();
|
2022-11-09 15:36:30 +08:00
|
|
|
_jsonString = jsonString;
|
2022-11-09 11:37:26 +08:00
|
|
|
setState(
|
|
|
|
|
() {
|
2023-07-07 16:07:47 +08:00
|
|
|
_widgetBuilder = (context) => Editor(
|
2022-11-09 15:36:30 +08:00
|
|
|
jsonString: _jsonString,
|
2022-11-09 11:37:26 +08:00
|
|
|
onEditorStateChange: (editorState) {
|
|
|
|
|
_editorState = editorState;
|
|
|
|
|
},
|
2023-09-20 11:17:39 +08:00
|
|
|
textDirection: textDirection,
|
2022-11-09 11:37:26 +08:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
2023-01-07 09:38:38 +08:00
|
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
|
|
|
completer.complete();
|
|
|
|
|
});
|
|
|
|
|
return completer.future;
|
2022-11-09 11:37:26 +08:00
|
|
|
}
|
2022-11-09 11:50:08 +08:00
|
|
|
|
2022-11-09 14:36:55 +08:00
|
|
|
void _exportFile(
|
|
|
|
|
EditorState editorState,
|
|
|
|
|
ExportFileType fileType,
|
|
|
|
|
) async {
|
|
|
|
|
var result = '';
|
|
|
|
|
|
|
|
|
|
switch (fileType) {
|
2023-07-03 19:19:32 +08:00
|
|
|
case ExportFileType.documentJson:
|
2022-11-09 14:36:55 +08:00
|
|
|
result = jsonEncode(editorState.document.toJson());
|
|
|
|
|
break;
|
|
|
|
|
case ExportFileType.markdown:
|
|
|
|
|
result = documentToMarkdown(editorState.document);
|
|
|
|
|
break;
|
2024-07-04 05:57:43 +02:00
|
|
|
case ExportFileType.pdf:
|
|
|
|
|
result = documentToMarkdown(editorState.document);
|
|
|
|
|
break;
|
|
|
|
|
|
2023-01-05 17:08:43 +08:00
|
|
|
case ExportFileType.delta:
|
2022-11-09 14:36:55 +08:00
|
|
|
throw UnimplementedError();
|
|
|
|
|
}
|
2022-11-09 11:50:08 +08:00
|
|
|
|
2023-10-10 00:42:51 -07:00
|
|
|
if (kIsWeb) {
|
|
|
|
|
final blob = html.Blob([result], 'text/plain', 'native');
|
|
|
|
|
html.AnchorElement(
|
|
|
|
|
href: html.Url.createObjectUrlFromBlob(blob).toString(),
|
|
|
|
|
)
|
|
|
|
|
..setAttribute('download', 'document.${fileType.extension}')
|
|
|
|
|
..click();
|
2024-09-11 17:51:53 +08:00
|
|
|
} else if (UniversalPlatform.isMobile) {
|
2023-10-10 00:42:51 -07:00
|
|
|
final appStorageDirectory = await getApplicationDocumentsDirectory();
|
|
|
|
|
|
|
|
|
|
final path = File(
|
|
|
|
|
'${appStorageDirectory.path}/${DateTime.now()}.${fileType.extension}',
|
|
|
|
|
);
|
|
|
|
|
await path.writeAsString(result);
|
|
|
|
|
if (mounted) {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
SnackBar(
|
|
|
|
|
content: Text(
|
|
|
|
|
'This document is saved to the ${appStorageDirectory.path}',
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// for desktop
|
2022-11-09 11:50:08 +08:00
|
|
|
final path = await FilePicker.platform.saveFile(
|
2022-11-09 14:36:55 +08:00
|
|
|
fileName: 'document.${fileType.extension}',
|
2022-11-09 11:50:08 +08:00
|
|
|
);
|
|
|
|
|
if (path != null) {
|
2022-11-09 14:36:55 +08:00
|
|
|
await File(path).writeAsString(result);
|
2024-07-04 05:57:43 +02:00
|
|
|
if (fileType == ExportFileType.pdf) {
|
|
|
|
|
final pdf = await PdfHTMLEncoder(
|
|
|
|
|
fontFallback: [
|
|
|
|
|
await PdfGoogleFonts.notoColorEmoji(),
|
|
|
|
|
await PdfGoogleFonts.notoColorEmojiRegular(),
|
|
|
|
|
],
|
|
|
|
|
).convert(result);
|
|
|
|
|
|
|
|
|
|
await File(path).writeAsBytes(await pdf.save());
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-09 11:50:08 +08:00
|
|
|
if (mounted) {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
SnackBar(
|
2022-11-09 14:36:55 +08:00
|
|
|
content: Text('This document is saved to the $path'),
|
2022-11-09 11:50:08 +08:00
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-09 15:06:36 +08:00
|
|
|
|
|
|
|
|
void _importFile(ExportFileType fileType) async {
|
|
|
|
|
final result = await FilePicker.platform.pickFiles(
|
|
|
|
|
allowMultiple: false,
|
|
|
|
|
allowedExtensions: [fileType.extension],
|
|
|
|
|
type: FileType.custom,
|
|
|
|
|
);
|
2022-11-09 15:59:00 +08:00
|
|
|
var plainText = '';
|
|
|
|
|
if (!kIsWeb) {
|
|
|
|
|
final path = result?.files.single.path;
|
|
|
|
|
if (path == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
plainText = await File(path).readAsString();
|
|
|
|
|
} else {
|
|
|
|
|
final bytes = result?.files.first.bytes;
|
|
|
|
|
if (bytes == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
plainText = const Utf8Decoder().convert(bytes);
|
2022-11-09 15:06:36 +08:00
|
|
|
}
|
2022-11-09 15:59:00 +08:00
|
|
|
|
2022-11-09 15:06:36 +08:00
|
|
|
var jsonString = '';
|
|
|
|
|
switch (fileType) {
|
2023-07-03 19:19:32 +08:00
|
|
|
case ExportFileType.documentJson:
|
2023-03-09 14:38:54 +07:00
|
|
|
jsonString = plainText;
|
2022-11-09 15:06:36 +08:00
|
|
|
break;
|
|
|
|
|
case ExportFileType.markdown:
|
|
|
|
|
jsonString = jsonEncode(markdownToDocument(plainText).toJson());
|
|
|
|
|
break;
|
2023-01-05 17:08:43 +08:00
|
|
|
case ExportFileType.delta:
|
2023-07-03 19:19:32 +08:00
|
|
|
final delta = Delta.fromJson(jsonDecode(plainText));
|
|
|
|
|
final document = quillDeltaEncoder.convert(delta);
|
|
|
|
|
jsonString = jsonEncode(document.toJson());
|
2023-01-05 17:08:43 +08:00
|
|
|
break;
|
2024-07-04 05:57:43 +02:00
|
|
|
case ExportFileType.pdf:
|
2022-11-09 15:06:36 +08:00
|
|
|
throw UnimplementedError();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mounted) {
|
|
|
|
|
_loadEditor(context, Future<String>.value(jsonString));
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-09 11:37:26 +08:00
|
|
|
}
|
2023-09-11 15:03:14 +08:00
|
|
|
|
|
|
|
|
String generateRandomString(int len) {
|
|
|
|
|
var r = Random();
|
|
|
|
|
return String.fromCharCodes(
|
|
|
|
|
List.generate(len, (index) => r.nextInt(33) + 89),
|
|
|
|
|
);
|
|
|
|
|
}
|