|
@@ -0,0 +1,86 @@
|
|
1
|
+import 'dart:convert';
|
|
2
|
+
|
|
3
|
+import 'package:flutter/material.dart';
|
|
4
|
+import 'package:quill_delta/quill_delta.dart';
|
|
5
|
+import 'package:zefyr/zefyr.dart';
|
|
6
|
+
|
|
7
|
+import 'full_page.dart';
|
|
8
|
+
|
|
9
|
+class ViewScreen extends StatefulWidget {
|
|
10
|
+ @override
|
|
11
|
+ _ViewScreen createState() => new _ViewScreen();
|
|
12
|
+}
|
|
13
|
+
|
|
14
|
+final doc =
|
|
15
|
+ r'[{"insert":"Zefyr"},{"insert":"\n","attributes":{"heading":1}},{"insert":"Soft and gentle rich text editing for Flutter applications.","attributes":{"i":true}},{"insert":"\n"},{"insert":"","attributes":{"embed":{"type":"image","source":"asset://images/breeze.jpg"}}},{"insert":"\n"},{"insert":"Photo by Hiroyuki Takeda.","attributes":{"i":true}},{"insert":"\nZefyr is currently in "},{"insert":"early preview","attributes":{"b":true}},{"insert":". If you have a feature request or found a bug, please file it at the "},{"insert":"issue tracker","attributes":{"a":"https://github.com/memspace/zefyr/issues"}},{"insert":'
|
|
16
|
+ r'".\nDocumentation"},{"insert":"\n","attributes":{"heading":3}},{"insert":"Quick Start","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/quick_start.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Data Format and Document Model","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/data_and_document.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Style Attributes","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/attr'
|
|
17
|
+ r'ibutes.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Heuristic Rules","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/heuristics.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"FAQ","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/faq.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Clean and modern look"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Zefyr’s rich text editor is built with simplicity and fle'
|
|
18
|
+ r'xibility in mind. It provides clean interface for distraction-free editing. Think Medium.com-like experience.\nMarkdown inspired semantics"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Ever needed to have a heading line inside of a quote block, like this:\nI’m a Markdown heading"},{"insert":"\n","attributes":{"block":"quote","heading":3}},{"insert":"And I’m a regular paragraph"},{"insert":"\n","attributes":{"block":"quote"}},{"insert":"Code blocks"},{"insert":"\n","attributes":{"headin'
|
|
19
|
+ r'g":2}},{"insert":"Of course:\nimport ‘package:flutter/material.dart’;"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"import ‘package:zefyr/zefyr.dart’;"},{"insert":"\n\n","attributes":{"block":"code"}},{"insert":"void main() {"},{"insert":"\n","attributes":{"block":"code"}},{"insert":" runApp(MyZefyrApp());"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"}"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"\n\n\n"}]';
|
|
20
|
+
|
|
21
|
+Delta getDelta() {
|
|
22
|
+ return Delta.fromJson(json.decode(doc));
|
|
23
|
+}
|
|
24
|
+
|
|
25
|
+class _ViewScreen extends State<ViewScreen> {
|
|
26
|
+ final doc = NotusDocument.fromDelta(getDelta());
|
|
27
|
+
|
|
28
|
+ @override
|
|
29
|
+ Widget build(BuildContext context) {
|
|
30
|
+ final theme = new ZefyrThemeData(
|
|
31
|
+ toolbarTheme: ZefyrToolbarTheme.fallback(context).copyWith(
|
|
32
|
+ color: Colors.grey.shade800,
|
|
33
|
+ toggleColor: Colors.grey.shade900,
|
|
34
|
+ iconColor: Colors.white,
|
|
35
|
+ disabledIconColor: Colors.grey.shade500,
|
|
36
|
+ ),
|
|
37
|
+ );
|
|
38
|
+ return Scaffold(
|
|
39
|
+ resizeToAvoidBottomPadding: true,
|
|
40
|
+ appBar: AppBar(
|
|
41
|
+ elevation: 1.0,
|
|
42
|
+ backgroundColor: Colors.grey.shade200,
|
|
43
|
+ brightness: Brightness.light,
|
|
44
|
+ title: ZefyrLogo(),
|
|
45
|
+ ),
|
|
46
|
+ body: ZefyrTheme(
|
|
47
|
+ data: theme,
|
|
48
|
+ child: ListView(
|
|
49
|
+ children: <Widget>[
|
|
50
|
+ SizedBox(height: 16.0),
|
|
51
|
+ ListTile(
|
|
52
|
+ leading: Icon(Icons.info),
|
|
53
|
+ title: Text('ZefyrView inside ListView'),
|
|
54
|
+ subtitle: Text('Allows embedding Notus documents in custom scrollables'),
|
|
55
|
+ trailing: Icon(Icons.keyboard_arrow_down),
|
|
56
|
+ ),
|
|
57
|
+ Padding(
|
|
58
|
+ padding: const EdgeInsets.all(16.0),
|
|
59
|
+ child: ZefyrView(
|
|
60
|
+ document: doc,
|
|
61
|
+ imageDelegate: new CustomImageDelegate(),
|
|
62
|
+ ),
|
|
63
|
+ )
|
|
64
|
+ ],
|
|
65
|
+ ),
|
|
66
|
+ ),
|
|
67
|
+ );
|
|
68
|
+ }
|
|
69
|
+}
|
|
70
|
+
|
|
71
|
+/// Custom image delegate used by this example to load image from application
|
|
72
|
+/// assets.
|
|
73
|
+///
|
|
74
|
+/// Default image delegate only supports [FileImage]s.
|
|
75
|
+class CustomImageDelegate extends ZefyrDefaultImageDelegate {
|
|
76
|
+ @override
|
|
77
|
+ Widget buildImage(BuildContext context, String imageSource) {
|
|
78
|
+ // We use custom "asset" scheme to distinguish asset images from other files.
|
|
79
|
+ if (imageSource.startsWith('asset://')) {
|
|
80
|
+ final asset = new AssetImage(imageSource.replaceFirst('asset://', ''));
|
|
81
|
+ return new Image(image: asset);
|
|
82
|
+ } else {
|
|
83
|
+ return super.buildImage(context, imageSource);
|
|
84
|
+ }
|
|
85
|
+ }
|
|
86
|
+}
|