Skip to content

Commit 4c3049c

Browse files
committed
Make lists page stream-aware
1 parent 53c0d71 commit 4c3049c

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import 'package:flutter/material.dart';
2+
3+
import '../powersync.dart';
4+
import './todo_list_page.dart';
5+
import '../models/todo_list.dart';
6+
7+
/// A variant of the `ListItem` that only shows a summary of completed and
8+
/// pending items when the respective list has an active sync stream.
9+
class SyncStreamsAwareListItem extends StatelessWidget {
10+
SyncStreamsAwareListItem({
11+
required this.list,
12+
}) : super(key: ObjectKey(list));
13+
14+
final TodoList list;
15+
16+
Future<void> delete() async {
17+
// Server will take care of deleting related todos
18+
await list.delete();
19+
}
20+
21+
@override
22+
Widget build(BuildContext context) {
23+
viewList() {
24+
var navigator = Navigator.of(context);
25+
26+
navigator.push(
27+
MaterialPageRoute(builder: (context) => TodoListPage(list: list)));
28+
}
29+
30+
return StreamBuilder(
31+
stream: db.statusStream,
32+
initialData: db.currentStatus,
33+
builder: (context, asyncSnapshot) {
34+
final status = asyncSnapshot.requireData;
35+
final stream =
36+
status.forStream(db.syncStream('todos', {'list': list.id}));
37+
38+
String subtext;
39+
if (stream == null || !stream.subscription.active) {
40+
subtext = 'Items not loaded - click to fetch.';
41+
} else {
42+
subtext =
43+
'${list.pendingCount} pending, ${list.completedCount} completed';
44+
}
45+
46+
return Card(
47+
child: Column(
48+
mainAxisSize: MainAxisSize.min,
49+
children: <Widget>[
50+
ListTile(
51+
onTap: viewList,
52+
leading: const Icon(Icons.list),
53+
title: Text(list.name),
54+
subtitle: Text(subtext),
55+
),
56+
Row(
57+
mainAxisAlignment: MainAxisAlignment.end,
58+
children: <Widget>[
59+
IconButton(
60+
iconSize: 30,
61+
icon: const Icon(
62+
Icons.delete,
63+
color: Colors.red,
64+
),
65+
tooltip: 'Delete List',
66+
alignment: Alignment.centerRight,
67+
onPressed: delete,
68+
),
69+
const SizedBox(width: 8),
70+
],
71+
),
72+
],
73+
),
74+
);
75+
},
76+
);
77+
}
78+
}

demos/supabase-todolist/lib/widgets/lists_page.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import 'package:flutter/material.dart';
22
import 'package:powersync/powersync.dart';
33

4+
import '../app_config.dart';
45
import './list_item.dart';
56
import './list_item_dialog.dart';
67
import '../main.dart';
78
import '../models/todo_list.dart';
89
import 'guard_by_sync.dart';
10+
import 'list_item_sync_stream.dart';
911

1012
void _showAddDialog(BuildContext context) async {
1113
return showDialog<void>(
@@ -55,7 +57,9 @@ class ListsWidget extends StatelessWidget {
5557
return ListView(
5658
padding: const EdgeInsets.symmetric(vertical: 8.0),
5759
children: todoLists.map((list) {
58-
return ListItemWidget(list: list);
60+
return AppConfig.hasSyncStreams
61+
? SyncStreamsAwareListItem(list: list)
62+
: ListItemWidget(list: list);
5963
}).toList(),
6064
);
6165
} else {

0 commit comments

Comments
 (0)