detailview realtime updates
This commit is contained in:
@@ -115,7 +115,7 @@ class _DashboardPageState extends State<DashboardPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onClChanged(List<Map<String, dynamic>> res) {
|
void _onClChanged(List<Map<String, dynamic>> res) {
|
||||||
checklists = DbHelper.resToList(res);
|
checklists = DbHelper.resToChecklistList(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _streamBuilder(
|
Widget _streamBuilder(
|
||||||
@@ -123,7 +123,7 @@ class _DashboardPageState extends State<DashboardPage> {
|
|||||||
AsyncSnapshot<List<Map<String, dynamic>>> snapshot,
|
AsyncSnapshot<List<Map<String, dynamic>>> snapshot,
|
||||||
List<Checklist> checklists) {
|
List<Checklist> checklists) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
checklists = DbHelper.resToList(snapshot.data!);
|
checklists = DbHelper.resToChecklistList(snapshot.data!);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
Checklist? _checklist;
|
Checklist? _checklist;
|
||||||
late Future<List<Object>> _checklistFutures;
|
late Future<List<Object>> _checklistFutures;
|
||||||
late final ChecklistProvider _checklistProvider;
|
late final ChecklistProvider _checklistProvider;
|
||||||
|
TextEditingController titleController = TextEditingController();
|
||||||
List<Item> _items = [];
|
List<Item> _items = [];
|
||||||
int? _selectedItemId;
|
int? _selectedItemId;
|
||||||
bool _titleEditMode = false;
|
bool _titleEditMode = false;
|
||||||
@@ -52,23 +53,11 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
_checklist = snapshot.data!.first as Checklist;
|
_checklist = snapshot.data!.first as Checklist;
|
||||||
_items = snapshot.data!.last as List<Item>;
|
_items = snapshot.data!.last as List<Item>;
|
||||||
String title = _checklist!.title;
|
return StreamBuilder(
|
||||||
if (pageTitle == null) {
|
stream: DbHelper.itemsChangeEventStream,
|
||||||
WidgetsBinding.instance
|
builder: (BuildContext context,
|
||||||
.addPostFrameCallback((_) => setState(() => pageTitle = title));
|
AsyncSnapshot<List<Map<String, dynamic>>> snapshot) =>
|
||||||
}
|
_streamBuilder(context, snapshot, _checklist, _items),
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Text(_checklist!.description),
|
|
||||||
SizedBox(
|
|
||||||
width: 500,
|
|
||||||
height: 500,
|
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: _items.length,
|
|
||||||
itemBuilder: _itemListBuilder,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
return Text('Ooooops, ${snapshot.error}');
|
return Text('Ooooops, ${snapshot.error}');
|
||||||
@@ -172,35 +161,17 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget get _pageTitleBuilder {
|
Widget get _pageTitleBuilder {
|
||||||
TextEditingController titleController = TextEditingController();
|
|
||||||
if (!_titleEditMode) {
|
if (!_titleEditMode) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => setState(() => _titleEditMode = true),
|
onTap: () => setState(() => _titleEditMode = true),
|
||||||
child: Text(pageTitle ?? ''));
|
child: Text(pageTitle ?? ''));
|
||||||
} else {
|
} else {
|
||||||
titleController.text = pageTitle ?? '';
|
titleController.text = pageTitle ?? '';
|
||||||
return Row(
|
return Expanded(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
child: TextField(
|
||||||
children: [
|
autofocus: true,
|
||||||
SizedBox(
|
controller: titleController,
|
||||||
width: 300,
|
),
|
||||||
height: Theme.of(context).appBarTheme.toolbarHeight,
|
|
||||||
child: TextField(
|
|
||||||
autofocus: true,
|
|
||||||
controller: titleController,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () => _onTitleChanged(
|
|
||||||
_checklist!.id,
|
|
||||||
titleController.text,
|
|
||||||
),
|
|
||||||
icon: const Icon(Icons.check),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () => setState(() => _titleEditMode = false),
|
|
||||||
icon: const Icon(Icons.cancel_outlined))
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,10 +190,22 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: _pageTitleBuilder,
|
title: _pageTitleBuilder,
|
||||||
actions: [
|
actions: [
|
||||||
if (selectedItemIndexes.isNotEmpty)
|
if (selectedItemIndexes.isNotEmpty && !_titleEditMode)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: _onDeleteItemsPressed,
|
onPressed: _onDeleteItemsPressed,
|
||||||
icon: const Icon(Icons.delete))
|
icon: const Icon(Icons.delete)),
|
||||||
|
if (_titleEditMode)
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => _onTitleChanged(
|
||||||
|
_checklist!.id,
|
||||||
|
titleController.text,
|
||||||
|
),
|
||||||
|
icon: const Icon(Icons.check),
|
||||||
|
),
|
||||||
|
if (_titleEditMode)
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => setState(() => _titleEditMode = false),
|
||||||
|
icon: const Icon(Icons.cancel_outlined)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: FutureBuilder(
|
body: FutureBuilder(
|
||||||
@@ -235,4 +218,31 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_streamBuilder(
|
||||||
|
BuildContext context,
|
||||||
|
AsyncSnapshot<List<Map<String, dynamic>>> snapshot,
|
||||||
|
Checklist? checklist,
|
||||||
|
List<Item> items) {
|
||||||
|
if (pageTitle != _checklist!.title) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback(
|
||||||
|
(_) => setState(() => pageTitle = _checklist!.title));
|
||||||
|
}
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
_items = DbHelper.resToItemList(snapshot.data!);
|
||||||
|
}
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Text(_checklist!.description),
|
||||||
|
SizedBox(
|
||||||
|
width: 500,
|
||||||
|
height: 500,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: _items.length,
|
||||||
|
itemBuilder: _itemListBuilder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,11 @@ class DbHelper {
|
|||||||
.from(checklistsTableName)
|
.from(checklistsTableName)
|
||||||
.stream(primaryKey: ['id']).eq('id', clProvider?.selectedChecklistId);
|
.stream(primaryKey: ['id']).eq('id', clProvider?.selectedChecklistId);
|
||||||
|
|
||||||
static List<Checklist> resToList(List<Map<String, dynamic>> res) {
|
static Stream<List<Map<String, dynamic>>> get itemsChangeEventStream =>
|
||||||
|
_client.from(itemsTableName).stream(primaryKey: ['id']).eq(
|
||||||
|
'checklist_id', clProvider?.selectedChecklistId);
|
||||||
|
|
||||||
|
static List<Checklist> resToChecklistList(List<Map<String, dynamic>> res) {
|
||||||
List<Checklist> checklists = [];
|
List<Checklist> checklists = [];
|
||||||
for (final element in res) {
|
for (final element in res) {
|
||||||
Checklist cl = Checklist(
|
Checklist cl = Checklist(
|
||||||
@@ -193,4 +197,22 @@ class DbHelper {
|
|||||||
}
|
}
|
||||||
return checklists;
|
return checklists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<Item> resToItemList(List<Map<String, dynamic>> res) {
|
||||||
|
final List<Item> items = [];
|
||||||
|
|
||||||
|
for (final item in res) {
|
||||||
|
items.add(
|
||||||
|
Item(
|
||||||
|
item['id'],
|
||||||
|
item['owner_id'],
|
||||||
|
item['title'],
|
||||||
|
item['description'],
|
||||||
|
DateTime.parse(item['created_time']),
|
||||||
|
null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,19 +10,28 @@ class ItemListTile extends StatefulWidget {
|
|||||||
required this.onTap,
|
required this.onTap,
|
||||||
required this.itemSelectionChanged,
|
required this.itemSelectionChanged,
|
||||||
required this.selectionMode,
|
required this.selectionMode,
|
||||||
|
this.isSelected = false,
|
||||||
});
|
});
|
||||||
final String title;
|
final String title;
|
||||||
final String description;
|
final String description;
|
||||||
final bool selectionMode;
|
final bool selectionMode;
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final BoolCallback itemSelectionChanged;
|
final BoolCallback itemSelectionChanged;
|
||||||
|
final bool isSelected;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ItemListTile> createState() => _ItemListTileState();
|
State<ItemListTile> createState() => _ItemListTileState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ItemListTileState extends State<ItemListTile> {
|
class _ItemListTileState extends State<ItemListTile> {
|
||||||
bool isSelected = false;
|
late bool isSelected;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
isSelected = widget.isSelected;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
|||||||
Reference in New Issue
Block a user