Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/data/database/task_dao.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,11 @@ class TaskDAO {
return false;
}
}

Future<bool> updateTasks(List<Task> tasks, bool isCompletedNewValue) async {
for (var task in tasks) {
update(task, isCompletedNewValue);
}
return true;
}
}
4 changes: 4 additions & 0 deletions lib/data/model/tasks_complete_status.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum TasksCompleteStatus {
checkAll,
uncheckAll
}
7 changes: 7 additions & 0 deletions lib/data/todo_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ abstract class TodoRepository {

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

Future<bool> updateTasks(List<Task> tasks, bool isCompletedNewValue);

Future<bool> addTask(Task task, int? checklistId);

Future<bool> deleteTasks(List<Task> tasks);
Expand Down Expand Up @@ -90,4 +92,9 @@ class TodoRepositoryImpl implements TodoRepository {
taskTitle: taskTitle,
);
}

@override
Future<bool> updateTasks(List<Task> tasks, bool isCompletedNewValue) async {
return await _todoDAO.updateTasks(tasks, isCompletedNewValue);
}
}
21 changes: 0 additions & 21 deletions lib/domain/format_task_list_message_use_case.dart

This file was deleted.

25 changes: 0 additions & 25 deletions lib/domain/progress_counter_use_case.dart

This file was deleted.

15 changes: 0 additions & 15 deletions lib/domain/should_show_share_button_use_case.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import 'package:injectable/injectable.dart';
import 'package:todoapp/data/model/task.dart';

abstract class TasksComparatorUseCase {
abstract class TaskListSortHelper {
bool areThemEqual({required List<Task> oldList, required List<Task> newList});
List<Task> sortByCompletedStatus(List<Task> tasks);
}

@Injectable(as: TasksComparatorUseCase)
class TasksComparatorUseCaseImpl extends TasksComparatorUseCase {
@Injectable(as: TaskListSortHelper)
class TaskListSortHelperImpl extends TaskListSortHelper {
@override
bool areThemEqual({
required List<Task> oldList,
Expand All @@ -29,4 +30,21 @@ class TasksComparatorUseCaseImpl extends TasksComparatorUseCase {
}
return true;
}

@override
List<Task> sortByCompletedStatus(List<Task> tasks) {
List<Task> tasksToBeSorted = List.from(tasks);
tasksToBeSorted.sort((a, b) => _sort(a, b));
return tasksToBeSorted;
}

int _sort(Task a, Task b) {
if (a.isCompleted == false && b.isCompleted) {
return -1;
} else if (a.isCompleted && b.isCompleted == false) {
return 1;
} else {
return 0;
}
}
}
62 changes: 62 additions & 0 deletions lib/domain/task_list_summary_helper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'package:injectable/injectable.dart';
import 'package:todoapp/data/model/task.dart';
import 'package:todoapp/data/model/tasks_complete_status.dart';

abstract class TaskListSummaryHelper {
bool shouldShowShareButton({required List<Task> tasks});
double calculateProgress({required List<Task> tasks});
String formatTaskList({required List<Task> tasks});
TasksCompleteStatus? checkStatus({required List<Task> tasks});
}

@Injectable(as: TaskListSummaryHelper)
class TaskListSummaryHelperImpl extends TaskListSummaryHelper {
@override
double calculateProgress({required List<Task> tasks}) {
int completedTasks = 0;
for (var task in tasks) {
if (task.isCompleted) {
completedTasks++;
}
}

if (tasks.isNotEmpty) {
return completedTasks / tasks.length.toDouble();
} else {
return 0.0;
}
}

@override
String formatTaskList({required List<Task> tasks}) {
var checklist = '';

for (var task in tasks) {
if (task.isCompleted == false) {
checklist += '- ${task.title}\n';
}
}
return checklist;
}

@override
bool shouldShowShareButton({required List<Task> tasks}) {
return tasks.any((task) => task.isCompleted == false);
}

@override
TasksCompleteStatus? checkStatus({required List<Task> tasks}) {
if (tasks.isEmpty) {
return null;
} else {
final areAllCompleted =
tasks.where((task) => task.isCompleted).length == tasks.length;

if (areAllCompleted) {
return TasksCompleteStatus.uncheckAll;
} else {
return TasksCompleteStatus.checkAll;
}
}
}
}
26 changes: 0 additions & 26 deletions lib/domain/tasks_sorter_use_case.dart

This file was deleted.

33 changes: 33 additions & 0 deletions lib/ui/components/widgets/check_all_action_chip_widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:todoapp/data/model/tasks_complete_status.dart';
import 'package:todoapp/ui/l10n/app_localizations.dart';

class CheckAllActionChipWidget extends StatelessWidget {
final TasksCompleteStatus status;
final VoidCallback onClick;

const CheckAllActionChipWidget({
super.key,
required this.status,
required this.onClick,
});

@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;

String text;
switch (status) {
case TasksCompleteStatus.checkAll:
text = localizations.check_all;
case TasksCompleteStatus.uncheckAll:
text = localizations.uncheck_all;
}
return ActionChip(
label: Text(text),
onPressed: () {
onClick();
},
);
}
}
40 changes: 18 additions & 22 deletions lib/ui/components/widgets/checklist/checklist_full_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,9 @@ class ChecklistsListFullWidgetState extends State<ChecklistsListFullWidget> {
final getIt = GetItStartupHandlerWrapper.getIt;
_tasksViewModel = TasksViewModel(
repository: getIt.get(),
taskListSummaryHelper: getIt.get(),
shareMessageHandler: getIt.get(),
shouldShowShareButtonUseCase: getIt.get(),
formatTaskListMessageUseCase: getIt.get(),
tasksSorterUseCase: getIt.get(),
tasksComparatorUseCase: getIt.get(),
progressCounterUseCase: getIt.get(),
taskListSortHelper: getIt.get(),
);
}

Expand Down Expand Up @@ -103,23 +100,22 @@ class ChecklistsListFullWidgetState extends State<ChecklistsListFullWidget> {
itemCount: widget.checklists.length,
),
),
Expanded(
flex: 6,
child: TasksListWidget(
tasks: tasks == null ? [] : tasks!,
emptyTasksMessage: localizations.empty_tasks,
onCompleteTask: _tasksViewModel.onCompleteTask,
onRemoveTask: (task) => _showConfirmationDialogToRemoveTask(
context,
task,
),
onReorder: _tasksViewModel.reorder,
onTap: (task) => _navigateToTaskScreen(
context,
checklistId: selected?.id,
task: task,
),
)),
TasksListWidget(
flex: 6,
tasks: tasks == null ? [] : tasks!,
emptyTasksMessage: localizations.empty_tasks,
onCompleteTask: _tasksViewModel.onCompleteTask,
onRemoveTask: (task) => _showConfirmationDialogToRemoveTask(
context,
task,
),
onReorder: _tasksViewModel.reorder,
onTap: (task) => _navigateToTaskScreen(
context,
checklistId: selected?.id,
task: task,
),
),
],
);
}
Expand Down
12 changes: 10 additions & 2 deletions lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:todoapp/ui/components/widgets/task/task_cell_widget.dart';

