diet-guard/app/lib/services/body_prefs.dart
Krzysztof kuhy Rudnicki e761926df4
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
file-length / file length <= 250 lines (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Has been cancelled
Tests / test (push) Has been cancelled
release-apk / release (APK) (push) Has been cancelled
Body tab: weight/body-fat logs, BMI, ideal weight, goal-based kcal target, workouts + Health Connect steps, week planner
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-28 09:03:03 +02:00

50 lines
1.8 KiB
Dart

/// The calorie goal the user last picked -- remembered and synced.
///
/// Stored as one extra field, `goal`, on the synced `profile` record (its
/// own stamp: saving it never counts as editing birth, height or sex), so the
/// sentence "To lose 0.5 kg / week on Moderate eat ..." reads the same on
/// the PC gate and the phone. Each part is validated on read: an unknown
/// direction, unit or activity falls back to that part of [defaultGoal].
///
/// Port of `diet_guard/_body_prefs.py`.
library;
import 'package:diet_guard_app/services/body_energy.dart';
import 'package:diet_guard_app/services/body_service.dart';
/// The profile field the goal is stored under.
const String goalField = 'goal';
/// The wire/disk form (short keys).
Map<String, Object> goalToJson(Goal goal) => {
'dir': goal.direction,
'amt': goal.amount,
'wu': goal.weightUnit,
'tu': goal.timeUnit,
'act': goal.activity,
};
/// Parses a stored goal part by part, defaulting whatever is unusable.
Goal goalFromJson(Object? raw) {
if (raw is! Map) return defaultGoal;
final dir = raw['dir'];
final amt = raw['amt'];
final wu = raw['wu'];
final tu = raw['tu'];
final act = raw['act'];
return defaultGoal.copyWith(
direction: dir is String && directions.contains(dir) ? dir : null,
amount: amt is num && amt >= 0 ? amt.toDouble() : null,
weightUnit: wu is String && weightUnits.containsKey(wu) ? wu : null,
timeUnit: tu is String && timeUnits.containsKey(tu) ? tu : null,
activity: act is String && activityChoices.contains(act) ? act : null,
);
}
/// The remembered goal (the default until one is saved).
Goal savedGoal(BodyService body) => goalFromJson(body.profileValue(goalField));
/// Remembers (and syncs) [goal].
Future<void> setGoal(BodyService body, Goal goal) =>
body.setProfileFields({goalField: goalToJson(goal)});