From cbacfa31e3a2fe0bc5900e85aff4a2de15782ad9 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Fri, 28 Feb 2020 14:16:23 +0100 Subject: [PATCH] First attempt of creating a NotesCache This is just for optimizing the loading of the Notes in the correct order. I want to avoid the notes appearing and disappearing in a strange order when loading. It gives a bad first impression. This cache isn't integrated, it's only half done. --- lib/core/notes_cache.dart | 88 ++++++++++++++++++++++++++++++++++++++ test/notes_cache_test.dart | 62 +++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 lib/core/notes_cache.dart create mode 100644 test/notes_cache_test.dart diff --git a/lib/core/notes_cache.dart b/lib/core/notes_cache.dart new file mode 100644 index 00000000..349c8a71 --- /dev/null +++ b/lib/core/notes_cache.dart @@ -0,0 +1,88 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:path/path.dart' as p; + +import 'package:gitjournal/core/note.dart'; +import 'package:gitjournal/core/notes_folder.dart'; + +enum NotesCacheSortOrder { + Modified, + Created, +} + +class NotesCache { + final String filePath; + final String notesBasePath; + + NotesCache({@required this.filePath, @required this.notesBasePath}); + + void updateCache(NotesFolder rootFolder) {} + + Future load() async { + var fileList = await loadFromDisk(); + var rootFolder = NotesFolder(null, this.notesBasePath); + + var sep = Platform.pathSeparator; + var notesBasePath = this.notesBasePath; + if (!notesBasePath.endsWith(sep)) { + notesBasePath += sep; + } + + for (var fullFilePath in fileList) { + var filePath = fullFilePath.substring(notesBasePath.length); + var components = filePath.split(sep); + + // + // Create required folders + var parent = rootFolder; + for (var i = 0; i < components.length - 1; i++) { + var c = components.sublist(0, i + 1); + var folderPath = p.join(this.notesBasePath, c.join(sep)); + + var folders = parent.subFolders; + var folderIndex = folders.indexWhere((f) => f.folderPath == folderPath); + if (folderIndex != -1) { + parent = folders[folderIndex]; + continue; + } + + var subFolder = NotesFolder(parent, folderPath); + parent.addFolder(subFolder); + parent = subFolder; + } + + var note = Note(parent, fullFilePath); + parent.add(note); + } + + return rootFolder; + } + + @visibleForTesting + Future> loadFromDisk() async { + String contents = ""; + try { + contents = await File(filePath).readAsString(); + } on FileSystemException catch (ex) { + if (ex.osError.errorCode == 2 /* file not found */) { + return []; + } + rethrow; + } + + return json.decode(contents).cast(); + } + + @visibleForTesting + Future saveToDisk(List files) { + var contents = json.encode(files); + return File(filePath).writeAsString(contents); + } +} + +// +// To Add: buildCache(NotesFolder rootFolder) +// To Add: either noteAdded / noteRemoved +// or monitor the root NotesFolder directly diff --git a/test/notes_cache_test.dart b/test/notes_cache_test.dart new file mode 100644 index 00000000..189ce922 --- /dev/null +++ b/test/notes_cache_test.dart @@ -0,0 +1,62 @@ +import 'dart:io'; + +import 'package:gitjournal/core/notes_cache.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; + +void main() { + group('Notes Cache', () { + Directory tempDir; + String cacheFilePath; + var fileList = [ + '/base/file.md', + '/base/d1/d2/file.md', + '/base/d5/file.md', + '/base/d1/file.md', + ]; + NotesCache cache; + + setUp(() async { + tempDir = await Directory.systemTemp.createTemp('__notes_test__'); + cacheFilePath = p.join(tempDir.path, "cache.raw"); + cache = NotesCache(filePath: cacheFilePath, notesBasePath: '/base'); + }); + + tearDown(() async { + tempDir.deleteSync(recursive: true); + }); + + test('Should load list correctly', () async { + var loadedList = await cache.loadFromDisk(); + expect(loadedList.length, 0); + + await cache.saveToDisk(fileList); + + loadedList = await cache.loadFromDisk(); + expect(loadedList, fileList); + }); + + test('Should create directory structure accurately', () async { + await cache.saveToDisk(fileList); + var rootFolder = await cache.load(); + + expect(rootFolder.subFolders.length, 2); + expect(rootFolder.notes.length, 1); + + // d1 + var folder = rootFolder.subFolders[0]; + expect(folder.subFolders.length, 1); + expect(folder.notes.length, 1); + + // d1/d2 + folder = rootFolder.subFolders[0].subFolders[0]; + expect(folder.subFolders.length, 0); + expect(folder.notes.length, 1); + + // d6 + folder = rootFolder.subFolders[1]; + expect(folder.subFolders.length, 0); + expect(folder.notes.length, 1); + }); + }); +}