visibility toggle for undone todos
This commit is contained in:
@@ -3,14 +3,27 @@ import 'package:flutter/material.dart';
|
|||||||
import '../widgets/todo_list.dart';
|
import '../widgets/todo_list.dart';
|
||||||
import 'todo_create_page.dart';
|
import 'todo_create_page.dart';
|
||||||
|
|
||||||
class DashboardPage extends StatelessWidget {
|
class DashboardPage extends StatefulWidget {
|
||||||
const DashboardPage({super.key});
|
const DashboardPage({super.key});
|
||||||
static const routeName = '/';
|
static const routeName = '/';
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DashboardPage> createState() => _DashboardPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DashboardPageState extends State<DashboardPage> {
|
||||||
|
bool _showDoneTodos = false;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(),
|
appBar: AppBar(
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => setState(() => _showDoneTodos = !_showDoneTodos),
|
||||||
|
icon: const Icon(Icons.visibility),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
Navigator.of(context).pushNamed(CreateTodoPage.routeName),
|
Navigator.of(context).pushNamed(CreateTodoPage.routeName),
|
||||||
@@ -19,7 +32,7 @@ class DashboardPage extends StatelessWidget {
|
|||||||
body: Center(
|
body: Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: MediaQuery.of(context).size.width * 0.9,
|
width: MediaQuery.of(context).size.width * 0.9,
|
||||||
child: const TodoList(),
|
child: TodoList(showDoneTodos: _showDoneTodos),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ class DbHelper {
|
|||||||
schemas: [TodoSchema],
|
schemas: [TodoSchema],
|
||||||
directory: dir.path,
|
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();
|
_isar.todos.where().doneEqualTo(false).sortByCreatedAtDesc().findAll();
|
||||||
|
|
||||||
|
static List<Todo> fetchAllTodos() =>
|
||||||
|
_isar.todos.where().sortByDone().thenByCreatedAt().findAll();
|
||||||
|
|
||||||
static void addOrUpdateTodo(Todo todo) =>
|
static void addOrUpdateTodo(Todo todo) =>
|
||||||
_isar.write((isar) => isar.todos.put(todo));
|
_isar.write((isar) => isar.todos.put(todo));
|
||||||
|
|
||||||
|
|||||||
@@ -2,57 +2,41 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import '../models/todo.dart';
|
import '../models/todo.dart';
|
||||||
import '../services/dbhelper.dart';
|
import '../services/dbhelper.dart';
|
||||||
|
import 'todo_listtile.dart';
|
||||||
|
|
||||||
class TodoList extends StatefulWidget {
|
class TodoList extends StatefulWidget {
|
||||||
const TodoList({super.key});
|
const TodoList({super.key, required this.showDoneTodos});
|
||||||
|
final bool showDoneTodos;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<TodoList> createState() => _TodoListState();
|
State<TodoList> createState() => _TodoListState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TodoListState extends State<TodoList> {
|
class _TodoListState extends State<TodoList> {
|
||||||
List<Todo> _todos = DbHelper.fetchTodos();
|
List<Todo> _todos = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
DbHelper.todosChangedStream.listen((event) {
|
DbHelper.todosChangedStream.listen((event) {
|
||||||
setState(() {
|
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) {
|
Widget _listBuilder(BuildContext context, int index) {
|
||||||
final todo = _todos.elementAt(index);
|
final todo = _todos.elementAt(index);
|
||||||
return ListTile(
|
return Padding(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
tileColor: Theme.of(context).colorScheme.primaryContainer,
|
child: TodoListTile(
|
||||||
title: Text(todo.title),
|
todo: todo,
|
||||||
trailing: IconButton(
|
onPressed: () => _onTodoPressed(todo),
|
||||||
onPressed: () {
|
|
||||||
todo.done = true;
|
|
||||||
DbHelper.addOrUpdateTodo(todo);
|
|
||||||
_showSnackbar(todo);
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
Icons.check_box,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showSnackbar(Todo todo) {
|
void _showDoneConfirmationSnackbar(Todo todo) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: const Text('Todo done'),
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
lib/widgets/todo_listtile.dart
Normal file
47
lib/widgets/todo_listtile.dart
Normal 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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user