Checklist: Implement serialization back into Note

This commit is contained in:
Vishesh Handa
2020-02-10 16:03:48 +01:00
parent b98a42543e
commit 9373988054
2 changed files with 113 additions and 30 deletions

View File

@ -1,29 +1,55 @@
import 'package:flutter/material.dart';
import 'package:markdown/markdown.dart' as md; import 'package:markdown/markdown.dart' as md;
import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/core/note.dart';
class ChecklistItem { class ChecklistItem {
bool checked;
String text;
md.Element element; md.Element element;
ChecklistItem({ bool get checked {
@required this.checked, return element.attributes['checked'] != "false";
@required this.text, }
@required this.element,
}); set checked(bool val) {
element.attributes['checked'] = val.toString();
}
String get text {
return element.attributes['text'];
}
set text(String val) {
element.attributes['text'] = val;
}
ChecklistItem.fromMarkdownElement(this.element);
@override @override
String toString() => 'ChecklistItem: $checked $text'; String toString() => 'ChecklistItem: $checked $text';
} }
class Checklist { class Checklist {
Note note; Note _note;
List<ChecklistItem> items; List<ChecklistItem> items;
List<md.Node> nodes;
Checklist(this.note) { Checklist(this._note) {
items = ChecklistBuilder().parse(note.body); var doc = md.Document(
encodeHtml: false,
inlineSyntaxes: [TaskListSyntax()],
extensionSet: md.ExtensionSet.gitHubFlavored,
);
nodes = doc.parseInline(_note.body);
items = ChecklistBuilder().build(nodes);
}
Note get note {
if (nodes.isEmpty) return _note;
var renderer = CustomRenderer();
_note.body = renderer.render(nodes);
return _note;
} }
} }
@ -62,19 +88,12 @@ class ChecklistBuilder implements md.NodeVisitor {
void visitText(md.Text text) {} void visitText(md.Text text) {}
@override @override
void visitElementAfter(md.Element element) { void visitElementAfter(md.Element el) {
final String tag = element.tag; final String tag = el.tag;
if (tag == 'input') { if (tag == 'input') {
var el = element;
if (el is md.Element && el.attributes['type'] == 'checkbox') { if (el is md.Element && el.attributes['type'] == 'checkbox') {
bool val = el.attributes['checked'] != 'false'; list.add(ChecklistItem.fromMarkdownElement(el));
var item = ChecklistItem(
checked: val,
text: el.attributes['text'],
element: el,
);
list.add(item);
} }
} }
} }
@ -87,15 +106,49 @@ class ChecklistBuilder implements md.NodeVisitor {
return list; return list;
} }
}
List<ChecklistItem> parse(String text) { class CustomRenderer implements md.NodeVisitor {
var doc = md.Document( StringBuffer buffer;
encodeHtml: false,
inlineSyntaxes: [TaskListSyntax()],
extensionSet: md.ExtensionSet.gitHubFlavored,
);
var nodes = doc.parseInline(text); @override
return build(nodes); bool visitElementBefore(md.Element element) {
return true;
}
@override
void visitText(md.Text text) {
buffer.write(text.text);
}
@override
void visitElementAfter(md.Element element) {
final String tag = element.tag;
if (tag == 'input') {
var el = element;
if (el is md.Element && el.attributes['type'] == 'checkbox') {
bool val = el.attributes['checked'] != 'false';
if (val) {
if (el.attributes['xUpperCase'] != 'false') {
buffer.write('[x] ');
} else {
buffer.write('[X] ');
}
} else {
buffer.write('[ ] ');
}
buffer.write(el.attributes['text']);
}
}
}
String render(List<md.Node> nodes) {
buffer = StringBuffer();
for (final node in nodes) {
node.accept(this);
}
return buffer.toString();
} }
} }

View File

@ -30,7 +30,7 @@ How are you doing?
[ ] item 1 [ ] item 1
[x] item 2 [x] item 2
[X] item 3 [x] item 3
[ ] item 4 [ ] item 4
Booga Wooga Booga Wooga
@ -55,6 +55,36 @@ Booga Wooga
expect(checklist.items[1].text, "item 2"); expect(checklist.items[1].text, "item 2");
expect(checklist.items[2].text, "item 3"); expect(checklist.items[2].text, "item 3");
expect(checklist.items[3].text, "item 4"); expect(checklist.items[3].text, "item 4");
//
// Serialization
//
checklist.items[0].checked = true;
checklist.items[1].checked = false;
checklist.items[1].text = "Foo";
await checklist.note.save();
var expectedContent = """---
title: Foo
modified: 2017-02-15T22:41:19+01:00
---
# Title 1
How are you doing?
[x] item 1
[ ] Foo
[X] item 3
[ ] item 4
Booga Wooga
""";
var actualContent = File(notePath).readAsStringSync();
expect(actualContent, equals(expectedContent));
}); });
}); });
} }