Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions demos/django-todolist/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const listsPage = ListsPage();
const homePage = listsPage;

const sqlConsolePage = Scaffold(
appBar: StatusAppBar(title: 'SQL Console'),
appBar: StatusAppBar(title: Text('SQL Console')),
body: QueryWidget(defaultQuery: defaultQuery));

const loginPage = LoginPage();
Expand Down Expand Up @@ -76,7 +76,7 @@ class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: StatusAppBar(title: title),
appBar: StatusAppBar(title: Text(title)),
body: Center(child: content),
floatingActionButton: floatingActionButton,
drawer: Drawer(
Expand Down
63 changes: 23 additions & 40 deletions demos/django-todolist/lib/widgets/lists_page.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:async';

import 'package:flutter/material.dart';

import '../powersync.dart';
import './list_item.dart';
import './list_item_dialog.dart';
import '../main.dart';
Expand Down Expand Up @@ -41,48 +40,32 @@ class ListsPage extends StatelessWidget {
}
}

class ListsWidget extends StatefulWidget {
class ListsWidget extends StatelessWidget {
const ListsWidget({super.key});

@override
State<StatefulWidget> createState() {
return _ListsWidgetState();
}
}

class _ListsWidgetState extends State<ListsWidget> {
List<TodoList> _data = [];
StreamSubscription? _subscription;

_ListsWidgetState();

@override
void initState() {
super.initState();
final stream = TodoList.watchListsWithStats();
_subscription = stream.listen((data) {
if (!context.mounted) {
return;
}
setState(() {
_data = data;
});
});
}

@override
void dispose() {
super.dispose();
_subscription?.cancel();
}

@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: _data.map((list) {
return ListItemWidget(list: list);
}).toList(),
return FutureBuilder(
future: db.waitForFirstSync(),
builder: (context, snapshot) {
return switch (snapshot.connectionState) {
ConnectionState.done => StreamBuilder(
stream: TodoList.watchListsWithStats(),
builder: (context, snapshot) {
final items = snapshot.data ?? const [];

return ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: items.map((list) {
return ListItemWidget(list: list);
}).toList(),
);
},
),
// waitForFirstSync() did not complete yet
_ => const Text('Busy with sync...'),
};
},
);
}
}
70 changes: 25 additions & 45 deletions demos/django-todolist/lib/widgets/status_app_bar.dart
Original file line number Diff line number Diff line change
@@ -1,62 +1,42 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:powersync/powersync.dart';
import 'package:powersync_django_todolist_demo/widgets/fts_search_delegate.dart';
import '../powersync.dart';