class TasksListWidget extends StatelessWidget {
final List<Task> tasks;
final int? flex;
final String emptyTasksMessage;
final Function(Task) onRemoveTask;
final Function(Task p1, bool p2) onCompleteTask;
Expand All @@ -13,6 +14,7 @@ class TasksListWidget extends StatelessWidget {
const TasksListWidget({
super.key,
required this.tasks,
this.flex,
required this.emptyTasksMessage,
required this.onRemoveTask,
required this.onCompleteTask,
Expand All @@ -26,16 +28,17 @@ class TasksListWidget extends StatelessWidget {
}

Widget _buildTaskList(BuildContext context) {
Widget child;
if (tasks.isEmpty) {
return Center(
child = Center(
child: Text(
emptyTasksMessage,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyLarge,
),
);
} else {
return ReorderableListView.builder(
child = ReorderableListView.builder(
onReorder: onReorder,
padding: const EdgeInsets.only(
top: 12,
Expand All @@ -47,6 +50,11 @@ class TasksListWidget extends StatelessWidget {
itemCount: tasks.length,
);
}

return Expanded(
flex: flex ?? 1,
child: child,
);
}

TaskCellWidget _buildTaskCellWidget(Task task) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:todoapp/data/model/task.dart';
import 'package:todoapp/data/model/tasks_complete_status.dart';

part 'tasks_screen_state.freezed.dart';

Expand All @@ -14,10 +15,14 @@ class TasksScreenState with _$TasksScreenState {
@override
final bool showShareIcon;

@override
final TasksCompleteStatus? tasksCompleteStatus;

const TasksScreenState({
required this.tasks,
required this.isLoading,
required this.progress,
required this.showShareIcon,
this.tasksCompleteStatus,
});
}
Loading