Skip to content

Commit ffe7ac7

Browse files
authored
Merge pull request #67 from CodandoTV/feature/clear-all-items
Implement bulk task updates and refactor task management
2 parents f539c5c + 11cdacf commit ffe7ac7

32 files changed

Lines changed: 820 additions & 760 deletions

lib/data/database/task_dao.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,11 @@ class TaskDAO {
123123
return false;
124124
}
125125
}
126+
127+
Future<bool> updateTasks(List<Task> tasks, bool isCompletedNewValue) async {
128+
for (var task in tasks) {
129+
update(task, isCompletedNewValue);
130+
}
131+
return true;
132+
}
126133
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
enum TasksCompleteStatus {
2+
checkAll,
3+
uncheckAll
4+
}

lib/data/todo_repository.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ abstract class TodoRepository {
99

1010
Future<bool> updateTask(Task task, bool isCompletedNewValue);
1111

12+
Future<bool> updateTasks(List<Task> tasks, bool isCompletedNewValue);
13+
1214
Future<bool> addTask(Task task, int? checklistId);
1315

1416
Future<bool> deleteTasks(List<Task> tasks);
@@ -90,4 +92,9 @@ class TodoRepositoryImpl implements TodoRepository {
9092
taskTitle: taskTitle,
9193
);
9294
}
95+
96+
@override
97+
Future<bool> updateTasks(List<Task> tasks, bool isCompletedNewValue) async {
98+
return await _todoDAO.updateTasks(tasks, isCompletedNewValue);
99+
}
93100
}

lib/domain/format_task_list_message_use_case.dart

Lines changed: 0 additions & 21 deletions
This file was deleted.

lib/domain/progress_counter_use_case.dart

Lines changed: 0 additions & 25 deletions
This file was deleted.

lib/domain/should_show_share_button_use_case.dart

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import 'package:injectable/injectable.dart';
22
import 'package:todoapp/data/model/task.dart';
33

4-
abstract class TasksComparatorUseCase {
4+
abstract class TaskListSortHelper {
55
bool areThemEqual({required List<Task> oldList, required List<Task> newList});
6+
List<Task> sortByCompletedStatus(List<Task> tasks);
67
}
78

8-
@Injectable(as: TasksComparatorUseCase)
9-
class TasksComparatorUseCaseImpl extends TasksComparatorUseCase {
9+
@Injectable(as: TaskListSortHelper)
10+
class TaskListSortHelperImpl extends TaskListSortHelper {
1011
@override
1112
bool areThemEqual({
1213
required List<Task> oldList,
@@ -29,4 +30,21 @@ class TasksComparatorUseCaseImpl extends TasksComparatorUseCase {
2930
}
3031
return true;
3132
}
33+
34+
@override
35+
List<Task> sortByCompletedStatus(List<Task> tasks) {
36+
List<Task> tasksToBeSorted = List.from(tasks);
37+
tasksToBeSorted.sort((a, b) => _sort(a, b));
38+
return tasksToBeSorted;
39+
}
40+
41+
int _sort(Task a, Task b) {
42+
if (a.isCompleted == false && b.isCompleted) {
43+
return -1;
44+
} else if (a.isCompleted && b.isCompleted == false) {
45+
return 1;
46+
} else {
47+
return 0;
48+
}
49+
}
3250
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import 'package:injectable/injectable.dart';
2+
import 'package:todoapp/data/model/task.dart';
3+
import 'package:todoapp/data/model/tasks_complete_status.dart';
4+
5+
abstract class TaskListSummaryHelper {
6+
bool shouldShowShareButton({required List<Task> tasks});
7+
double calculateProgress({required List<Task> tasks});
8+
String formatTaskList({required List<Task> tasks});
9+
TasksCompleteStatus? checkStatus({required List<Task> tasks});
10+
}
11+
12+
@Injectable(as: TaskListSummaryHelper)
13+
class TaskListSummaryHelperImpl extends TaskListSummaryHelper {
14+
@override
15+
double calculateProgress({required List<Task> tasks}) {
16+
int completedTasks = 0;
17+
for (var task in tasks) {
18+
if (task.isCompleted) {
19+
completedTasks++;
20+
}
21+
}
22+
23+
if (tasks.isNotEmpty) {
24+
return completedTasks / tasks.length.toDouble();
25+
} else {
26+
return 0.0;
27+
}
28+
}
29+
30+
@override
31+
String formatTaskList({required List<Task> tasks}) {
32+
var checklist = '';
33+
34+
for (var task in tasks) {
35+
if (task.isCompleted == false) {
36+
checklist += '- ${task.title}\n';
37+
}
38+
}
39+
return checklist;
40+
}
41+
42+
@override
43+
bool shouldShowShareButton({required List<Task> tasks}) {
44+
return tasks.any((task) => task.isCompleted == false);
45+
}
46+
47+
@override
48+
TasksCompleteStatus? checkStatus({required List<Task> tasks}) {
49+
if (tasks.isEmpty) {
50+
return null;
51+
} else {
52+
final areAllCompleted =
53+
tasks.where((task) => task.isCompleted).length == tasks.length;
54+
55+
if (areAllCompleted) {
56+
return TasksCompleteStatus.uncheckAll;
57+
} else {
58+
return TasksCompleteStatus.checkAll;
59+
}
60+
}
61+
}
62+
}

lib/domain/tasks_sorter_use_case.dart

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:todoapp/data/model/tasks_complete_status.dart';
3+
import 'package:todoapp/ui/l10n/app_localizations.dart';
4+
5+
class CheckAllActionChipWidget extends StatelessWidget {
6+
final TasksCompleteStatus status;
7+
final VoidCallback onClick;
8+
9+
const CheckAllActionChipWidget({
10+
super.key,
11+
required this.status,
12+
required this.onClick,
13+
});
14+
15+
@override
16+
Widget build(BuildContext context) {
17+
final localizations = AppLocalizations.of(context)!;
18+
19+
String text;
20+
switch (status) {
21+
case TasksCompleteStatus.checkAll:
22+
text = localizations.check_all;
23+
case TasksCompleteStatus.uncheckAll:
24+
text = localizations.uncheck_all;
25+
}
26+
return ActionChip(
27+
label: Text(text),
28+
onPressed: () {
29+
onClick();
30+
},
31+
);
32+
}
33+
}

0 commit comments

Comments
 (0)