| 
				
			 | 
			
			
				@@ -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
			 | 
			
			
				+} 
			 |