- Update 1.1.0(1):
-
12-Week Progress View
- Toggle between weekly breakdown and 12-week overview with segmented control.
- Tap weeks in 12-week view to browse history, then drill down to daily stats in week mode.
- Tap individual days to see single-day performance with persistent vertical line indicator.
- Dynamic titles: "This week", "Sep 22 - Sep 28, 2025", "Today", "Wednesday, Sep 24".
- Discrete clear button (×) to return from day view to week totals.
- Implementation:
- Created
stats_view_mode_provider.dartfor toggle state (defaults to Last 12 Weeks). - Built
stats_segmented_control.dartwith mode switching. - Added
selected_week_provider.dartandselected_day_provider.dartfor selection state (tried to follow DRY pattern). - Extended
weekly_line_chart.dartto support both 7-day and 12-week modes with month labels (JUL, AUG, SEP, OCT). - Centralized date utilities in
date_utils.dart(week ranges, month/day name constants). - Refactored
weekly_snapshot.dartto handle both modes with individual week/day drill-down. - Chart shows 3 horizontal grid lines (0, middle, max) for minimal clutter.
- Activity list below chart filters to show runs from selected week/day (Week mode only).
- Created
-
Projected finish time now shows for distance-only goals
- Users can now see their projected finish time based on current pace even when they only set a distance goal (without a time target).
- Implementation:
- Modified
projected_finish_provider.dartto calculate projections with just distance (removed requirement for target time). - Updated
prediction_display.dartto show projection in white for distance-only goals (no color coding since there's no time to compare against). - Updated
live_activity_provider.dartto display projection for distance-only goals on iOS Live Activities. - Fixed
current_run.dartto showPredictionDisplaywhen only distance is set.
- Modified
- Behavior: Distance+time goals still show color coding (red when behind, white/green when on track), while distance-only goals always display in white.
-
Manual Activity Entry
- Added ability to manually enter running activities
- Implementation:
- Added "+" button to Activities screen AppBar for easy access.
- Created
AddManualActivityModal. - Built custom Cupertino pickers for all input types:
- Date/Time: "Today at 3:56 PM" format for current day, "Tue Oct 7 at 3:56 PM" for other days.
- Duration: HH:MM:SS format with range 00:00:00 - 99:59:59.
- Distance: 0.0-999.9 with 1 decimal, integrated mi/km unit selection in picker wheel.
- Pace: MM:SS format with range 0:00-59:59, integrated /mi or /km unit selection in picker wheel.
- Auto-calculation Logic: If exactly 2 of 3 fields (Time, Distance, Pace) are filled, automatically calculates the third. If all 3 fields have values and user edits one, recalculates the field that was calculated automatically most recently.
- Unit Synchronization: Distance and Pace units are always synchronized (mi <-> km) without converting numerical values.
- Smart Save Button: Gray and disabled when data incomplete, purple and enabled when all fields complete.
- Persistence: Uses existing
RunSaveServicewithisManual: truefield to distinguish manual from GPS runs.
-
Activities Graph Sharing
- Users can now share their weekly/12-week stats graph as a PNG image to social media
- Implementation:
- Unified clipboard logic into reusable
ClipboardService(DRY principle) - removed duplication fromrunning_stats.dartandrun_summary_screen.dart. - Added discrete share button (iOS share icon) next to graph title.
- Export uses brief "flicker" effect to apply export styling without affecting normal UI.
- Exported image features:
- Semi-transparent white background and 18px rounded corners.
- 20px internal padding (so that graph labels stay visible).
- Pacebud horizontal logo
- Buttons and controls hidden during capture to keep image clean.
- Uses
RepaintBoundary,GlobalKey, andValueNotifierfor selective widget capture at 3x pixel ratio. - Comments:
- Not a big fan of the "flicker" (28ms) but it's the only solution I can think of at the moment. Will probably improve when I add the social media sharing modal.
- Unified clipboard logic into reusable
-
Live activity would not stop if user started a run and ran less than 0.1 mi/km.
- Solution: stop it when pressing 'discard' on the "no movement detected" warning.
-
Distance+time and distance-only goals could show "short by 0.00" or save goalAchieved=false when finishing right at the target distance. UI showed a rounded distance (ex. 8.0 mi) while the threshold crossing used raw precision, so the "first reach" timestamp could be missing.
- Solution:
- Use raw distance internally (and pass it to summary) for consistent evaluation.
- Apply epsilon (0.01 mi / 0.02 km) to treat edge cases as reached.
- If the "first reach" timestamp is missing but distance is effectively reached, fall back to total run time for goal evaluation and to save goalCompletionTimeSeconds.
- For distance-only headers, use the same epsilon and clamp tiny remainders (< epsilon) to 0.00 so the UI doesn’t show misleading "short by 0.00".
- Presentational only: format distance in the card to 2 decimals; evaluation keeps full precision.
- Solution:
-
Some users don't wait around to press "Done", which is when we save the run.
- Solution:
- Moved save flow from "Done" button to "FINISH" button so runs persist immediately.
- Created
RunSaveServiceto modularly build and persist run data. - Modified
saveRunData()to return Firestore doc ID for tracking. - Pass saved doc ID to
RunSummaryScreenso "Discard run" can delete it from database. - Added
deleteRun(docId)method toRunSaveServicefor modular deletion. - Added loading dialog "Saving run..." so user sees feedback (no frozen screen).
- Implemented local backup with
SharedPreferencesif Firestore fails or user is offline. - Auto-sync pending runs on app startup via
AuthWrapper(2s delay for Firebase init). - Show orange snackbar if save fails: "Run saved locally. Will sync when online."
- Solution:
-
Goal distance validation was too strict (1.0 minimum) and didn't prevent navigation on invalid input.
- Solution:
- Lowered hard minimum from 1.0 to 0.1 mi/km for flexibility.
- Added soft warning dialog for distances < 1.0, allowing users to proceed if desired.
- Made
setGoalFromTempSelectionsasync and return bool to prevent navigation on validation failure. - Reused dialog pattern from existing code for consistency (DRY principle).
- Solution:
-
Goal setup dialog was duplicated in two places (onboarding and help button), causing inconsistency.
- Solution:
- Created
showGoalSetupDialog()as single source of truth ininline_goal_input.dart. - Removed duplicate dialog from
home_screen.dart(~180 lines). - Standardized to use Icon instead of emoji for consistency.
- Both onboarding and help button now call the same function.
- Created
- Solution:
-
Unit of measurement always defaulted to km on app restart.
- Solution:
- Converted
distanceUnitProviderfrom simpleStateProvidertoStateNotifierwith automatic persistence. - Implemented
SharedPreferencesstorage with_loadPreference()on init andsetUnit()for saves. - Updated
settings_sheet.dartandinline_goal_input.dartto use asyncsetUnit()method.
- Converted
- Solution:
- Run completed screen (or any other screen) can be enlarged if the user has the text of their phone larger, resulting in not seeing the 'ok button immediatly. Given that we currently save the run when they press this button, if they leave without pressing this, their run will not be saved.
- Save the map photo in the user's data. If user has no map, don't show anything. Make it optional to share it on user's story (Include map? Y/N)
- Add medals/rewards for completing a goal. Then by completing their longest ever run/ fastest time in the 5k, 10k 1/2mara, or marathon.
- Make it easier to share on social media (maybe with appinio_social_share 0.3.2).
- The user should leave the "end run" button pressed for about a second to make sure they intended to finish the run (or add an alert to confirm).
- Improve more DRY occassions.
- Add a streak by week like Hevy/Strava.
- Add a graph that shows how your endurance/speed has improved in the previous runs.
- Additional: Add a function to plan ahead by calculating the distance of a route (with google maps calculate distance feature).
- Add the split pace alerts option.
- If we eventually add social media, a user should be able to challenge their friends for time/distance/pace runs and bet trophies or something.
- Send notifications after periods of inactivity (ex. "Those miles aren't gonna run themselves")
- Activities:
- Default view of last 12 weeks is this week and that's ok. But let's add an easter egg. By tapping "last 12 weeks" (when it's already selected), we can show the total amount of data for the last 12 weeks accumulated.
- Add a "share button" to save on camera roll or "copy to clipboard" for saving the whole rectangle of information along with the graph.