|
|
|
|
20
|
|
20
|
|
21
|
For more methods of creating a project see [official documentation](https://flutter.dev/docs/get-started/test-drive).
|
21
|
For more methods of creating a project see [official documentation](https://flutter.dev/docs/get-started/test-drive).
|
22
|
|
22
|
|
23
|
-### 02. Add Zefyr to your new project
|
|
|
|
|
23
|
+### 02. Add Zefyr to your project
|
24
|
|
24
|
|
25
|
Add `zefyr` package as a dependency to `pubspec.yaml` of your new project:
|
25
|
Add `zefyr` package as a dependency to `pubspec.yaml` of your new project:
|
26
|
|
26
|
|
|
|
|
|
34
|
dependencies, including [notus](https://pub.dev/packages/notus) package which
|
34
|
dependencies, including [notus](https://pub.dev/packages/notus) package which
|
35
|
implements Zefyr's document model.
|
35
|
implements Zefyr's document model.
|
36
|
|
36
|
|
37
|
-> Notus package is platform-agnostic and can be used outside of Flutter apps,
|
|
|
38
|
-> that is, on the web or server-side.
|
|
|
|
|
37
|
+> Notus package is platform-agnostic and can be used outside of Flutter apps
|
|
|
38
|
+> (in web or server-side Dart projects).
|
39
|
|
39
|
|
40
|
### 03. Create editor page
|
40
|
### 03. Create editor page
|
41
|
|
41
|
|
|
|
|
|
68
|
super.initState();
|
68
|
super.initState();
|
69
|
// Here we must load the document and pass it to Zefyr controller.
|
69
|
// Here we must load the document and pass it to Zefyr controller.
|
70
|
final document = _loadDocument();
|
70
|
final document = _loadDocument();
|
71
|
- _controller = new ZefyrController(document);
|
|
|
72
|
- _focusNode = new FocusNode();
|
|
|
|
|
71
|
+ _controller = ZefyrController(document);
|
|
|
72
|
+ _focusNode = FocusNode();
|
73
|
}
|
73
|
}
|
74
|
|
74
|
|
75
|
@override
|
75
|
@override
|
|
|
|
|
251
|
Future<NotusDocument> _loadDocument() async {
|
251
|
Future<NotusDocument> _loadDocument() async {
|
252
|
final file = File(Directory.systemTemp.path + "/quick_start.json");
|
252
|
final file = File(Directory.systemTemp.path + "/quick_start.json");
|
253
|
if (await file.exists()) {
|
253
|
if (await file.exists()) {
|
254
|
- final contents = file.readAsStringSync();
|
|
|
|
|
254
|
+ final contents = await file.readAsString();
|
255
|
return NotusDocument.fromJson(jsonDecode(contents));
|
255
|
return NotusDocument.fromJson(jsonDecode(contents));
|
256
|
}
|
256
|
}
|
257
|
final Delta delta = Delta()..insert("Zefyr Quick Start\n");
|
257
|
final Delta delta = Delta()..insert("Zefyr Quick Start\n");
|
|
|
|
|
265
|
However we can no longer initialize `ZefyrController` in `initState` and
|
265
|
However we can no longer initialize `ZefyrController` in `initState` and
|
266
|
therefore can't display the editor until document is loaded.
|
266
|
therefore can't display the editor until document is loaded.
|
267
|
|
267
|
|
268
|
-A common way to fix this is to show loader animation while we are reading our
|
|
|
|
|
268
|
+One way to fix this is to show loader animation while we are reading our
|
269
|
document from file. But first, we still need to update `initState` method:
|
269
|
document from file. But first, we still need to update `initState` method:
|
270
|
|
270
|
|
271
|
```dart
|
271
|
```dart
|
|
|
|
|
276
|
@override
|
276
|
@override
|
277
|
void initState() {
|
277
|
void initState() {
|
278
|
super.initState();
|
278
|
super.initState();
|
279
|
- _focusNode = new FocusNode();
|
|
|
|
|
279
|
+ _focusNode = FocusNode();
|
280
|
_loadDocument().then((document) {
|
280
|
_loadDocument().then((document) {
|
281
|
setState(() {
|
281
|
setState(() {
|
282
|
- _controller = new ZefyrController(document);
|
|
|
|
|
282
|
+ _controller = ZefyrController(document);
|
283
|
});
|
283
|
});
|
284
|
});
|
284
|
});
|
285
|
}
|
285
|
}
|
286
|
}
|
286
|
}
|
287
|
```
|
287
|
```
|
288
|
|
288
|
|
289
|
-We initialize `_controller` only when our document is fully loaded from file
|
|
|
|
|
289
|
+We initialize `_controller` only when our document is fully loaded from the file
|
290
|
system. An important part here is to update `_controller` field inside of
|
290
|
system. An important part here is to update `_controller` field inside of
|
291
|
-`setState` call as required by Flutter's stateful widgets.
|
|
|
|
|
291
|
+`setState` call as required by Flutter's `StatefulWidget`'s contract.
|
292
|
|
292
|
|
293
|
The only thing left is to update `build()` method to show loader animation:
|
293
|
The only thing left is to update `build()` method to show loader animation:
|
294
|
|
294
|
|
|
|
|
|
333
|
|
333
|
|
334
|
<img src="https://github.com/memspace/zefyr/raw/gitbook/assets/quick-start-rec-03.gif" width="600">
|
334
|
<img src="https://github.com/memspace/zefyr/raw/gitbook/assets/quick-start-rec-03.gif" width="600">
|
335
|
|
335
|
|
336
|
-Note that in your test you'll likely not notice loading animation at all. This
|
|
|
337
|
-is because reading a tiny file from disk is too fast. For the above recording
|
|
|
338
|
-we added an artificial delay of 1 second in order to demonstrate loading. We'll
|
|
|
339
|
-leave this task to you as an exercise.
|
|
|
|
|
336
|
+Note that in your tests you'll likely not notice any loading animation at all.
|
|
|
337
|
+This is because reading a tiny file from disk is too fast. For the above
|
|
|
338
|
+recording we added an artificial delay of 1 second in order to demonstrate
|
|
|
339
|
+loading. If you'd like to replicate this, we'll leave implementation of this
|
|
|
340
|
+task to you as an exercise.
|