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
233 lines
6.8 KiB
Dart
233 lines
6.8 KiB
Dart
import '../about/external/data/RoutineChain.dart';
|
|
import '../about/external/data/RoutineStep.dart';
|
|
import '../about/internal/application/CommitmentClass.dart';
|
|
import '../about/internal/application/RoutineKind.dart';
|
|
import '../about/internal/application/StepMode.dart';
|
|
|
|
/// Starting points for the routine builder. A blank routine is a harder
|
|
/// thing to commit to than one you only have to adjust.
|
|
class RoutineTemplates {
|
|
static List<RoutineChain> forKind(RoutineKind kind) {
|
|
switch (kind) {
|
|
case RoutineKind.Workout:
|
|
return <RoutineChain>[fullBody(), upperPush(), mobility()];
|
|
case RoutineKind.Meditation:
|
|
return <RoutineChain>[boxBreathing(), bodyScan()];
|
|
case RoutineKind.MustDo:
|
|
return <RoutineChain>[morning(), shutdown()];
|
|
}
|
|
}
|
|
|
|
static RoutineChain fullBody() {
|
|
return RoutineChain(
|
|
title: "Full body strength",
|
|
kind: RoutineKind.Workout,
|
|
days: <int>[1, 3, 5],
|
|
startMinute: 7 * 60,
|
|
steps: <RoutineStep>[
|
|
RoutineStep(
|
|
title: "Warm up",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 300,
|
|
cue: "Easy pace. Raise the heart rate, not the effort."),
|
|
RoutineStep(
|
|
title: "Deadlifts",
|
|
mode: StepMode.Reps,
|
|
sets: 4,
|
|
reps: 6,
|
|
timerSeconds: 45,
|
|
restSeconds: 120,
|
|
cue: "Brace, then push the floor away."),
|
|
RoutineStep(
|
|
title: "Goblet squats",
|
|
mode: StepMode.Reps,
|
|
sets: 3,
|
|
reps: 10,
|
|
timerSeconds: 40,
|
|
restSeconds: 90),
|
|
RoutineStep(
|
|
title: "Push-ups",
|
|
mode: StepMode.Reps,
|
|
sets: 3,
|
|
reps: 12,
|
|
timerSeconds: 30,
|
|
restSeconds: 60),
|
|
RoutineStep(
|
|
title: "Plank",
|
|
mode: StepMode.Timed,
|
|
sets: 3,
|
|
timerSeconds: 45,
|
|
restSeconds: 30,
|
|
cue: "Ribs down. Squeeze everything."),
|
|
RoutineStep(
|
|
title: "Cool down",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 180),
|
|
],
|
|
);
|
|
}
|
|
|
|
static RoutineChain upperPush() {
|
|
return RoutineChain(
|
|
title: "Shoulders & chest",
|
|
kind: RoutineKind.Workout,
|
|
days: <int>[2, 4],
|
|
startMinute: 18 * 60,
|
|
steps: <RoutineStep>[
|
|
RoutineStep(
|
|
title: "Band pull-aparts",
|
|
mode: StepMode.Reps,
|
|
sets: 2,
|
|
reps: 15,
|
|
timerSeconds: 30,
|
|
restSeconds: 30),
|
|
RoutineStep(
|
|
title: "Overhead press",
|
|
mode: StepMode.Reps,
|
|
sets: 4,
|
|
reps: 8,
|
|
timerSeconds: 40,
|
|
restSeconds: 90),
|
|
RoutineStep(
|
|
title: "Incline press",
|
|
mode: StepMode.Reps,
|
|
sets: 3,
|
|
reps: 10,
|
|
timerSeconds: 40,
|
|
restSeconds: 90),
|
|
RoutineStep(
|
|
title: "Lateral raises",
|
|
mode: StepMode.Reps,
|
|
sets: 3,
|
|
reps: 15,
|
|
timerSeconds: 35,
|
|
restSeconds: 45),
|
|
RoutineStep(
|
|
title: "Dips",
|
|
mode: StepMode.Reps,
|
|
sets: 3,
|
|
reps: 10,
|
|
timerSeconds: 35,
|
|
restSeconds: 60),
|
|
],
|
|
);
|
|
}
|
|
|
|
static RoutineChain mobility() {
|
|
return RoutineChain(
|
|
title: "Mobility flow",
|
|
kind: RoutineKind.Workout,
|
|
commitmentClass: CommitmentClass.Elective,
|
|
steps: <RoutineStep>[
|
|
RoutineStep(
|
|
title: "Cat-cow", mode: StepMode.Timed, timerSeconds: 60),
|
|
RoutineStep(
|
|
title: "World's greatest stretch",
|
|
mode: StepMode.Timed,
|
|
sets: 2,
|
|
timerSeconds: 45,
|
|
restSeconds: 10),
|
|
RoutineStep(
|
|
title: "Hip 90/90", mode: StepMode.Timed, timerSeconds: 90),
|
|
RoutineStep(
|
|
title: "Thoracic rotations",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 60),
|
|
],
|
|
);
|
|
}
|
|
|
|
static RoutineChain boxBreathing() {
|
|
return RoutineChain(
|
|
title: "Box breathing",
|
|
kind: RoutineKind.Meditation,
|
|
days: <int>[1, 2, 3, 4, 5, 6, 7],
|
|
startMinute: 6 * 60 + 30,
|
|
steps: <RoutineStep>[
|
|
RoutineStep(
|
|
title: "Settle",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 60,
|
|
cue: "Sit tall. Let the breath find its own pace."),
|
|
RoutineStep(
|
|
title: "Box breathing",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 300,
|
|
cue: "In 4 · hold 4 · out 4 · hold 4"),
|
|
RoutineStep(
|
|
title: "Open awareness",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 120,
|
|
cue: "Notice sounds, then let them go."),
|
|
],
|
|
);
|
|
}
|
|
|
|
static RoutineChain bodyScan() {
|
|
return RoutineChain(
|
|
title: "Evening body scan",
|
|
kind: RoutineKind.Meditation,
|
|
commitmentClass: CommitmentClass.Elective,
|
|
startMinute: 22 * 60,
|
|
steps: <RoutineStep>[
|
|
RoutineStep(
|
|
title: "Feet to hips",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 240,
|
|
cue: "Move attention slowly. Nothing to fix."),
|
|
RoutineStep(
|
|
title: "Torso and arms",
|
|
mode: StepMode.Timed,
|
|
timerSeconds: 240),
|
|
RoutineStep(
|
|
title: "Neck and face", mode: StepMode.Timed, timerSeconds: 180),
|
|
],
|
|
);
|
|
}
|
|
|
|
static RoutineChain morning() {
|
|
return RoutineChain(
|
|
title: "Morning non-negotiables",
|
|
kind: RoutineKind.MustDo,
|
|
commitmentClass: CommitmentClass.NonNegotiable,
|
|
days: <int>[1, 2, 3, 4, 5],
|
|
startMinute: 6 * 60,
|
|
steps: <RoutineStep>[
|
|
RoutineStep(
|
|
title: "Out of bed, no phone",
|
|
mode: StepMode.Check,
|
|
timerSeconds: 60),
|
|
RoutineStep(
|
|
title: "Glass of water", mode: StepMode.Check, timerSeconds: 60),
|
|
RoutineStep(
|
|
title: "Make the bed", mode: StepMode.Check, timerSeconds: 120),
|
|
RoutineStep(
|
|
title: "Write the three things for today",
|
|
mode: StepMode.Check,
|
|
timerSeconds: 300),
|
|
],
|
|
);
|
|
}
|
|
|
|
static RoutineChain shutdown() {
|
|
return RoutineChain(
|
|
title: "Evening shutdown",
|
|
kind: RoutineKind.MustDo,
|
|
days: <int>[1, 2, 3, 4, 5],
|
|
startMinute: 21 * 60 + 30,
|
|
steps: <RoutineStep>[
|
|
RoutineStep(
|
|
title: "Clear the desk", mode: StepMode.Check, timerSeconds: 180),
|
|
RoutineStep(
|
|
title: "Plan tomorrow's first task",
|
|
mode: StepMode.Check,
|
|
timerSeconds: 300),
|
|
RoutineStep(
|
|
title: "Phone on the charger, outside the bedroom",
|
|
mode: StepMode.Check,
|
|
timerSeconds: 60),
|
|
],
|
|
);
|
|
}
|
|
}
|