visibility toggle for undone todos

This commit is contained in:
SomnusVeritas
2023-11-08 13:26:06 +01:00
parent c9deb726e0
commit 401ee053a4
4 changed files with 121 additions and 32 deletions

View File

@@ -3,14 +3,27 @@ import 'package:flutter/material.dart';
import '../widgets/todo_list.dart';
import 'todo_create_page.dart';
class DashboardPage extends StatelessWidget {
class DashboardPage extends StatefulWidget {
const DashboardPage({super.key});
static const routeName = '/';
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
bool _showDoneTodos = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
appBar: AppBar(
actions: [
IconButton(
onPressed: () => setState(() => _showDoneTodos = !_showDoneTodos),
icon: const Icon(Icons.visibility),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () =>
Navigator.of(context).pushNamed(CreateTodoPage.routeName),
@@ -19,7 +32,7 @@ class DashboardPage extends StatelessWidget {
body: Center(
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.9,
child: const TodoList(),
child: TodoList(showDoneTodos: _showDoneTodos),
),
),
);

View File

@@ -13,12 +13,15 @@ class DbHelper {
schemas: [TodoSchema],
directory: dir.path,
);
_isar.write((isar) => isar.todos.clear());
// _isar.write((isar) => isar.todos.clear());
}
static List<Todo> fetchTodos() =>
static List<Todo> fetchUndoneTodos() =>
_isar.todos.where().doneEqualTo(false).sortByCreatedAtDesc().findAll();
static List<Todo> fetchAllTodos() =>
_isar.todos.where().sortByDone().thenByCreatedAt().findAll();
static void addOrUpdateTodo(Todo todo) =>
_isar.write((isar) => isar.todos.put(todo));

View File

@@ -2,57 +2,41 @@ import 'package:flutter/material.dart';
import '../models/todo.dart';
import '../services/dbhelper.dart';
import 'todo_listtile.dart';
class TodoList extends StatefulWidget {
const TodoList({super.key});
const TodoList({super.key, required this.showDoneTodos});
final bool showDoneTodos;
@override
State<TodoList> createState() => _TodoListState();
}
class _TodoListState extends State<TodoList> {
List<Todo> _todos = DbHelper.fetchTodos();
List<Todo> _todos = [];
@override
void initState() {
super.initState();
DbHelper.todosChangedStream.listen((event) {
setState(() {
_todos = DbHelper.fetchTodos();
// _todos = _updateTodos();
});
});
}
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: const EdgeInsets.only(bottom: 60),
itemBuilder: _listBuilder,
itemCount: _todos.length,
);
}
Widget _listBuilder(BuildContext context, int index) {
final todo = _todos.elementAt(index);
return ListTile(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
tileColor: Theme.of(context).colorScheme.primaryContainer,
title: Text(todo.title),
trailing: IconButton(
onPressed: () {
todo.done = true;
DbHelper.addOrUpdateTodo(todo);
_showSnackbar(todo);
},
icon: Icon(
Icons.check_box,
color: Theme.of(context).colorScheme.primary,
),
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: TodoListTile(
todo: todo,
onPressed: () => _onTodoPressed(todo),
),
);
}
void _showSnackbar(Todo todo) {
void _showDoneConfirmationSnackbar(Todo todo) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Todo done'),
@@ -65,4 +49,46 @@ class _TodoListState extends State<TodoList> {
),
);
}
void _showDeleteConfirmationSnackbar(Todo todo) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Todo deleted'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {
DbHelper.addOrUpdateTodo(todo);
}),
),
);
}
void _onTodoPressed(Todo todo) {
if (todo.done) {
DbHelper.deleteTodo(todo);
_showDeleteConfirmationSnackbar(todo);
} else {
todo.done = true;
DbHelper.addOrUpdateTodo(todo);
_showDoneConfirmationSnackbar(todo);
}
}
@override
Widget build(BuildContext context) {
_todos = _updateTodos();
return ListView.builder(
padding: const EdgeInsets.only(bottom: 60),
itemBuilder: _listBuilder,
itemCount: _todos.length,
);
}
List<Todo> _updateTodos() {
if (widget.showDoneTodos) {
return DbHelper.fetchAllTodos();
} else {
return DbHelper.fetchUndoneTodos();
}
}
}

View File

@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import '../models/todo.dart';
class TodoListTile extends StatelessWidget {
const TodoListTile({super.key, required this.todo, required this.onPressed});
final Todo todo;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
if (!todo.done) {
return undoneTodo(context);
}
return doneTodo(context);
}
Widget undoneTodo(BuildContext context) {
return ListTile(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
tileColor: Theme.of(context).colorScheme.primaryContainer,
title: Text(todo.title),
trailing: IconButton(
onPressed: onPressed,
icon: Icon(
Icons.check_box,
color: Theme.of(context).colorScheme.primary,
),
),
);
}
Widget doneTodo(BuildContext context) {
return ListTile(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
tileColor: Theme.of(context).colorScheme.surfaceVariant,
title: Text(todo.title),
trailing: IconButton(
onPressed: onPressed,
icon: Icon(
Icons.delete,
color: Theme.of(context).colorScheme.error,
),
),
);
}
}