powersync based muscles

This commit is contained in:
Dieter Plaetinck
2024-09-15 19:37:21 +03:00
parent 4fef0b052d
commit e02bf6b31f
5 changed files with 93 additions and 82 deletions

View File

@@ -25,12 +25,13 @@ class Muscle {
}
Future<void> delete() async {
await db.execute('DELETE FROM $musclesTable WHERE id = ?', [id]);
await db.execute('DELETE FROM $tableMuscles WHERE id = ?', [id]);
}
/// Watch all lists.
static Stream<List<Muscle>> watchMuscles() {
return db.watch('SELECT * FROM $musclesTable ORDER BY id').map((results) {
return db.watch('SELECT * FROM $tableMuscles ORDER BY id').map((results) {
print('watchMuscles triggered' + results.toString());
return results.map(Muscle.fromRow).toList(growable: false);
});
}

View File

@@ -1,29 +1,33 @@
import 'package:powersync/powersync.dart';
const todosTable = 'todos';
const musclesTable = 'exercises_muscle';
const logItemsTable = 'nutrition_logitem';
const tableMuscles = 'exercises_muscle';
const tableLogItems = 'nutrition_logitem';
const tableNutritionPlans = 'nutrition_nutritionplan';
const tableMeals = 'nutrition_meal';
const tableMealItems = 'nutrition_mealitem';
/*
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,
tableMuscles,
[Column.text('name'), Column.text('name_en'), Column.text('is_front')],
),
Table(
tableNutritionPlans,
[
Column.text('creation_date'),
Column.text('description'),
Column.integer('has_goal_calories'),
Column.integer('user_id'),
Column.integer('only_logging'),
Column.integer('goal_carbohydrates'),
Column.integer('goal_energy'),
Column.integer('goal_fat'),
Column.integer('goal_protein'),
Column.integer('goal_fiber'),
],
),
Table(
tableLogItems,
[
Column.text('datetime'),
Column.text('comment'),
@@ -31,71 +35,29 @@ Schema schema = const Schema([
Column.integer('ingredient_id'),
Column.integer('plan_id'),
Column.integer('weight_unit_id'),
Column.integer('meal_id'),
Column.integer('meal_id'), // optional
],
indexes: [
// Index('plan', [IndexedColumn('plan_id')])
],
),
Table(
todosTable,
tableMeals,
[
Column.text('list_id'),
Column.text('created_at'),
Column.text('completed_at'),
Column.text('description'),
Column.integer('completed'),
Column.text('created_by'),
Column.text('completed_by'),
],
indexes: [
// Index to allow efficient lookup within a list
Index('list', [IndexedColumn('list_id')]),
],
),
Table(
'lists',
[
Column.text('created_at'),
Column.integer('order'),
Column.text('time'),
Column.integer('plan_id'),
Column.text('name'),
Column.text('owner_id'),
],
),
Table(
'exercises_muscle',
[Column.text('name'), Column.text('name_en'), Column.text('is_front')],
tableMealItems,
[
Column.integer('order'),
Column.integer('amount'),
Column.integer('ingredient_id'),
Column.integer('meal_id'),
Column.integer('weight_unit_id'),
],
),
]);
// post gres columns:
// todos:
// id | created_at | completed_at | description | completed | created_by | completed_by | list_id
// lists:
// id | created_at | name | owner_id
// diagnostics app:
/*
new Schema([
new Table({
name: 'lists', // same as flutter
columns: [
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'name', type: ColumnType.TEXT }),
new Column({ name: 'owner_id', type: ColumnType.TEXT })
]
}),
new Table({
name: 'todos', // misses completed_at and completed_by, until these actually get populated with something
columns: [
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'description', type: ColumnType.TEXT }),
new Column({ name: 'completed', type: ColumnType.INTEGER }),
new Column({ name: 'created_by', type: ColumnType.TEXT }),
new Column({ name: 'list_id', type: ColumnType.TEXT })
]
})
])
Column.text('completed_at'),
Column.text('completed_by'),
*/

View File

@@ -125,6 +125,9 @@ class NutritionPlansProvider with ChangeNotifier {
}
/// Fetches a plan fully, i.e. with all corresponding child objects
///
Future<NutritionalPlan> fetchAndSetPlanFull(int planId) async {
NutritionalPlan plan;
try {

View File

@@ -16,8 +16,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:wger/models/muscle.dart';
import 'package:wger/widgets/core/app_bar.dart';
import 'package:wger/widgets/dashboard/calendar.dart';
import 'package:wger/widgets/dashboard/widgets.dart';
@@ -39,6 +42,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
padding: EdgeInsets.all(10),
child: Column(
children: [
DashboardMuscleWidget(),
DashboardWorkoutWidget(),
DashboardNutritionWidget(),
DashboardWeightWidget(),
@@ -50,3 +54,46 @@ class _DashboardScreenState extends State<DashboardScreen> {
);
}
}
class DashboardMuscleWidget extends StatefulWidget {
const DashboardMuscleWidget({super.key});
@override
_DashboardMuscleWidgetState createState() => _DashboardMuscleWidgetState();
}
class _DashboardMuscleWidgetState extends State<DashboardMuscleWidget> {
List<Muscle> _data = [];
StreamSubscription? _subscription;
_DashboardMuscleWidgetState();
@override
void initState() {
super.initState();
final stream = Muscle.watchMuscles();
_subscription = stream.listen((data) {
if (!context.mounted) {
return;
}
setState(() {
_data = data;
});
});
}
@override
void dispose() {
_subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.brown,
child: Column(
children: [Text('muscles'), ..._data.map((e) => Text(e.name)).toList()],
));
}
}

View File

@@ -87,12 +87,10 @@ class _HomeTabsScreenState extends State<HomeTabsScreen> with SingleTickerProvid
// TODO: should we cache these credentials? that's what their demo does?
// we could maybe get the initial token from the /api/v2/login call
final credentials = await connector.fetchCredentials();
print('----------');
print(credentials);
print('----------');
print('fetched credentials' + credentials.toString());
await openDatabase(true, baseUrl, powerSyncUrl);
} catch (e) {
print('fail' + e.toString());
print('failed to fetchCredentials()' + e.toString());
}
}