Add routines module and full goal management

Routines: workout, meditation and must-do routines with timed, rep and
tick steps, sets and rest. A library screen, a builder with templates
and drag-to-reorder steps, and a full-screen player that auto-advances
timed phases, counts backgrounding and logs broken chains as partial.

Goals: a goal editor (deadline, colour, category, default class, archive),
routines linked to goals, and a goal field on tasks and routines. Tasks
added from inside a goal are now actually attached to it via parentId.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
This commit is contained in:
alvocool
2026-11-02 08:45:41 +03:00
parent c88887b639
commit 1a5867a98f
49 changed files with 5384 additions and 220 deletions

View File

@@ -0,0 +1,40 @@
import '../../external/data/RoutineStep.dart';
import 'StepMode.dart';
/// One beat of a running routine — a single work set or the rest after it.
/// The runner walks a flat list of these, so "set 2 of 4" and "rest" are the
/// same kind of thing to the clock.
class RoutinePhase {
/// Index of the step this phase belongs to.
final int stepIndex;
final RoutineStep step;
/// 1-based set number within the step.
final int set;
final bool rest;
RoutinePhase({
required this.stepIndex,
required this.step,
this.set = 1,
this.rest = false,
});
/// Seconds the clock runs for. Zero means the phase waits for a tap.
int get seconds {
if (rest) {
return step.restSeconds;
}
return step.mode == StepMode.Timed ? step.timerSeconds : 0;
}
bool get countsDown {
return seconds > 0;
}
bool get lastSet {
return set >= step.sets;
}
}