class StatusAppBar extends StatefulWidget implements PreferredSizeWidget {
const StatusAppBar({super.key, required this.title});

final String title;
class StatusAppBar extends StatelessWidget implements PreferredSizeWidget {
final Widget title;

@override
State<StatusAppBar> createState() => _StatusAppBarState();
const StatusAppBar({super.key, required this.title});

@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

class _StatusAppBarState extends State<StatusAppBar> {
late SyncStatus _connectionState;
StreamSubscription<SyncStatus>? _syncStatusSubscription;

@override
void initState() {
super.initState();
_connectionState = db.currentStatus;
_syncStatusSubscription = db.statusStream.listen((event) {
setState(() {
_connectionState = db.currentStatus;
});
});
}

@override
void dispose() {
super.dispose();
_syncStatusSubscription?.cancel();
}

@override
Widget build(BuildContext context) {
final statusIcon = _getStatusIcon(_connectionState);
return StreamBuilder(
stream: db.statusStream,
initialData: db.currentStatus,
builder: (context, snapshot) {
final status = snapshot.data!;
final statusIcon = _getStatusIcon(status);

return AppBar(
title: Text(widget.title),
actions: <Widget>[
IconButton(
onPressed: () {
showSearch(context: context, delegate: FtsSearchDelegate());
},
icon: const Icon(Icons.search),
),
statusIcon,
// Make some space for the "Debug" banner, so that the status
// icon isn't hidden
if (kDebugMode) _makeIcon('Debug mode', Icons.developer_mode),
],
return AppBar(
title: title,
actions: <Widget>[
IconButton(
onPressed: () {
showSearch(context: context, delegate: FtsSearchDelegate());
},
icon: const Icon(Icons.search),
),
statusIcon,
// Make some space for the "Debug" banner, so that the status
// icon isn't hidden
if (kDebugMode) _makeIcon('Debug mode', Icons.developer_mode),
],
);
},
);
}
}
Expand Down
56 changes: 14 additions & 42 deletions demos/django-todolist/lib/widgets/todo_list_page.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:powersync_django_todolist_demo/models/todo_item.dart';

import './status_app_bar.dart';
import './todo_item_dialog.dart';
Expand Down Expand Up @@ -34,56 +31,31 @@ class TodoListPage extends StatelessWidget {
);

return Scaffold(
appBar: StatusAppBar(title: list.name),
appBar: StatusAppBar(title: Text(list.name)),
floatingActionButton: button,
body: TodoListWidget(list: list));
}
}

class TodoListWidget extends StatefulWidget {
class TodoListWidget extends StatelessWidget {
final TodoList list;

const TodoListWidget({super.key, required this.list});

@override
State<StatefulWidget> createState() {
return TodoListWidgetState();
}
}

class TodoListWidgetState extends State<TodoListWidget> {
List<TodoItem> _data = [];
StreamSubscription? _subscription;

TodoListWidgetState();

@override
void initState() {
super.initState();
final stream = widget.list.watchItems();
_subscription = stream.listen((data) {
if (!context.mounted) {
return;
}
setState(() {
_data = data;
});
});
}

@override
void dispose() {
super.dispose();
_subscription?.cancel();
}

@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: _data.map((todo) {
return TodoItemWidget(todo: todo);
}).toList(),
return StreamBuilder(
stream: list.watchItems(),
builder: (context, snapshot) {
final items = snapshot.data ?? const [];

return ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: items.map((todo) {
return TodoItemWidget(todo: todo);
}).toList(),
);
},
);
}
}
4 changes: 2 additions & 2 deletions demos/firebase-nodejs-todolist/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const listsPage = ListsPage();
const homePage = listsPage;

const sqlConsolePage = Scaffold(
appBar: StatusAppBar(title: 'SQL Console'),
appBar: StatusAppBar(title: Text('SQL Console')),
body: QueryWidget(defaultQuery: defaultQuery));

const loginPage = LoginPage();
Expand Down Expand Up @@ -77,7 +77,7 @@ class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: StatusAppBar(title: title),
appBar: StatusAppBar(title: Text(title)),
body: Center(child: content),
floatingActionButton: floatingActionButton,
drawer: Drawer(
Expand Down
63 changes: 23 additions & 40 deletions demos/firebase-nodejs-todolist/lib/widgets/lists_page.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:async';

import 'package:flutter/material.dart';

import '../powersync.dart';
import './list_item.dart';
import './list_item_dialog.dart';
import '../main.dart';
Expand Down Expand Up @@ -41,48 +40,32 @@ class ListsPage extends StatelessWidget {
}
}

class ListsWidget extends StatefulWidget {
class ListsWidget extends StatelessWidget {
const ListsWidget({super.key});

@override
State<StatefulWidget> createState() {
return _ListsWidgetState();
}
}

class _ListsWidgetState extends State<ListsWidget> {
List<TodoList> _data = [];
StreamSubscription? _subscription;

_ListsWidgetState();

@override
void initState() {
super.initState();
final stream = TodoList.watchListsWithStats();
_subscription = stream.listen((data) {
if (!mounted) {
return;
}
setState(() {
_data = data;
});
});
}

@override
void dispose() {
super.dispose();
_subscription?.cancel();
}

@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: _data.map((list) {
return ListItemWidget(list: list);
}).toList(),
return FutureBuilder(
future: db.waitForFirstSync(),
builder: (context, snapshot) {
return switch (snapshot.connectionState) {
ConnectionState.done => StreamBuilder(
stream: TodoList.watchListsWithStats(),
builder: (context, snapshot) {
final items = snapshot.data ?? const [];

return ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: items.map((list) {
return ListItemWidget(list: list);
}).toList(),
);
},
),
// waitForFirstSync() did not complete yet
_ => const Text('Busy with sync...'),
};
},
);
}
}
Loading