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