forked from brianegan/flutter_architecture_samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtodo_list_model.dart
119 lines (95 loc) · 3.24 KB
/
todo_list_model.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2018 The Flutter Architecture Sample Authors. All rights reserved.
// Use of this source code is governed by the MIT license that can be found
// in the LICENSE file.
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:scoped_model_sample/models.dart';
import 'package:todos_repository_core/todos_repository_core.dart';
class TodoListModel extends Model {
final TodosRepository repository;
VisibilityFilter _activeFilter;
VisibilityFilter get activeFilter => _activeFilter;
set activeFilter(VisibilityFilter filter) {
_activeFilter = filter;
notifyListeners();
}
List<Todo> get todos => _todos.toList();
List<Todo> _todos = [];
bool _isLoading = false;
bool get isLoading => _isLoading;
TodoListModel({@required this.repository, VisibilityFilter activeFilter})
: this._activeFilter = activeFilter ?? VisibilityFilter.all;
/// Wraps [ScopedModel.of] for this [Model]. See [ScopedModel.of] for more
static TodoListModel of(BuildContext context) =>
ScopedModel.of<TodoListModel>(context);
@override
void addListener(VoidCallback listener) {
super.addListener(listener);
// update data for every subscriber, especially for the first one
loadTodos();
}
/// Loads remote data
///
/// Call this initially and when the user manually refreshes
Future loadTodos() {
_isLoading = true;
notifyListeners();
return repository.loadTodos().then((loadedTodos) {
_todos = loadedTodos.map(Todo.fromEntity).toList();
_isLoading = false;
notifyListeners();
}).catchError((err) {
_isLoading = false;
_todos = [];
notifyListeners();
});
}
List<Todo> get filteredTodos => _todos.where((todo) {
if (activeFilter == VisibilityFilter.all) {
return true;
} else if (activeFilter == VisibilityFilter.active) {
return !todo.complete;
} else if (activeFilter == VisibilityFilter.completed) {
return todo.complete;
}
}).toList();
void clearCompleted() {
_todos.removeWhere((todo) => todo.complete);
notifyListeners();
}
void toggleAll() {
var allComplete = todos.every((todo) => todo.complete);
_todos = _todos.map((todo) => todo.copy(complete: !allComplete)).toList();
notifyListeners();
_uploadItems();
}
/// updates a [Todo] by replacing the item with the same id by the parameter [todo]
void updateTodo(Todo todo) {
assert(todo != null);
assert(todo.id != null);
var oldTodo = _todos.firstWhere((it) => it.id == todo.id);
var replaceIndex = _todos.indexOf(oldTodo);
_todos.replaceRange(replaceIndex, replaceIndex + 1, [todo]);
notifyListeners();
_uploadItems();
}
void removeTodo(Todo todo) {
_todos.removeWhere((it) => it.id == todo.id);
notifyListeners();
_uploadItems();
}
void addTodo(Todo todo) {
_todos.add(todo);
notifyListeners();
_uploadItems();
}
void _uploadItems() {
repository.saveTodos(_todos.map((it) => it.toEntity()).toList());
}
Todo todoById(String id) {
return _todos.firstWhere((it) => it.id == id, orElse: () => null);
}
}
enum VisibilityFilter { all, active, completed }