Compare commits

...

6 Commits

Author SHA1 Message Date
andrei
5e532a132a Hive adapter + testing 2021-12-02 10:27:02 -05:00
andrei
98942b231b refactored card lists into seperate widgets 2021-11-23 19:05:09 -05:00
andrei
647cdc4002 adding new list takes you to the list 2021-11-23 18:39:36 -05:00
andrei
88fb731a07 refactored list items into seperate class 2021-11-23 18:33:41 -05:00
andrei
9d4ac739c2 took care of compiler warnings 2021-11-20 17:51:29 -05:00
andrei
d6dbe5234e refactored lock button 2021-11-04 22:36:27 -04:00
19 changed files with 722 additions and 186 deletions

0
checks/checks.hive Normal file
View File

0
checks/checks.lock Normal file
View File

BIN
checks/test.hive Normal file

Binary file not shown.

0
checks/test.lock Normal file
View File

View File

@@ -1,3 +1,4 @@
import 'package:boxchecker/check_list.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'data_util.dart' as data; import 'data_util.dart' as data;
import 'db_helper.dart'; import 'db_helper.dart';
@@ -7,20 +8,17 @@ class AddForm extends StatefulWidget {
final data.Page type; final data.Page type;
@override @override
State<StatefulWidget> createState() => _AddFormState(type); State<StatefulWidget> createState() => _AddFormState();
} }
class _AddFormState extends State<AddForm> { class _AddFormState extends State<AddForm> {
_AddFormState(this.type);
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
final data.Page type;
int _templatChoice = -1; int _templatChoice = -1;
String _listLabel = ""; String _listLabel = "";
String _listDesc = ""; String _listDesc = "";
List<data.List> templates = []; List<data.List> templates = [];
final FocusNode _TemplateFocusNode = FocusNode(); final FocusNode _templateFocusNode = FocusNode();
void loadTemplates() async { void loadTemplates() async {
var rows = await DBHelper.dbHelper.getAllLists(data.Page.templates); var rows = await DBHelper.dbHelper.getAllLists(data.Page.templates);
@@ -36,7 +34,7 @@ class _AddFormState extends State<AddForm> {
List<DropdownMenuItem<int>> generateDropdown() { List<DropdownMenuItem<int>> generateDropdown() {
loadTemplates(); loadTemplates();
List<DropdownMenuItem<int>> items = [ List<DropdownMenuItem<int>> items = [
DropdownMenuItem<int>(child: Text("None"), value: -1) const DropdownMenuItem<int>(child: Text("None"), value: -1)
]; ];
templates.asMap().forEach((index, value) { templates.asMap().forEach((index, value) {
items.add(DropdownMenuItem<int>( items.add(DropdownMenuItem<int>(
@@ -53,9 +51,9 @@ class _AddFormState extends State<AddForm> {
appBar: AppBar( appBar: AppBar(
title: Text( title: Text(
'Add ' + 'Add ' +
((type == data.Page.lists) ((widget.type == data.Page.lists)
? 'Check List' ? 'Check List'
: (type == data.Page.templates) : (widget.type == data.Page.templates)
? 'Template' ? 'Template'
: ''), : ''),
), ),
@@ -89,7 +87,7 @@ class _AddFormState extends State<AddForm> {
}, },
), ),
DropdownButtonFormField<int>( DropdownButtonFormField<int>(
focusNode: _TemplateFocusNode, focusNode: _templateFocusNode,
value: _templatChoice, value: _templatChoice,
onChanged: (value) => setState(() { onChanged: (value) => setState(() {
_templatChoice = value!; _templatChoice = value!;
@@ -103,20 +101,21 @@ class _AddFormState extends State<AddForm> {
), ),
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
child: Icon(Icons.save_alt), child: const Icon(Icons.save_alt),
onPressed: () async { onPressed: () async {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
int id = await DBHelper.dbHelper.insertList( int id = await DBHelper.dbHelper.insertList(
data.List( data.List(
_listLabel, _listLabel,
isTemplate: type.index == 1, isTemplate: widget.type.index == 1,
description: _listDesc, description: _listDesc,
), ),
); );
if (_templatChoice >= 0 && _templatChoice < templates.length) { if (_templatChoice >= 0 && _templatChoice < templates.length) {
DBHelper.dbHelper.copyList(templates[_templatChoice].id!, id); DBHelper.dbHelper.copyList(templates[_templatChoice].id!, id);
} }
Navigator.pop(context); // TODO replace route with checklist page Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => CheckList(id: id)));
} }
}, },
), ),

View File

@@ -1,9 +1,12 @@
import 'package:boxchecker/list_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'add_form.dart'; import 'add_form.dart';
import 'check_list.dart'; import 'check_list.dart';
import 'db_helper.dart'; import 'db_helper.dart';
import 'data_util.dart' as data; import 'data_util.dart' as data;
typedef FutureCallback = Future<bool?> Function(DismissDirection);
void main() { void main() {
runApp(const BoxChecker()); runApp(const BoxChecker());
} }
@@ -15,14 +18,16 @@ class BoxChecker extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'Flutter Demo', title: 'Flutter Demo',
theme: ThemeData.from(colorScheme: ColorScheme.dark()).copyWith( // starting with dark theme but changing the primary colors manually
theme: ThemeData.from(colorScheme: const ColorScheme.dark()).copyWith(
canvasColor: Colors.blueGrey[900], canvasColor: Colors.blueGrey[900],
cardColor: Colors.grey[800],
scaffoldBackgroundColor: Colors.black12, scaffoldBackgroundColor: Colors.black12,
shadowColor: Colors.black38, shadowColor: Colors.black38,
toggleableActiveColor: Colors.blue, toggleableActiveColor: Colors.blue,
colorScheme: ColorScheme.fromSwatch( colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
cardColor: Colors.grey[800],
backgroundColor: Colors.black12,
), ),
), ),
themeMode: ThemeMode.dark, themeMode: ThemeMode.dark,
@@ -44,7 +49,6 @@ class _MainListPageState extends State<MainListPage> {
List<data.List> lists = []; List<data.List> lists = [];
final double _marginHorizontal = 10; final double _marginHorizontal = 10;
final double _cardSpacing = 4;
Future<void> _loadData(data.Page listType) async { Future<void> _loadData(data.Page listType) async {
lists.clear(); lists.clear();
@@ -56,10 +60,6 @@ class _MainListPageState extends State<MainListPage> {
}); });
} }
Future<void> _removeList(data.List list) async {
DBHelper.dbHelper.deleteList(list);
}
@override @override
void initState() { void initState() {
_loadData(data.Page.lists); _loadData(data.Page.lists);
@@ -67,11 +67,42 @@ class _MainListPageState extends State<MainListPage> {
super.initState(); super.initState();
} }
FutureCallback genCofirmDismiss(index) {
return (direction) async {
if (direction != DismissDirection.startToEnd) {
return false;
}
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Are you sure?'),
content: const Text('You are about to delete this permently'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('Cancel')),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('OK')),
],
);
}).then((value) {
if (value) {
setState(() {
DBHelper.dbHelper.deleteList(lists[index]);
lists.removeAt(index);
});
}
return value;
});
};
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final EdgeInsets cardMargin =
EdgeInsets.symmetric(vertical: _cardSpacing, horizontal: 0);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(widget.title), title: Text(widget.title),
@@ -96,71 +127,9 @@ class _MainListPageState extends State<MainListPage> {
child: ListView.builder( child: ListView.builder(
itemCount: lists.length, itemCount: lists.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Dismissible( return ListCard(
direction: DismissDirection.startToEnd, checkList: lists[index],
key: Key(lists[index].id.toString()), confirmDismiss: genCofirmDismiss(index),
background: Card(
margin: cardMargin,
color: Colors.red,
child: Row(
children: const [
Padding(
padding: EdgeInsets.all(10),
child: Icon(Icons.delete),
),
],
),
),
confirmDismiss: (direction) async {
if (direction != DismissDirection.startToEnd) {
return false;
}
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Are you sure?'),
content: const Text(
'You are about to delete this permently'),
actions: [
TextButton(
onPressed: () =>
Navigator.pop(context, false),
child: const Text('Cancel')),
TextButton(
onPressed: () =>
Navigator.pop(context, true),
child: const Text('OK')),
],
);
}).then((value) {
if (value) {
setState(() {
_removeList(lists[index]);
lists.removeAt(index);
});
}
return value;
});
},
child: Card(
margin: cardMargin,
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CheckList(id: lists[index].id!)));
},
title: Text(lists[index].name),
subtitle: Text((lists[index].description != null)
? lists[index].description!
: ""),
),
),
); );
}))), }))),
bottomNavigationBar: BottomNavigationBar( bottomNavigationBar: BottomNavigationBar(

View File

@@ -1,3 +1,4 @@
import 'package:boxchecker/check_list_item.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'data_util.dart' as data; import 'data_util.dart' as data;
import 'db_helper.dart'; import 'db_helper.dart';
@@ -7,18 +8,16 @@ class CheckList extends StatefulWidget {
final int id; final int id;
@override @override
State<StatefulWidget> createState() => _CheckList(id); State<StatefulWidget> createState() => _CheckList();
} }
class _CheckList extends State<CheckList> { class _CheckList extends State<CheckList> {
_CheckList(this.id); late bool _editable;
final int id;
bool _editable = false;
data.List? listData; data.List? listData;
List<data.Check> list = []; List<data.Check> list = [];
void _loadList() async { void _loadList() async {
var rows = await DBHelper.dbHelper.getList(id); var rows = await DBHelper.dbHelper.getList(widget.id);
list.clear(); list.clear();
setState(() { setState(() {
@@ -29,8 +28,9 @@ class _CheckList extends State<CheckList> {
} }
void _loadListData() async { void _loadListData() async {
var rows = await DBHelper.dbHelper.getListData(id); var rows = await DBHelper.dbHelper.getListData(widget.id);
listData = (rows.isNotEmpty) ? data.List.fromMap(rows[0]) : null; listData = (rows.isNotEmpty) ? data.List.fromMap(rows[0]) : null;
_editable = (listData != null && !listData!.isTemplate!);
} }
void _addItem() async { void _addItem() async {
@@ -42,14 +42,6 @@ class _CheckList extends State<CheckList> {
}); });
} }
void _removeItem(data.Check item) async {
DBHelper.dbHelper.deleteItem(item);
}
void _updateItem(data.Check item) async {
DBHelper.dbHelper.updateItem(item);
}
void _toggleEditable() { void _toggleEditable() {
setState(() { setState(() {
_editable = !_editable; _editable = !_editable;
@@ -63,26 +55,23 @@ class _CheckList extends State<CheckList> {
super.initState(); super.initState();
} }
Widget iconButton() {
return IconButton(
onPressed: () => _toggleEditable(),
icon: Icon(_editable ? Icons.lock_open : Icons.lock),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text((listData != null) ? listData!.name : 'Check List: $id'), title: Text(
actions: (listData != null && listData!.isTemplate! && !_editable) (listData != null) ? listData!.name : 'Check List: ${widget.id}'),
? [ actions:
IconButton( (listData != null && listData!.isTemplate!) ? [iconButton()] : [],
onPressed: () => _toggleEditable(),
icon: const Icon(Icons.lock))
]
: (listData != null && listData!.isTemplate!)
? [
IconButton(
onPressed: () => _toggleEditable(),
icon: const Icon(Icons.lock_open))
]
: [],
), ),
body: RefreshIndicator( body: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
@@ -92,65 +81,25 @@ class _CheckList extends State<CheckList> {
child: ListView.builder( child: ListView.builder(
itemCount: list.length, itemCount: list.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Dismissible( return CheckListItem(
key: Key(list[index].id.toString()),
confirmDismiss: (direction) async { confirmDismiss: (direction) async {
var item = list[index]; if (!_editable) return false;
if (direction == DismissDirection.endToStart) { if (direction == DismissDirection.endToStart) {
setState(() { setState(() {
_removeItem(item); DBHelper.dbHelper.deleteItem(list[index]);
list.removeAt(index); list.removeAt(index);
}); });
return true; return true;
} }
_updateItem(item); DBHelper.dbHelper.updateItem(list[index]);
setState(() { setState(() {
item.value = !item.value; list[index].value = !list[index].value;
}); });
return false; return false;
}, },
background: Container( item: list[index],
color: Colors.blue, locked: !_editable,
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,
),
); );
}, },
), ),
@@ -160,7 +109,8 @@ class _CheckList extends State<CheckList> {
if (listData!.isTemplate! && !_editable) { if (listData!.isTemplate! && !_editable) {
ScaffoldMessenger.of(context) ScaffoldMessenger.of(context)
..clearSnackBars() ..clearSnackBars()
..showSnackBar(SnackBar(content: Text("Template is locked"))); ..showSnackBar(
const SnackBar(content: Text("Template is locked")));
return; return;
} }
_addItem(); _addItem();

95
lib/check_list_item.dart Normal file
View File

@@ -0,0 +1,95 @@
import 'package:boxchecker/check_list.dart';
import 'package:flutter/material.dart';
import 'data_util.dart' as data;
import 'db_helper.dart';
import 'box_checker.dart';
class CheckListItem extends StatefulWidget {
const CheckListItem(
{Key? key,
required this.item,
required this.confirmDismiss,
this.locked = false})
: super(key: key);
final data.Check item;
final FutureCallback confirmDismiss;
final bool locked;
@override
State<StatefulWidget> createState() => _CheckListItem();
}
class _CheckListItem extends State<CheckListItem> {
Widget dismissIconPadding(Widget icon) {
return Padding(
padding: const EdgeInsets.all(10),
child: icon,
);
}
Widget dismissBackground() {
return Container(
color: Colors.blue,
child: Row(children: const [
Padding(
padding: EdgeInsets.all(10),
child: Icon(Icons.check),
),
Spacer(),
]));
}
Widget dismissSecondaryBackground() {
return Container(
color: Colors.red,
child: Row(children: [
const Spacer(),
dismissIconPadding(const Icon(Icons.delete_forever)),
]),
);
}
Widget dismissLockedBackground() {
return Container(
color: Colors.grey[900],
child: Row(
children: [
dismissIconPadding(const Icon(Icons.lock)),
const Spacer(),
dismissIconPadding(const Icon(Icons.lock)),
],
));
}
@override
Widget build(BuildContext context) {
return Dismissible(
key: Key(widget.item.id.toString()),
background:
!widget.locked ? dismissBackground() : dismissLockedBackground(),
secondaryBackground: !widget.locked ? dismissSecondaryBackground() : null,
confirmDismiss: widget.confirmDismiss,
child: CheckboxListTile(
title: TextFormField(
enabled: !widget.locked,
decoration: const InputDecoration(border: InputBorder.none),
initialValue: widget.item.text,
onChanged: (value) {
widget.item.text = value;
DBHelper.dbHelper.updateItem(widget.item);
},
),
controlAffinity: ListTileControlAffinity.leading,
value: widget.item.value,
onChanged: !widget.locked
? ((value) {
DBHelper.dbHelper.updateItem(widget.item);
setState(() {
widget.item.value = value!;
});
})
: null,
),
);
}
}

View File

@@ -1,17 +1,36 @@
import 'dart:core';
import 'dart:core' as core;
import 'package:hive/hive.dart';
part 'data_util.g.dart';
enum Page { lists, templates } enum Page { lists, templates }
@HiveType(typeId: 1)
class List { class List {
List(this.name, {this.id, this.description, this.isTemplate}); List(
this.name, {
this.id,
this.description,
this.isTemplate,
this.checks = const [],
});
@HiveField(0)
int? id; int? id;
@HiveField(1)
String name; String name;
@HiveField(2)
String? description; String? description;
@HiveField(3)
bool? isTemplate; bool? isTemplate;
@HiveField(4)
core.List<Check> checks;
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
var map = Map<String, dynamic>(); var map = <String, dynamic>{};
if (id != null) map["id"] = this.id; if (id != null) map["id"] = id;
map["list_name"] = this.name; map["list_name"] = name;
if (description != null) map["list_desc"] = description; if (description != null) map["list_desc"] = description;
if (isTemplate != null) map["is_template"] = isTemplate! ? 1 : 0; if (isTemplate != null) map["is_template"] = isTemplate! ? 1 : 0;
return map; return map;
@@ -27,20 +46,25 @@ class List {
} }
} }
@HiveType(typeId: 2)
class Check { class Check {
Check(this.text, this.value, {this.id, this.listID}); Check(this.text, this.value, {this.id, this.listID});
@HiveField(5)
int? id; int? id;
@HiveField(6)
String text; String text;
@HiveField(7)
bool value; bool value;
@HiveField(8)
int? listID; int? listID;
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
var map = Map<String, dynamic>(); var map = <String, dynamic>{};
if (id != null) map["id"] = this.id; if (id != null) map["id"] = id;
map["check_text"] = this.text; map["check_text"] = text;
map["status"] = this.value ? 1 : 0; map["status"] = value ? 1 : 0;
if (listID != null) map["list_id"] = this.listID! as int; if (listID != null) map["list_id"] = listID!;
return map; return map;
} }

96
lib/data_util.g.dart Normal file
View File

@@ -0,0 +1,96 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'data_util.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class ListAdapter extends TypeAdapter<List> {
@override
final int typeId = 1;
@override
List read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return List(
fields[1] as String,
id: fields[0] as int?,
description: fields[2] as String?,
isTemplate: fields[3] as bool?,
checks: (fields[4] as core.List).cast<Check>(),
);
}
@override
void write(BinaryWriter writer, List obj) {
writer
..writeByte(5)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.name)
..writeByte(2)
..write(obj.description)
..writeByte(3)
..write(obj.isTemplate)
..writeByte(4)
..write(obj.checks);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ListAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class CheckAdapter extends TypeAdapter<Check> {
@override
final int typeId = 2;
@override
Check read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Check(
fields[6] as String,
fields[7] as bool,
id: fields[5] as int?,
listID: fields[8] as int?,
);
}
@override
void write(BinaryWriter writer, Check obj) {
writer
..writeByte(4)
..writeByte(5)
..write(obj.id)
..writeByte(6)
..write(obj.text)
..writeByte(7)
..write(obj.value)
..writeByte(8)
..write(obj.listID);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CheckAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

53
lib/list_card.dart Normal file
View File

@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'data_util.dart' as data;
import 'check_list.dart';
import 'box_checker.dart';
class ListCard extends StatelessWidget {
const ListCard({
Key? key,
required this.checkList,
required this.confirmDismiss,
}) : super(key: key);
final data.List checkList;
final FutureCallback confirmDismiss;
final double _cardSpacing = 4;
@override
Widget build(BuildContext context) {
final EdgeInsets cardMargin =
EdgeInsets.symmetric(vertical: _cardSpacing, horizontal: 0);
return Dismissible(
direction: DismissDirection.startToEnd,
key: Key(checkList.id.toString()),
background: Card(
margin: cardMargin,
color: Colors.red,
child: Row(
children: const [
Padding(
padding: EdgeInsets.all(10),
child: Icon(Icons.delete),
),
],
),
),
confirmDismiss: confirmDismiss,
child: Card(
margin: cardMargin,
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CheckList(id: checkList.id!)));
},
title: Text(checkList.name),
subtitle: Text(
(checkList.description != null) ? checkList.description! : ""),
),
),
);
}
}

BIN
lists/lists.hive Normal file

Binary file not shown.

0
lists/lists.lock Normal file
View File

View File

@@ -1,6 +1,27 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "31.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
async: async:
dependency: transitive dependency: transitive
description: description:
@@ -15,6 +36,62 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "7.2.2"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "8.1.3"
characters: characters:
dependency: transitive dependency: transitive
description: description:
@@ -29,6 +106,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
cli_util:
dependency: transitive
description:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.5"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@@ -36,6 +127,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@@ -43,6 +141,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -50,6 +162,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.3" version: "1.0.3"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@@ -57,6 +176,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@@ -74,6 +207,76 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
hive:
dependency: "direct main"
description:
name: hive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
hive_generator:
dependency: "direct dev"
description:
name: hive_generator
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.4.0"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@@ -81,6 +284,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@@ -95,6 +305,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.7.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
path: path:
dependency: transitive dependency: transitive
description: description:
@@ -102,11 +326,60 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0" version: "1.8.0"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.0"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
source_helper:
dependency: transitive
description:
name: source_helper
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@@ -142,6 +415,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
@@ -170,6 +450,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.2" version: "0.4.2"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@@ -184,6 +471,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.14.0 <3.0.0"
flutter: ">=1.10.0" flutter: ">=1.10.0"

View File

@@ -30,6 +30,7 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
sqflite: ^2.0.0+4 sqflite: ^2.0.0+4
hive: ^2.0.4
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
@@ -39,7 +40,8 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
hive_generator: ^1.1.1
build_runner:
# The "flutter_lints" package below contains a set of recommended lints to # The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is # encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your # activated in the `analysis_options.yaml` file located at the root of your
@@ -47,6 +49,7 @@ dev_dependencies:
# rules and activating additional ones. # rules and activating additional ones.
flutter_lints: ^1.0.0 flutter_lints: ^1.0.0
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec

45
test/box_test.dart Normal file
View File

@@ -0,0 +1,45 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:boxchecker/data_util.dart' as data;
import 'package:hive/hive.dart';
void main() {
Hive.init("lists");
Hive.registerAdapter(data.ListAdapter());
Hive.registerAdapter(data.CheckAdapter());
test('opening box', () async {
var box = await Hive.openBox<data.List>("lists");
expect(box, isNotNull);
box.close();
});
test('adding lists to box', () async {
var box = await Hive.openBox<data.List>("lists");
await box.clear();
expect(box.length, 0);
final data.List list = data.List("test_list");
box.add(list);
expect(box.length, 1);
var l = box.get(0);
expect(l, isNotNull);
box.close();
});
test('adding chekcs to lists', () async {
var box = await Hive.openBox<data.List>("lists");
var l = box.get(0);
expect(l, isNotNull);
expect(l!.checks, isEmpty);
//print(l.checks);
l.checks.add(data.Check("test Check", false));
expect(l.checks, isNotEmpty);
var l2 = box.get(0);
expect(l2, isNotNull);
expect(l2!.checks, isNotEmpty);
});
}

BIN
test/test.hive Normal file

Binary file not shown.

0
test/test.lock Normal file
View File

View File

@@ -11,20 +11,14 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:boxchecker/box_checker.dart'; import 'package:boxchecker/box_checker.dart';
void main() { void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async { testWidgets('swaping tabs', (WidgetTester tester) async {
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget(const MyApp()); await tester.pumpWidget(const BoxChecker());
// Verify that our counter starts at 0. // Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget); expect(find.text('test list'), findsOneWidget);
expect(find.text('1'), findsNothing); expect(find.text('test template'), findsNothing);
// Tap the '+' icon and trigger a frame. tester.tap(find.byIcon(Icons.list_alt));
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
}); });
} }