173 lines
5.2 KiB
Dart
173 lines
5.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'data_util.dart' as data;
|
|
import 'db_helper.dart';
|
|
|
|
class CheckList extends StatefulWidget {
|
|
const CheckList({Key? key, required this.id}) : super(key: key);
|
|
final int id;
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => _CheckList(id);
|
|
}
|
|
|
|
class _CheckList extends State<CheckList> {
|
|
_CheckList(this.id);
|
|
final int id;
|
|
bool _editable = false;
|
|
data.List? listData;
|
|
List<data.Check> list = [];
|
|
|
|
void _loadList() async {
|
|
var rows = await DBHelper.dbHelper.getList(id);
|
|
|
|
list.clear();
|
|
setState(() {
|
|
for (var row in rows) {
|
|
list.add(data.Check.fromMap(row));
|
|
}
|
|
});
|
|
}
|
|
|
|
void _loadListData() async {
|
|
var rows = await DBHelper.dbHelper.getListData(id);
|
|
listData = (rows.isNotEmpty) ? data.List.fromMap(rows[0]) : null;
|
|
}
|
|
|
|
void _addItem() async {
|
|
var item = data.Check("", false, listID: listData!.id!);
|
|
int id = await DBHelper.dbHelper.insertItem(item);
|
|
item.id = id;
|
|
setState(() {
|
|
list.add(item);
|
|
});
|
|
}
|
|
|
|
void _removeItem(data.Check item) async {
|
|
DBHelper.dbHelper.deleteItem(item);
|
|
}
|
|
|
|
void _updateItem(data.Check item) async {
|
|
DBHelper.dbHelper.updateItem(item);
|
|
}
|
|
|
|
void _toggleEditable() {
|
|
setState(() {
|
|
_editable = !_editable;
|
|
});
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
_loadListData();
|
|
_loadList();
|
|
super.initState();
|
|
}
|
|
|
|
Widget iconButton() {
|
|
return IconButton(
|
|
onPressed: () => _toggleEditable(),
|
|
icon: Icon(_editable ? Icons.lock_open : Icons.lock),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return GestureDetector(
|
|
onTap: () => FocusScope.of(context).unfocus(),
|
|
child: Scaffold(
|
|
appBar: AppBar(
|
|
title: Text((listData != null) ? listData!.name : 'Check List: $id'),
|
|
actions:
|
|
(listData != null && listData!.isTemplate!) ? [iconButton()] : [],
|
|
),
|
|
body: RefreshIndicator(
|
|
onRefresh: () async {
|
|
_loadListData();
|
|
_loadList();
|
|
},
|
|
child: ListView.builder(
|
|
itemCount: list.length,
|
|
itemBuilder: (context, index) {
|
|
return Dismissible(
|
|
key: Key(list[index].id.toString()),
|
|
confirmDismiss: (direction) async {
|
|
var item = list[index];
|
|
if (direction == DismissDirection.endToStart) {
|
|
setState(() {
|
|
_removeItem(item);
|
|
list.removeAt(index);
|
|
});
|
|
return true;
|
|
}
|
|
_updateItem(item);
|
|
setState(() {
|
|
item.value = !item.value;
|
|
});
|
|
return false;
|
|
},
|
|
background: Container(
|
|
color: Colors.blue,
|
|
child: Row(children: const [
|
|
Padding(
|
|
padding: EdgeInsets.all(10),
|
|
child: Icon(Icons.check),
|
|
),
|
|
Spacer(),
|
|
]),
|
|
),
|
|
secondaryBackground: Container(
|
|
color: Colors.red,
|
|
child: Row(children: const [
|
|
Spacer(),
|
|
Padding(
|
|
padding: EdgeInsets.all(10),
|
|
child: Icon(Icons.delete_forever)),
|
|
]),
|
|
),
|
|
child: CheckboxListTile(
|
|
title: TextFormField(
|
|
enabled: (listData != null &&
|
|
(!listData!.isTemplate! || _editable)),
|
|
decoration: InputDecoration(border: InputBorder.none),
|
|
initialValue: list[index].text,
|
|
onChanged: (value) {
|
|
list[index].text = value;
|
|
_updateItem(list[index]);
|
|
},
|
|
),
|
|
controlAffinity: ListTileControlAffinity.leading,
|
|
value: list[index].value,
|
|
onChanged: (listData != null &&
|
|
(!listData!.isTemplate! || _editable))
|
|
? ((value) {
|
|
_updateItem(list[index]);
|
|
setState(() {
|
|
list[index].value = value!;
|
|
});
|
|
})
|
|
: null,
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
floatingActionButton: FloatingActionButton(
|
|
onPressed: () {
|
|
if (listData!.isTemplate! && !_editable) {
|
|
ScaffoldMessenger.of(context)
|
|
..clearSnackBars()
|
|
..showSnackBar(SnackBar(content: Text("Template is locked")));
|
|
return;
|
|
}
|
|
_addItem();
|
|
// TODO switch focus to new card
|
|
},
|
|
child: const Icon(Icons.check_box_outlined),
|
|
tooltip: "Add Item",
|
|
),
|
|
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
|
),
|
|
);
|
|
}
|
|
}
|