This commit is contained in:
Dieter Plaetinck
2024-09-10 21:08:45 +03:00
parent 6faba1f188
commit cea3ae15a6
4 changed files with 113 additions and 66 deletions

View File

@@ -0,0 +1,68 @@
import 'package:powersync/sqlite3.dart' as sqlite;
import 'package:wger/models/schema.dart';
import '../../powersync.dart';
/// TodoItem represents a result row of a query on "todos".
///
/// This class is immutable - methods on this class do not modify the instance
/// directly. Instead, watch or re-query the data to get the updated item.
/// confirm how the watch works. this seems like a weird pattern
class TodoItem {
final String id;
final String description;
final String? photoId;
final bool completed;
TodoItem(
{required this.id,
required this.description,
required this.completed,
required this.photoId});
factory TodoItem.fromRow(sqlite.Row row) {
return TodoItem(
id: row['id'],
description: row['description'],
photoId: row['photo_id'],
completed: row['completed'] == 1);
}
Future<void> toggle() async {
if (completed) {
await db.execute(
'UPDATE $logItemsTable SET completed = FALSE, completed_by = NULL, completed_at = NULL WHERE id = ?',
[id]);
} else {
await db.execute(
'UPDATE $logItemsTable SET completed = TRUE, completed_by = ?, completed_at = datetime() WHERE id = ?',
[await getUserId(), id]);
}
}
Future<void> delete() async {
await db.execute('DELETE FROM $logItemsTable WHERE id = ?', [id]);
}
static Future<void> addPhoto(String photoId, String id) async {
await db.execute('UPDATE $logItemsTable SET photo_id = ? WHERE id = ?', [photoId, id]);
}
}
/*
static Stream<List<TodoList>> watchLists() {
// This query is automatically re-run when data in "lists" or "todos" is modified.
return db.watch('SELECT * FROM lists ORDER BY created_at, id').map((results) {
return results.map(TodoList.fromRow).toList(growable: false);
});
}
static Future<TodoList> create(String name) async {
final results = await db.execute('''
INSERT INTO
lists(id, created_at, name, owner_id)
VALUES(uuid(), datetime(), ?, ?)
RETURNING *
''', [name, await getUserId()]);
return TodoList.fromRow(results.first);
}
*/

View File

@@ -2,9 +2,41 @@ import 'package:powersync/powersync.dart';
const todosTable = 'todos';
const musclesTable = 'muscles';
const logItemsTable = 'nutrition_logitem';
// these are the same ones as in postgres, except for 'id'
/*
Postgres:
wger@localhost:wger> \d nutrition_logitem;
+----------------+--------------------------+--------------------------------------------+
| Column | Type | Modifiers |
|----------------+--------------------------+--------------------------------------------|
| id | integer | not null generated by default as identity |
| datetime | timestamp with time zone | not null |
| comment | text | |
| amount | numeric(6,2) | not null |
| ingredient_id | integer | not null |
| plan_id | integer | not null |
| weight_unit_id | integer | |
| meal_id | integer | |
+----------------+--------------------------+--------------------------------------------+
*/
// these are the same ones as in postgres, except for 'id', because that is implied
Schema schema = const Schema([
Table(
logItemsTable,
[
Column.text('datetime'),
Column.text('comment'),
Column.integer('amount'),
Column.integer('ingredient_id'),
Column.integer('plan_id'),
Column.integer('weight_unit_id'),
Column.integer('meal_id'),
],
indexes: [
// Index('plan', [IndexedColumn('plan_id')])
],
),
Table(
todosTable,
[
@@ -31,11 +63,7 @@ Schema schema = const Schema([
),
Table(
'muscles',
[
Column.text('name'),
Column.text('name_en'),
Column.text('is_front'),
],
[Column.text('name'), Column.text('name_en'), Column.text('is_front')],
),
]);

View File

@@ -1,51 +0,0 @@
import 'package:powersync/sqlite3.dart' as sqlite;
import 'package:wger/models/schema.dart';
import 'package:wger/powersync.dart';
/// TodoItem represents a result row of a query on "todos".
///
/// This class is immutable - methods on this class do not modify the instance
/// directly. Instead, watch or re-query the data to get the updated item.
/// confirm how the watch works. this seems like a weird pattern
class TodoItem {
final String id;
final String description;
final String? photoId;
final bool completed;
TodoItem({
required this.id,
required this.description,
required this.completed,
required this.photoId,
});
factory TodoItem.fromRow(sqlite.Row row) {
return TodoItem(
id: row['id'],
description: row['description'],
photoId: row['photo_id'],
completed: row['completed'] == 1,
);
}
Future<void> toggle() async {
if (completed) {
await db.execute(
'UPDATE $todosTable SET completed = FALSE, completed_by = NULL, completed_at = NULL WHERE id = ?',
[id]);
} else {
await db.execute(
'UPDATE $todosTable SET completed = TRUE, completed_by = ?, completed_at = datetime() WHERE id = ?',
[await getUserId(), id]);
}
}
Future<void> delete() async {
await db.execute('DELETE FROM $todosTable WHERE id = ?', [id]);
}
static Future<void> addPhoto(String photoId, String id) async {
await db.execute('UPDATE $todosTable SET photo_id = ? WHERE id = ?', [photoId, id]);
}
}

View File

@@ -52,7 +52,7 @@ class DjangoConnector extends PowerSyncBackendConnector {
}
try {
for (var op in transaction.crud) {
for (final op in transaction.crud) {
final record = {
'table': op.table,
'data': {'id': op.id, ...?op.opData},
@@ -86,9 +86,14 @@ late final PowerSyncDatabase db;
// Hacky flag to ensure the database is only initialized once, better to do this with listeners
bool _dbInitialized = false;
/// id of the user currently logged in
Future<String?> getUserId() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('id');
}
Future<bool> isLoggedIn() async {
final prefs = await SharedPreferences.getInstance(); // Initialize SharedPreferences
final userId = prefs.getString('id');
final userId = await getUserId();
return userId != null;
}
@@ -113,6 +118,9 @@ Future<void> openDatabase() async {
// Otherwise, connect once logged in.
currentConnector = DjangoConnector(db);
db.connect(connector: currentConnector);
// TODO: should we respond to login state changing? like here:
// https://www.powersync.com/blog/flutter-tutorial-building-an-offline-first-chat-app-with-supabase-and-powersync#implement-auth-methods
}
}
@@ -120,9 +128,3 @@ Future<void> openDatabase() async {
Future<void> logout() async {
await db.disconnectAndClear();
}
/// id of the user currently logged in
Future<String?> getUserId() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('id');
}