Android Studio
Let’s test this out by deleting our todos and writing the import code.
Back in menus.dart, find the handleImport method. Add:
final result = await FilePicker.platform.pickFiles(
dialogTitle: 'Open file',
allowedExtensions: ['todo'],
type: FileType.custom
);
if (result == null || result.files.isEmpty) {
return;
}
final path = result.files[0].path;
Similar to saving, we use the open command with a title and set the extension to be ‘.todo’. Now add:
// 1
if (path != null) {
// 2
final file = File(path);
// 3
if (await file.exists()) {
// 4
final repository = ref.read(repositoryProvider);
// 5
file.readAsString().then((String contents) async {
// 6
final jsonArray = jsonDecode(contents) as List<dynamic>;
// 7
await Future.forEach(jsonArray, (value) async {
final map = value as Map<String, dynamic>;
var list = TodoList.fromJson(map);
// 8
list = list.copyWith(id: -1);
// 9
final todoListId = await repository.addTodoList(list);
// 10
await Future.forEach(list.categories, (category) async {
// 11
category = category.copyWith(id: -1, todoList: todoListId);
// 12
final categoryId = await repository.addCategory(category);
await Future.forEach(category.todos, (todo) async {
todo = todo.copyWith(id: -1, category: categoryId);
await repository.addTodo(todo);
});
});
});
});
}
}
First check to see if there is a path, create a file object and make sure it exists. Using Riverpod, you get the repository, then read the file as a string. Next, decode it into a dynamic list. Then for each list, convert it to a real TodoList class. Since the json contains the ids of the items, you want to set the ids to -1 to let the database know to assign a new id. Next add the todo list to the repository. Then for each category set it’s id to -1 and then add it to the repository. Do the same for all of the todos.
Hot reload the app. Now choose Todo -> import. It should recreate the screen the way it was.
You now have a way of either importing and exporting files or saving and opening files.