Repository navigation
Add a Distance field to the manual add/edit workout sheet (#1195) - #1203
Merged
Merged
Conversation
Manual workouts (and detected/imported ones opened for edit) could set sport, start, duration, avg HR and calories — but not distance, even though the workout row already stores distanceM and shows it in the detail view. This adds a unit-aware Distance field to the sheet on both platforms, so a session tracked elsewhere (or one where GPS was off/denied) can carry a real distance. - WorkoutSource.buildManualRow / WorkoutEditing.buildManualRow: accept an optional distanceM (default nil), validated 0–1,000 km. preservingCaptured now takes distanceM from the freshly built row instead of force-carrying the old one — the sheet pre-fills the field from the edited row, so an untouched edit round-trips the stored distance, a changed value overrides, and a cleared field clears. The captured route polyline is still preserved. - iOS ManualWorkoutSheet: a Distance field beside Duration; enter in the user's unit (km/mi), stored as metres. New strings localized in all 8 catalog locales. - Android ManualWorkoutDialog: the same field, matching the dialog's existing plain-field style. - Unit tests both platforms: distance bounds + the preservingCaptured override. The Kotlin distanceM param is trailing so the existing positional callers are unaffected. No migration (the column already exists). App-target Swift compiled via app-build; StrandTests has no CI so the Swift test mirrors the Kotlin one verbatim.
This was referenced Aug 10, 2026
ryanbr
pushed a commit
that referenced
this pull request
Aug 15, 2026
…fting it Rebased onto current main: applied the ScrollView refactor to the current formContent (which now carries the #1203 distance row) and kept the NoopChromeSurface() background (main changed it from surfaceOverlay since this branch was opened). Logic/structure otherwise unchanged from #521. #450 raised the sheet to .large but left a bare fixed-height VStack, so iOS keyboard-avoidance rigidly shifts the whole block (clipping the header/Sport field + its suggestion overlay off-screen, and colliding the footer with the system Done accessory). Wrapping the iOS body in a ScrollView gives avoidance somewhere to scroll instead. macOS's fixed 420pt panel is untouched.
ryanbr
added a commit
that referenced
this pull request
Aug 15, 2026
…fting it (#1336) Rebased onto current main: applied the ScrollView refactor to the current formContent (which now carries the #1203 distance row) and kept the NoopChromeSurface() background (main changed it from surfaceOverlay since this branch was opened). Logic/structure otherwise unchanged from #521. #450 raised the sheet to .large but left a bare fixed-height VStack, so iOS keyboard-avoidance rigidly shifts the whole block (clipping the header/Sport field + its suggestion overlay off-screen, and colliding the footer with the system Done accessory). Wrapping the iOS body in a ScrollView gives avoidance somewhere to scroll instead. macOS's fixed 420pt panel is untouched. Co-authored-by: Max Schädlich <schaedlich.max@gmail.com>
simoncad7
pushed a commit
to simoncad7/noop
that referenced
this pull request
Aug 17, 2026
… (ryanbr#1203) Manual workouts (and detected/imported ones opened for edit) could set sport, start, duration, avg HR and calories — but not distance, even though the workout row already stores distanceM and shows it in the detail view. This adds a unit-aware Distance field to the sheet on both platforms, so a session tracked elsewhere (or one where GPS was off/denied) can carry a real distance. - WorkoutSource.buildManualRow / WorkoutEditing.buildManualRow: accept an optional distanceM (default nil), validated 0–1,000 km. preservingCaptured now takes distanceM from the freshly built row instead of force-carrying the old one — the sheet pre-fills the field from the edited row, so an untouched edit round-trips the stored distance, a changed value overrides, and a cleared field clears. The captured route polyline is still preserved. - iOS ManualWorkoutSheet: a Distance field beside Duration; enter in the user's unit (km/mi), stored as metres. New strings localized in all 8 catalog locales. - Android ManualWorkoutDialog: the same field, matching the dialog's existing plain-field style. - Unit tests both platforms: distance bounds + the preservingCaptured override. The Kotlin distanceM param is trailing so the existing positional callers are unaffected. No migration (the column already exists). App-target Swift compiled via app-build; StrandTests has no CI so the Swift test mirrors the Kotlin one verbatim.
simoncad7
pushed a commit
to simoncad7/noop
that referenced
this pull request
Aug 17, 2026
…fting it (ryanbr#1336) Rebased onto current main: applied the ScrollView refactor to the current formContent (which now carries the ryanbr#1203 distance row) and kept the NoopChromeSurface() background (main changed it from surfaceOverlay since this branch was opened). Logic/structure otherwise unchanged from ryanbr#521. ryanbr#450 raised the sheet to .large but left a bare fixed-height VStack, so iOS keyboard-avoidance rigidly shifts the whole block (clipping the header/Sport field + its suggestion overlay off-screen, and colliding the footer with the system Done accessory). Wrapping the iOS body in a ScrollView gives avoidance somewhere to scroll instead. macOS's fixed 420pt panel is untouched. Co-authored-by: Max Schädlich <schaedlich.max@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second follow-up from #1195 (after #1202 added live distance/pace). The issue asks for manual distance editing — "manually add or edit the total distance after a workout is completed." The manual add/edit sheet already edits sport / start / duration / avg HR / calories, and the workout row already stores
distanceMand shows it in the detail view — it just wasn't editable. This adds the field.What changed
buildManualRow(both platforms) — accepts an optionaldistanceM(default nil), validated 0–1,000 km (covers any single session; an Ironman bike is 180 km).preservingCapturednow takesdistanceMfrom the freshly-built row instead of force-carrying the old value: the sheet pre-fills the field from the edited row, so an untouched edit round-trips the stored distance, a changed value overrides, and a cleared field clears. The captured route polyline is still preserved.ManualWorkoutSheet— a Distance field beside Duration; entered in the user's unit (km/mi), stored as metres. New strings localized in all 8 catalog locales.ManualWorkoutDialog— the same field, matching the dialog's existing plain-field style.preservingCapturedoverride/clear behavior.No migration (the
distanceMcolumn already exists). The KotlindistanceMparam is trailing so existing positional callers are untouched; the one caller that sets it passes it by name.Verification
compileFullDebugKotlinclean;WorkoutEditingTest(new distance cases) +UnitFormatterTestgreen.Tools/i18n_audit.py --ciclean (new iOS strings added to the catalog; the Android dialog matches its siblings' baselined plain-field pattern).WorkoutSource,ManualWorkoutSheet,Units) compiled viaapp-build.yml.StrandTestshas no CI, so the Swift test mirrors the passing Kotlin one verbatim.Scope vs #1195
Live distance/pace shipped in #1202; HC distance import shipped in #215. Remaining after this: route import (HC
ExerciseRoute/ Apple Health), and splits (needs per-point timestamps, which the stored track lacks) — both better as their own issues.