mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 01:45:55 +08:00
Note: Replace 'id' with 'fileName'
It all just makes far more since when each Note has a fileName. Though we don't save the fileName in the YAML header. It seems quite redundant to do that. Another advantage of this is that if we can read any file ending with a '.md' in a git repo. It doesn't need to be named exactly how we want it, and we will still save the details correctly.
This commit is contained in:
@ -5,23 +5,23 @@ typedef NoteRemover(Note note);
|
||||
typedef NoteUpdator(Note note);
|
||||
|
||||
class Note implements Comparable {
|
||||
String id;
|
||||
String fileName;
|
||||
DateTime created;
|
||||
String body;
|
||||
|
||||
Map<String, dynamic> extraProperties = new Map<String, dynamic>();
|
||||
|
||||
Note({this.created, this.body, this.id, this.extraProperties}) {
|
||||
Note({this.created, this.body, this.fileName, this.extraProperties}) {
|
||||
if (extraProperties == null) {
|
||||
extraProperties = new Map<String, dynamic>();
|
||||
}
|
||||
}
|
||||
|
||||
factory Note.fromJson(Map<String, dynamic> json) {
|
||||
String id;
|
||||
if (json.containsKey("id")) {
|
||||
id = json["id"].toString();
|
||||
json.remove("id");
|
||||
String fileName = "";
|
||||
if (json.containsKey("fileName")) {
|
||||
fileName = json["fileName"].toString();
|
||||
json.remove("fileName");
|
||||
}
|
||||
|
||||
DateTime created;
|
||||
@ -50,10 +50,6 @@ class Note implements Comparable {
|
||||
json.remove("created");
|
||||
}
|
||||
|
||||
if (id == null && created != null) {
|
||||
id = toIso8601WithTimezone(created);
|
||||
}
|
||||
|
||||
String body = "";
|
||||
if (json.containsKey("body")) {
|
||||
body = json['body'];
|
||||
@ -61,7 +57,7 @@ class Note implements Comparable {
|
||||
}
|
||||
|
||||
return new Note(
|
||||
id: id,
|
||||
fileName: fileName,
|
||||
created: created,
|
||||
body: body,
|
||||
extraProperties: json,
|
||||
@ -72,21 +68,24 @@ class Note implements Comparable {
|
||||
var json = Map<String, dynamic>.from(extraProperties);
|
||||
json['created'] = toIso8601WithTimezone(created);
|
||||
json['body'] = body;
|
||||
json['id'] = id;
|
||||
json['fileName'] = fileName;
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
id.hashCode ^ created.hashCode ^ body.hashCode ^ extraProperties.hashCode;
|
||||
fileName.hashCode ^
|
||||
created.hashCode ^
|
||||
body.hashCode ^
|
||||
extraProperties.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is Note &&
|
||||
runtimeType == other.runtimeType &&
|
||||
id == other.id &&
|
||||
fileName == other.fileName &&
|
||||
body == other.body &&
|
||||
created == other.created &&
|
||||
_equalMaps(extraProperties, other.extraProperties);
|
||||
@ -98,7 +97,7 @@ class Note implements Comparable {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Note{id: $id, body: $body, created: $created, extraProperties: $extraProperties}';
|
||||
return 'Note{fileName: $fileName, body: $body, created: $created, extraProperties: $extraProperties}';
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -49,7 +49,6 @@ class StateContainerState extends State<StateContainer> {
|
||||
getDirectory: getNotesDir,
|
||||
dirName: "journal",
|
||||
gitCloneUrl: "root@bcn.vhanda.in:git/test",
|
||||
fileNameGenerator: (Note n) => toIso8601WithTimezone(n.created) + '.md',
|
||||
);
|
||||
|
||||
StateContainerState(bool onBoardingCompleted) {
|
||||
@ -140,9 +139,10 @@ class StateContainerState extends State<StateContainer> {
|
||||
}
|
||||
|
||||
void insertNote(int index, Note note) {
|
||||
print("State Container insertNote");
|
||||
setState(() {
|
||||
if (note.id == null || note.id.isEmpty) {
|
||||
note.id = toIso8601WithTimezone(note.created);
|
||||
if (note.fileName == null || note.fileName.isEmpty) {
|
||||
note.fileName = toIso8601WithTimezone(note.created) + '.md';
|
||||
}
|
||||
appState.notes.insert(index, note);
|
||||
noteRepo.addNote(note).then((NoteRepoResult _) {
|
||||
@ -152,6 +152,7 @@ class StateContainerState extends State<StateContainer> {
|
||||
}
|
||||
|
||||
void updateNote(Note note) {
|
||||
print("State Container updateNote");
|
||||
setState(() {
|
||||
noteRepo.updateNote(note).then((NoteRepoResult _) {
|
||||
_syncNotes();
|
||||
|
@ -10,15 +10,14 @@ import 'package:path/path.dart' as p;
|
||||
typedef String NoteFileNameGenerator(Note note);
|
||||
|
||||
/// Each Note is saved in a different file
|
||||
/// Each note must have a fileName which ends in a .md
|
||||
class FileStorage implements NoteRepository {
|
||||
final Future<Directory> Function() getDirectory;
|
||||
final NoteSerializer noteSerializer;
|
||||
final NoteFileNameGenerator fileNameGenerator;
|
||||
|
||||
const FileStorage({
|
||||
@required this.getDirectory,
|
||||
@required this.noteSerializer,
|
||||
@required this.fileNameGenerator,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -32,14 +31,9 @@ class FileStorage implements NoteRepository {
|
||||
if (note == null) {
|
||||
continue;
|
||||
}
|
||||
if (!fileEntity.path.endsWith('.md') &&
|
||||
!fileEntity.path.endsWith('.MD')) {
|
||||
if (!note.fileName.toLowerCase().endsWith('.md')) {
|
||||
continue;
|
||||
}
|
||||
if (note.id == null) {
|
||||
String filename = p.basename(fileEntity.path);
|
||||
note.id = filename;
|
||||
}
|
||||
notes.add(note);
|
||||
}
|
||||
|
||||
@ -54,13 +48,16 @@ class FileStorage implements NoteRepository {
|
||||
}
|
||||
var file = entity as File;
|
||||
final string = await file.readAsString();
|
||||
return noteSerializer.decode(string);
|
||||
|
||||
var note = noteSerializer.decode(string);
|
||||
note.fileName = p.basename(entity.path);
|
||||
return note;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<NoteRepoResult> addNote(Note note) async {
|
||||
final dir = await getDirectory();
|
||||
var filePath = p.join(dir.path, fileNameGenerator(note));
|
||||
var filePath = p.join(dir.path, note.fileName);
|
||||
|
||||
var file = new File(filePath);
|
||||
if (file == null) {
|
||||
@ -75,7 +72,7 @@ class FileStorage implements NoteRepository {
|
||||
@override
|
||||
Future<NoteRepoResult> removeNote(Note note) async {
|
||||
final dir = await getDirectory();
|
||||
var filePath = p.join(dir.path, fileNameGenerator(note));
|
||||
var filePath = p.join(dir.path, note.fileName);
|
||||
|
||||
var file = new File(filePath);
|
||||
await file.delete();
|
||||
@ -95,11 +92,9 @@ class FileStorage implements NoteRepository {
|
||||
|
||||
Future<Directory> saveNotes(List<Note> notes) async {
|
||||
final dir = await getDirectory();
|
||||
// FIXME: Why do we need to delete everything?
|
||||
// await dir.delete(recursive: true);
|
||||
|
||||
for (var note in notes) {
|
||||
var filePath = p.join(dir.path, fileNameGenerator(note));
|
||||
var filePath = p.join(dir.path, note.fileName);
|
||||
|
||||
var file = new File(filePath);
|
||||
var contents = noteSerializer.encode(note);
|
||||
|
@ -24,14 +24,10 @@ class GitNoteRepository implements NoteRepository {
|
||||
@required this.gitCloneUrl,
|
||||
@required this.dirName,
|
||||
@required this.getDirectory,
|
||||
@required fileNameGenerator,
|
||||
}) : _fileStorage = FileStorage(
|
||||
noteSerializer: new MarkdownYAMLSerializer(),
|
||||
fileNameGenerator: fileNameGenerator,
|
||||
getDirectory: getDirectory,
|
||||
) {
|
||||
// FIXME: This isn't correct. The gitUrl might not be cloned at this point!
|
||||
}
|
||||
) {}
|
||||
|
||||
@override
|
||||
Future<NoteRepoResult> addNote(Note note) async {
|
||||
@ -39,7 +35,6 @@ class GitNoteRepository implements NoteRepository {
|
||||
}
|
||||
|
||||
Future<NoteRepoResult> _addNote(Note note, String commitMessage) async {
|
||||
print("Calling gitStorage addNote");
|
||||
var result = await _fileStorage.addNote(note);
|
||||
if (result.error) {
|
||||
return result;
|
||||
|
@ -48,13 +48,7 @@ class MarkdownYAMLSerializer implements NoteSerializer {
|
||||
|
||||
var metadata = note.toJson();
|
||||
metadata.remove('body');
|
||||
|
||||
// Do not save the 'id' if it is just the 'created' file like default
|
||||
if (metadata.containsKey('id') && metadata.containsKey('created')) {
|
||||
if (metadata['id'] == metadata['created']) {
|
||||
metadata.remove('id');
|
||||
}
|
||||
}
|
||||
metadata.remove('fileName');
|
||||
|
||||
str += toYAML(metadata);
|
||||
str += serparator;
|
||||
|
@ -29,7 +29,7 @@ class JournalList extends StatelessWidget {
|
||||
|
||||
var note = notes[i];
|
||||
return new Dismissible(
|
||||
key: new Key(note.id),
|
||||
key: new Key(note.fileName),
|
||||
child: _buildRow(context, note, i),
|
||||
background: new Container(color: Theme.of(context).accentColor),
|
||||
onDismissed: (direction) {
|
||||
|
@ -15,15 +15,14 @@ DateTime nowWithoutMicro() {
|
||||
main() {
|
||||
group('FileStorage', () {
|
||||
var notes = [
|
||||
Note(id: "1", body: "test", created: nowWithoutMicro()),
|
||||
Note(id: "2", body: "test2", created: nowWithoutMicro()),
|
||||
Note(fileName: "1.md", body: "test", created: nowWithoutMicro()),
|
||||
Note(fileName: "2.md", body: "test2", created: nowWithoutMicro()),
|
||||
];
|
||||
|
||||
final directory = Directory.systemTemp.createTemp('__storage_test__');
|
||||
final storage = FileStorage(
|
||||
getDirectory: () => directory,
|
||||
noteSerializer: new JsonNoteSerializer(),
|
||||
fileNameGenerator: (Note note) => note.id + '.md',
|
||||
);
|
||||
|
||||
tearDownAll(() async {
|
||||
|
@ -10,8 +10,8 @@ DateTime nowWithoutMicro() {
|
||||
|
||||
main() {
|
||||
group('Serializers', () {
|
||||
var note =
|
||||
Note(id: "2", body: "This is the body", created: nowWithoutMicro());
|
||||
var note = Note(
|
||||
fileName: "2", body: "This is the body", created: nowWithoutMicro());
|
||||
|
||||
test('JSON Serializer', () {
|
||||
var serializer = new JsonNoteSerializer();
|
||||
@ -26,6 +26,9 @@ main() {
|
||||
var str = serializer.encode(note);
|
||||
var note2 = serializer.decode(str);
|
||||
|
||||
// The YAML seriazlier loses the fileName by design
|
||||
note2.fileName = note.fileName;
|
||||
|
||||
expect(note2, note);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user