fix: Just Lift muscle-group classification + retroactive/prompted exercise tagging#483
Conversation
…eral Mobile push hardcoded muscle_group="General" for every session exercise (SyncManager), collapsing the portal Body tab into a single bucket. Resolve the real catalog muscle group via a new SyncRepository.getExerciseMuscleGroup lookup (id -> exact name -> case-insensitive name); default to "General" only for ad-hoc movements not in the catalog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
After PR #435 removed Just Lift exercise auto-detection, untagged freestyle sessions synced with a null session name. PortalSyncAdapter now falls back to "Just Lift" when the session isJustLift and has no routine/exercise name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Untagged Just Lift sessions (isJustLift=true, null exerciseId) could only be tagged during the live workout summary, leaving older ones stuck as "Unknown Exercise" forever. This reuses the existing live tagging mechanism so users can tag them from HistoryTab. - SetSummaryCard: drop the `!isHistoryView` clause gating the tag section so visibility is driven purely by `isJustLiftTaggingEnabled` (caller decides). - HistoryTab: thread an `onTagJustLiftSessionExercise` callback into both SetSummaryCard sites (WorkoutHistoryCard and GroupedRoutineCard), wiring per-session picker state and MiniExercisePickerDialog. The affordance shows only for untagged Just Lift sessions (isJustLift && exerciseId.isNullOrBlank()). - AnalyticsScreen: pass MainViewModel::tagJustLiftSessionExercise to HistoryTab. isAmrap is defaulted to false: WorkoutSession persists no amrap flag and the value only affects cosmetic CompletedSet.setType labeling. The history list refreshes automatically via the SQLDelight-backed groupedWorkoutHistory StateFlow; no manual reload needed. Verified: ./gradlew :shared:testAndroidHostTest — BUILD SUCCESSFUL (compiles + unit tests pass). Not device-verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the user taps Done/Continue on a Just Lift set summary that is still untagged and has real reps (repCount > 0), surface a one-time AlertDialog nudging them to tag the exercise (reusing the existing MiniExercisePickerDialog and onTagJustLiftSessionExercise path). "Tag" opens the picker; "Skip" or dismiss proceeds exactly as before via onProceedFromSummary(). UI-layer only (WorkoutTab.kt). The workout state machine, proceedFromSummary, DefaultWorkoutSessionManager, and ActiveSessionEngine are unchanged. The prompt is one-time per summary (tagPromptResolved keyed on summarySessionId), so there is no nag loop, and the skip path preserves existing save/reset behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
UNTAGGED state now uses primaryContainer background with onPrimaryContainer
content colour, stronger title/subtitle copy, and a FilledTonalButton("Tag
exercise") CTA. TAGGED state is unchanged (muted surfaceContainerHigh, calm
TextButton("Change")). No signature or behaviour change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces the ability to retroactively tag "Just Lift" sessions with an exercise from the history tab, adds a one-time nudge dialog prompting users to tag untagged "Just Lift" sets before dismissing the workout summary, and resolves real muscle groups from the exercise catalog during sync push instead of hardcoding "General". Feedback on these changes suggests ensuring that ID-based lookups in SqlDelightSyncRepository do not fall back to name-based lookups if the muscle group is null, avoiding auto-advancing the summary screen when dismissing the tag prompt dialog by tapping outside, and externalizing hardcoded strings in the dialog to shared resources for internationalization.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3dd1361e1e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Code Review Roast 🔥Verdict: No Issues Found | Recommendation: Merge Oh wait, this PR is actually clean now. I need to sit down. I had my flamethrower warmed up and everything. 📊 Overall: Like a first pancake — the shape was wrong before, but someone actually flipped it and now it's golden. Files Reviewed (10 files)
Reviewed by laguna-m.1-20260312:free · 408,346 tokens |
Summary
Fixes the root cause of the portal Body tab showing everything as "General" and exercises showing as "Unknown Exercise", and makes "Just Lift" (freestyle) sessions taggable so they stop producing unlabeled data.
Data fixes (baseline commits):
muscle_group = "General"for every session exercise, collapsing the portal's Muscle Distribution/Radar into a single bucket. Now resolves the real catalog muscle group via a newSyncRepository.getExerciseMuscleGrouplookup (id → name → case-insensitive); defaults to "General" only for ad-hoc movements.PortalSyncAdapternow falls back to "Just Lift" when the session isisJustLiftwith no routine/exercise name.Tagging UX (new) — makes untagged Just Lift sessions recoverable:
SetSummaryCardtag-section gate; wired bothHistoryTabrender sites + theAnalyticsScreencallback). Reuses the existingtagJustLiftSessionExercisebackend.WorkoutTab; no state-machine changes).primaryContainer+FilledTonalButton); tagged state left calm.Background
"Unknown Exercise" = untagged Just Lift sessions in the post-detection world (auto-detection was replaced with manual tagging in PR #435). These changes restore meaningful labels going forward and let the user salvage the existing backlog. A companion portal change relabels "Unknown Exercise" → "Just Lift (untagged)" and classifies the Body tab by exercise name; the historical
exercises.muscle_grouprows were backfilled.All three tagging features are Compose UI that has NOT been run on a device/emulator. Each passed spec + code-quality review and an integration review, and the module compiles + unit tests pass (
./gradlew :shared:testAndroidHostTest→ BUILD SUCCESSFUL). Runtime/visual behavior is unverified — see Test Plan.Test Plan (on-device)
primaryContainer+ "Tag exercise" filled button + "Label this lift to track it"; tapping opens the picker exactly once.Notes
GroupedRoutineCard's tag block is defensive/unreachable today (Just Lift sessions are always standalone) — harmless.🤖 Generated with Claude Code