From 48d21bfafc135344e4a28d954e327b3079555552 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Tue, 10 Nov 2026 18:47:53 +0100 Subject: [PATCH] One-mode run, pace target, idle map Remove the run/walk toggle: every recording uses the 25 km/h running filter and writes a Running TCX; decodeTcx still reads walking files. Add the optional pace target (stepper, 30 s current pace, band, throttled cues, persisted). The idle map follows the user's fix; refused location shows only the red icon, no map and no start. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01WzxdWZ9CKZsNxtD5Jr9bYD --- .../workout_app/DOCS-workout-app-context.md | 9 +- .../workout_app/assets/sounds/pace_fast.wav | Bin 0 -> 24740 bytes .../workout_app/assets/sounds/pace_slow.wav | Bin 0 -> 49436 bytes .../lib/sandbox/sandbox_run_replay.dart | 40 ++--- .../workout_app/lib/screens/run_screen.dart | 130 +++++++++++--- .../lib/screens/run_screen_numbers.dart | 87 +++++++++ .../lib/screens/run_screen_parts.dart | 169 ++++++------------ .../lib/services/feedback_cues.dart | 33 ++++ .../workout_app/lib/services/gps_filter.dart | 13 +- .../lib/services/idle_location.dart | 98 ++++++++++ .../workout_app/lib/services/pace_band.dart | 114 ++++++++++++ .../workout_app/lib/services/pace_coach.dart | 48 +++++ .../lib/services/pace_target_store.dart | 41 +++++ .../lib/services/position_source.dart | 8 +- .../services/position_source_geolocator.dart | 25 ++- .../services/position_source_scripted.dart | 3 + .../lib/services/run_controller.dart | 52 +++++- .../workout_app/lib/services/run_format.dart | 6 +- .../workout_app/lib/services/run_math.dart | 19 +- .../lib/services/run_notification.dart | 22 ++- .../workout_app/lib/services/run_phase.dart | 17 +- .../lib/services/run_recorder.dart | 65 ++++--- .../workout_app/lib/widgets/run_map.dart | 53 ++++-- .../lib/widgets/run_map_layers.dart | 5 + .../workout_app/lib/widgets/run_map_slot.dart | 11 +- .../lib/widgets/run_pace_picker.dart | 161 +++++++++++++++++ .../workout_app/pubspec.yaml | 2 + .../workout_app/test/fake_geolocator.dart | 27 +++ .../workout_app/test/fake_run_service.dart | 7 + .../workout_app/test/run_test_fixtures.dart | 22 ++- .../test/sandbox/sandbox_run_replay_test.dart | 85 +++++---- .../test/screens/_run_screen_fixtures.dart | 48 ++++- .../test/screens/home_run_entry_test.dart | 11 ++ .../test/screens/run_screen_denied_test.dart | 160 +++++++++++++++++ .../screens/run_screen_idle_map_test.dart | 102 +++++++++++ .../test/screens/run_screen_insets_test.dart | 10 ++ .../screens/run_screen_one_mode_test.dart | 43 +++++ .../test/screens/run_screen_pace_test.dart | 117 ++++++++++++ .../screens/run_screen_problems_test.dart | 27 +-- .../screens/run_screen_sandbox_idle_test.dart | 63 +++++++ .../test/screens/run_screen_sandbox_test.dart | 10 +- .../test/screens/run_screen_test.dart | 35 +--- .../services/feedback_cues_pace_test.dart | 50 ++++++ .../test/services/gps_filter_test.dart | 46 ++--- .../test/services/idle_location_test.dart | 127 +++++++++++++ .../test/services/pace_band_test.dart | 168 +++++++++++++++++ .../test/services/pace_target_store_test.dart | 34 ++++ .../test/services/position_source_test.dart | 13 ++ .../services/run_controller_idle_test.dart | 131 ++++++++++++++ .../test/services/run_controller_test.dart | 2 +- .../test/services/run_format_test.dart | 6 + .../test/services/run_math_test.dart | 11 +- .../test/services/run_notification_test.dart | 13 ++ .../test/services/run_recorder_pace_test.dart | 108 +++++++++++ .../services/run_recorder_start_test.dart | 58 ++++-- .../test/services/run_recorder_test.dart | 8 +- .../test/widgets/run_map_position_test.dart | 125 +++++++++++++ .../test/widgets/run_pace_picker_test.dart | 116 ++++++++++++ .../workout_app/tools/render_pace_tones.py | 63 +++++++ 59 files changed, 2675 insertions(+), 402 deletions(-) create mode 100644 stronglift_replacement/workout_app/assets/sounds/pace_fast.wav create mode 100644 stronglift_replacement/workout_app/assets/sounds/pace_slow.wav create mode 100644 stronglift_replacement/workout_app/lib/screens/run_screen_numbers.dart create mode 100644 stronglift_replacement/workout_app/lib/services/idle_location.dart create mode 100644 stronglift_replacement/workout_app/lib/services/pace_band.dart create mode 100644 stronglift_replacement/workout_app/lib/services/pace_coach.dart create mode 100644 stronglift_replacement/workout_app/lib/services/pace_target_store.dart create mode 100644 stronglift_replacement/workout_app/lib/widgets/run_pace_picker.dart create mode 100644 stronglift_replacement/workout_app/test/fake_geolocator.dart create mode 100644 stronglift_replacement/workout_app/test/screens/run_screen_denied_test.dart create mode 100644 stronglift_replacement/workout_app/test/screens/run_screen_idle_map_test.dart create mode 100644 stronglift_replacement/workout_app/test/screens/run_screen_one_mode_test.dart create mode 100644 stronglift_replacement/workout_app/test/screens/run_screen_pace_test.dart create mode 100644 stronglift_replacement/workout_app/test/screens/run_screen_sandbox_idle_test.dart create mode 100644 stronglift_replacement/workout_app/test/services/feedback_cues_pace_test.dart create mode 100644 stronglift_replacement/workout_app/test/services/idle_location_test.dart create mode 100644 stronglift_replacement/workout_app/test/services/pace_band_test.dart create mode 100644 stronglift_replacement/workout_app/test/services/pace_target_store_test.dart create mode 100644 stronglift_replacement/workout_app/test/services/run_controller_idle_test.dart create mode 100644 stronglift_replacement/workout_app/test/services/run_recorder_pace_test.dart create mode 100644 stronglift_replacement/workout_app/test/widgets/run_map_position_test.dart create mode 100644 stronglift_replacement/workout_app/test/widgets/run_pace_picker_test.dart create mode 100644 stronglift_replacement/workout_app/tools/render_pace_tones.py diff --git a/stronglift_replacement/workout_app/DOCS-workout-app-context.md b/stronglift_replacement/workout_app/DOCS-workout-app-context.md index 598bd30..fdb5825 100644 --- a/stronglift_replacement/workout_app/DOCS-workout-app-context.md +++ b/stronglift_replacement/workout_app/DOCS-workout-app-context.md @@ -16,12 +16,17 @@ Implementing design_v2.md improvements. sync layer owns that database's ordering) ## GPS runs (foundation, 2026-11-10) -- The app records runs/walks itself and uploads a TCX the PC credits unchanged. +- The app records one mode: every GPS activity is a run (25 km/h jump cap, + `Sport="Running"`, `_Running.tcx`); the PC credits all with one rule. No + run/walk toggle. `decodeTcx` still reads old `_Walking.tcx` imports. Optional + pace target (`pace_band.dart`, picker `run_pace_picker.dart`); idle map follows + the user's fix (`idle_location.dart`, display-only); location refused = no + map and no start, only the red icon. The app uploads a TCX the PC credits unchanged. Contract = the PC parser, pinned by `screen_locker/tests/fixtures/run_tcx/` (Dart `test/services/tcx_golden_fixture_test.dart` <-> pytest `screen_locker/tests/test_run_tcx_golden.py`). Regenerate after a deliberate codec change: `UPDATE_GOLDEN=1 flutter test test/services/tcx_golden_fixture_test.dart`. -- File name `RunnerUp_YYYY-MM-DD-HH-MM-SS_.tcx`, stamp in +- File name `RunnerUp_YYYY-MM-DD-HH-MM-SS_.tcx` (historic: `Walking`), stamp in LOCAL time; ``/`