feat(#665): add Previously completed exercise filter to Single Exercise, Routine, and Profile#669
Conversation
…se, Routine, and Profile Implements the signed-off enhancement for Issue #665: a shared, off-by-default 'Previously completed' filter chip in the exercise picker, wired to exactly three callers: Single Exercise, Routine Editor add-exercise, and Profile Exercise Insights. Changes: - CompletedExerciseIds.kt: profile-tagged state + history ID extraction - ExercisePickerFilters.kt: pure AND-composed filter predicate - ExerciseFilterShelf: Previously completed chip (after Custom, before muscle divider) - MainViewModel/ProfileViewModel: flatMapLatest profile-safe completed-history state - SingleExerciseScreen/RoutineEditorScreen/ProfileScreen: opt-in wiring - FakeWorkoutRepository: profile-scoped + positive-rep getHistoryVisibleSessions - Locale strings in all 6 bundles (en, de, es, fr, it, nl) - Focused tests: ExercisePickerFiltersTest, FakeWorkoutRepositoryTest Closes #665
Code Review Roast 🔥Verdict: No Issues Found | Recommendation: Merge Oh wait, this PR is actually clean. I need to sit down. I had my flamethrower warmed up and everything, and the worst I can find is some whitespace churn and a pre-existing UX bug in unchanged code that this PR accidentally exposes. Overview
Issue Details (click to expand)No correctness or safety findings on changed lines. One summary-only follow-up:
🏆 Best part: The 💀 Worst part: The whitespace churn in 📊 Overall: Like a well-rehearsed stage play — three actors (SingleExercise, RoutineEditor, Profile) hit their marks identically, the cue sheet ( Files Reviewed (18 files)
Ponytail: Lean already. Ship. Reviewed by minimax-m3 · Input: 115.3K · Output: 34.5K · Cached: 5M |
Summary
Implements the signed-off enhancement for Issue #665: a shared, off-by-default Previously completed filter chip in the exercise picker, wired to exactly three callers.
What this adds
A Previously completed filter chip in the exercise picker filter shelf (after Favorites/Custom, before the muscle/equipment divider). When selected, it narrows the exercise list to only exercises the active profile has actually completed in workout history.
Affected flows
Key design decisions
flatMapLatestonactiveProfileContextto prevent cross-profile ID leaks during profile switchesfilterExercisePickerCandidates) for all narrowing filtersgetHistoryVisibleSessionsqueryprofileId == active profile AND deletedAt IS NULL AND (workingReps > 0 OR totalReps > 0) AND exerciseId is not blankChanges (18 files, +521/-148)
New files
CompletedExerciseIds.kt— profile-tagged state + history ID extractionExercisePickerFilters.kt— pure AND-composed filter predicateExercisePickerFiltersTest.kt— filter contract testsFakeWorkoutRepositoryTest.kt— profile-scoped fake coverageModified files
ExercisePicker.kt— opt-in params, loading state, shared filter wiringExerciseFilterShelf.kt— Previously completed chipMainViewModel.kt/ProfileViewModel.kt— profile-safe completed-history stateSingleExerciseScreen.kt/RoutineEditorScreen.kt/ProfileScreen.kt— caller opt-insFakeWorkoutRepository.kt— profile-scoped + positive-rep filteringTesting
Result: BUILD SUCCESSFUL — all tests pass, spotless check passes, debug APK assembles.
Visual Evidence
Final emulator screenshots captured on
phoenix_phantom_api36(API 36):01-single-exercise-default-off.png— default state, chip unselected02-single-exercise-filtered.png— chip selected, empty state with Clear recovery03-routine-add-exercise-default.png— Routine Editor picker, chip visible04-routine-add-exercise-filtered.png— chip selected, empty state05-profile-insights-default.png— Profile Insights picker, no custom exercise button06-profile-insights-filtered.png— chip selected, empty state with Clear recoveryEvidence stored in pipeline artifact directory:
~/.hermes/phoenix-enhancements/issue-665-1527694753049874593/final-visuals/Release Notes
Previously completed exercise filter — A new filter chip in the exercise picker lets you quickly find exercises you have actually done before. Available in Single Exercise, Routine Editor, and Profile Exercise Insights. Off by default; tap the chip to activate.
Closes #665