diet-guard/app/lib/models/workout_session.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

73 lines
2.1 KiB
Dart

/// One published workout, as the PC syncs it in the Body document.
///
/// Split out of `services/activity_kcal.dart` for the 250-line cap; that
/// file re-exports it, so importers see no change. Parsing is tolerant: a
/// malformed session is dropped, an unparsable time reads as null.
library;
/// One workout, reduced to what the energy formulas need.
class Session {
/// Creates a session.
const Session({
required this.day,
required this.kind,
required this.minutes,
required this.km,
required this.label,
required this.source,
this.start,
this.end,
});
/// Parses the synced wire object (`day, kind, min, km, label, src`), or
/// null when it is malformed.
static Session? fromWire(Object? raw) {
if (raw is! Map) return null;
final day = raw['day'];
final kind = raw['kind'];
final minutes = raw['min'];
final km = raw['km'];
if (day is! String || kind is! String || minutes is! num) return null;
if (km != null && km is! num) return null;
return Session(
day: day,
kind: kind,
minutes: minutes.toDouble(),
km: (km as num?)?.toDouble(),
label: raw['label'] is String ? raw['label'] as String : kind,
source: raw['src'] is String ? raw['src'] as String : '',
start: _stampOrNull(raw['start']),
end: _stampOrNull(raw['end']),
);
}
/// Local `YYYY-MM-DD` the workout happened on.
final String day;
/// `strength`, `run`, `walk`, `cycle` or `other`.
final String kind;
/// Duration in minutes.
final double minutes;
/// Distance, or null when the source has none.
final double? km;
/// Human description.
final String label;
/// Where it came from (`runnerup`, `screen-locker`).
final String source;
/// ISO start time, when the source knows it.
final String? start;
/// ISO end time, when the source knows it. The phone drops Health
/// Connect steps inside `start..end`, so a walk is not counted twice.
final String? end;
}
/// An ISO time string, or null when absent or unparsable.
String? _stampOrNull(Object? value) =>
value is String && DateTime.tryParse(value) != null ? value : null;