mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
wip
This commit is contained in:
68
lib/models/nutrition/log_powersync.dart
Normal file
68
lib/models/nutrition/log_powersync.dart
Normal 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);
|
||||
}
|
||||
*/
|
||||
@@ -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')],
|
||||
),
|
||||
]);
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user