Mobile micro-activity coach for desk workers and recovery-focused users. Built for the PhysTech hackathon β a one-handed companion that nudges you to move, tracks how you feel, and adapts a 7-day plan around your real body signals: pain, sleep, energy, and posture.
MoveMate is a physiotherapy-grade micro-coach. Most movement apps push you toward 30-minute workouts; MoveMate is built for the office worker whose ideal session is two minutes. The whole interaction model is "tap once, follow a gentle voice, get back to your day."
It does three things really well:
- Tracks the signals that matter β daily pain (per body area), sleep hours and quality, energy, mood, hydration, posture, and movement history.
- Builds a daily and 7-day plan that responds to those signals β when you flag lower-back pain at 7/10, the plan rearranges. When you slept five hours, it swaps cardio for breath. When your shoulders haven't been touched in a week, it surfaces a shoulder-focused flow.
- Coaches you through every session by voice β TTS-led exercises with per-step prompts, tuned by a personality setting (Calm / Upbeat / Strict).
Everything works offline with shared_preferences. No cloud, no
account.
- Adaptive 7-day plan β generates a personalized week using profile, body coverage, hot pain areas, latest sleep, and energy
- Recommender β picks the next session based on time of day, recent history, daily-goal status, energy, and skipped categories
- Smart Coach β surfaces 4 contextual lines per day, prioritised by signal strength
- Moment of Pride β ranked picker that surfaces the user's best recent
signal (pain drop > streak > week growth > milestone > mood lift > variety
comeback) as a celebration hero on Home
- What's Working β pure-function picker that scans the last 7β14 days for positive observations (active-day rhythm, pain trending down, mood lift, variety, week-over-week growth, morning energy spike) and returns up to three for a green Home card
- Wellness Score β composite index (Streak / Variety / Volume / Today) with a week-over-week delta
- Movement DNA + Energy Hours + Body Coverage β analytics derived from raw session history
- Personal Records β longest streak, longest session, best day, totals, top focus, active hour window
- Movement sessions β exercise-by-exercise timer with voice prompts and mid-session mood capture
- Breathing room β Box Β· 4-7-8 Β· Triangle Β· Coherent breath patterns with a pulsing focal circle
- Breathing wind-down β automatic 4-cycle box-breathing modal after cardio or any session β₯ 5 min, with travelling-dot box visualization
- Focus mode β Pomodoro block with built-in mid-block movement nudge
- Eye Break (20-20-20) β 30-second three-phase eye-rest
- Walk Break β 1 / 2 / 5-min standing walk with TTS cues
- Mindful Moment (5-4-3-2-1) β sensory grounding exercise
- Posture Check β 5-question self-check with a tailored 3-min follow-up
- Body Tension Map β pick sore spots; the app builds a session prioritising exercises that overlap them
- Custom builder β pick any exercises, set durations, save and run
- Pain Journal β per-body-area pain (0β10) with an interactive body heatmap (front-view silhouette that tints by pain level) plus 14-day sparkline charts; drives the adaptive plan + coach
- Pain report share image β one-tap render of a 1080Γ1920 PNG card summarising 30-day per-area trends, biggest improvement, hottest area, and days logged β shareable straight to a physiotherapist
- Sleep journal β last night's hours and 1β5 quality, surfaces 7-day avg
- Energy check-in β quick 1β5 emoji tap that influences recommendations
- Mood + notes β captured per session
- Notes journal β a dedicated screen (Progress β notes-book icon) listing every session note with full-text search (highlighted matches), date-grouped sections (Today / Yesterday / weekday / full date), the category accent and mood-delta inline per entry β turns scattered notes into a scannable diary
- Mood quick-log on Home β standalone 5-emoji bar (π π π π π) that logs how you feel right now without starting a session; auto-collapses for 4 hours after a fresh log, expands again when stale. With β₯ 3 check-ins in the last 7 days, an inline mini line-chart shows the trend
- Mood line chart β smooth 14-session area chart on Progress with green fill above the zero baseline and red fill below
- Hydration β daily glass goal with a single-tap pill
- Daily challenge + daily mantra β generated from the date
- Mantra share card β the daily mantra on the Smart Coach card has a one-tap share button that renders a 1080Γ1920 portrait quote PNG (gradient background, big emoji, mantra text, dated footer) and pushes it to the system share sheet β a daily affirmation you can post or save
- Streak with freezes β protection days earned every 7-day milestone; evening rescue banner if today is empty
- 18 achievements with a confetti-firing celebration dialog (pulsing trophy, gradient backdrop, per-badge bounce-in animation) and per-badge progress bars showing how close you are to locked ones (e.g. "5/7 days", "120/200 min")
- Daily goal celebration β when a session crosses your daily-minutes goal, a green confetti dialog fires once per day
- Streak milestone celebrations β dedicated dialog at 7 / 14 / 30 / 60 / 100 / 200 / 365 day milestones
- Weekly review β Monday auto-popup summarising the prior week
- Weekly recap share image β 1080Γ1920 portrait recap card (totals, day-by-day bar chart, streak, top focus, mood) shareable from Progress
- Daily progress ring in the header β animated circular ring around the app icon showing today's minutes vs daily goal as a percentage; turns green with a checkmark + glow when the goal is hit
- Quick action chips row β horizontally scrollable colored pills under the header (Pain Β· Eye break Β· Walk Β· Breathe Β· Mindful) for one-tap navigation to the most-used tools
- Hot pain alert banner β gradient red-to-orange banner that surfaces
whenever
storage.hotPainAreas()reports anything β₯ 4/10. Shows the most painful area with a "Soothe" CTA that builds a tailored 3-minute relief session viaExerciseLibrary.buildQuickPlanForArea. Includes an inline 7-day mini-sparkline and a dynamic blurb (Trending down Β· Climbing Β· Steady) so the trend is readable at a glance - Yesterday recap card β compact inline card between Today's Plan and Recommended showing yesterday's minutes, session count, top category and mood-delta chip; only appears when yesterday had at least one session
- Moment of Pride hero β celebratory card that picks the user's best recent signal and presents it with a per-kind gradient
- What's Working card β green/teal panel listing 1β3 positive observations from the last week (active days, pain trending down, mood lift, variety, +min vs last week, morning energy) β hides cleanly when there's nothing celebratory to say
- 30-day daily-minutes heatmap β classic month grid
- 90-day consistency heatmap β GitHub-style 13-week Γ 7-day grid with active-day count, total minutes, and longest streak callout
- Body coverage radar β hexagonal CustomPainter visualising minutes per body area (neck/shoulders/back/core/hips/legs)
- 6-tile wellness strip β Eye, Walk, Posture, Tension, Mindful, Sleep, Pain β horizontally scrollable
- Quiet hours β silence reminders during a window that wraps past midnight
- Test notification button β preview what a real reminder looks like before relying on the schedule
- Voice personality preview β tap-to-hear button next to each Coach option in Settings (Calm / Upbeat / Strict) that speaks a sample line using that profile's rate + pitch so users can pick by ear
- Backup / export β share a JSON dump of all settings, sessions, and logs via the system share sheet
- Demo seeder β Settings tile that loads a 30-day realistic snapshot (sessions, healing back-pain trend, sleep, energy, hydration, posture) for instant demos and screenshots
- Onboarding pain pre-tag β fourth onboarding page lets users tap any achy areas (cycles mild β moderate β sharp β cleared) so the adaptive plan personalizes from session zero
- Branded splash β gradient background + vector M monogram, with light and dark variants
- Light / dark / auto theme, configurable coach voice personality, hydration & daily-minutes goals
- App shortcuts β long-press the launcher icon for instant access to
Pain Β· Stretch Β· Breathe (intent-filters in
AndroidManifest.xml,MethodChannelplumbing inMainActivity.kt, Dart-side routing viaFadeThroughRouteinmain.dart) - System notifications β TZ-aware scheduling, channel + boot receiver registration, quiet-hours filter
| Layer | Tech |
|---|---|
| UI | Flutter (Dart 3.11+), Material 3, custom transitions |
| State | Plain Storage wrapper around shared_preferences (no provider/bloc β keeps the surface tiny and testable) |
| Voice | flutter_tts with a per-personality rate / pitch profile |
| Notifications | flutter_local_notifications + timezone + flutter_timezone, with quiet-hours filtering |
| Sharing | share_plus + path_provider for share-card PNGs and JSON backups |
| Effects | confetti for streak / goal / achievement celebrations |
| Native | Kotlin MethodChannel for app shortcuts |
| i18n | intl for date formatting |
No backend, no auth, no analytics SDK. Single-binary APK.
ββββββββββββββββββββββββββββββββββββββββββββ
β 4-tab nav: Home Β· Tools Β· Progress Β· β β
ββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββ ββββββββββββββ ββββββββββββββββ
β Screens β β Algorithmsβ β Storage β
ββββββββββββββ€ ββββββββββββββ€ ββββββββββββββββ€
β home β β recommenderβ β shared_prefs β
β tools β β smart_coachβ β β β
β history β β adaptive_ β β Storage β
β settings β β plan β β facade β
β session β β records β β β
β pain_log β β wellness_ β β β
β sleep β β score β β β
β ...12 more β β moment_of_ β β β
β β β pride β β β
β β β insights β β β
βββββββ¬βββββββ ββββββββ¬ββββββ ββββββββ¬ββββββββ
β β β
ββββββββββββββββββ΄βββββββββββββββ
β
βββββββββββΌβββββββββββ
β Models β
β (Exercise, Plan, β
β SessionRecord, β
β BodyArea, ...) β
ββββββββββββββββββββββ
Services:
Β· NotificationService β TZ-aware reminder scheduling, quiet-hours filter,
test-now + showTestNow API
Β· TtsService β voice prompts, personality-driven rate/pitch
Β· MainActivity.kt β Android app shortcuts plumbed via MethodChannel
The Storage facade (lib/storage.dart) is the single source of truth.
Every screen reads through it and triggers a setState in the shell on
write. There are no streams, controllers, or providers β every render of the
home screen rebuilds from scratch. This was deliberate: the data set is small
(~hundreds of session records), the screens are short-lived, and the overhead
is dwarfed by the productivity gain of having "just a class."
The algorithm modules are pure: they take a Storage (or a list of
sessions) and return a result. That makes them trivially testable without
any framework setup β see test/.
lib/
main.dart Entry, theme, 4-tab AppShell, shortcut routing
storage.dart Single SharedPreferences facade β every key + helper
models.dart Exercise, WorkoutPlan, SessionRecord, BodyArea, ...
# Dashboard + tools
home_screen.dart Dashboard (progress ring header, quick actions, hot pain alert,
today card, score, pride, coach, plan, yesterday recap, mood log)
tools_screen.dart Adaptive plan + wellness strip + categories + plans
history_screen.dart Stats, calendar, heatmaps, body coverage radar, mood line,
achievements with progress bars, records
settings_screen.dart Profile, goals, reminders (with test-fire), quiet hours,
voice (with preview), backup
# Active sessions
session_screen.dart Plan-driven workout runner with TTS, mood capture,
goal celebration, achievement + streak dialogs
breathing_screen.dart Box / 4-7-8 / Triangle / Coherent breath patterns
wind_down_sheet.dart 4-cycle box-breathing modal after high-effort sessions
focus_screen.dart Pomodoro focus + movement nudge
eye_break_screen.dart 20-20-20 eye-rest
walk_break_screen.dart 1 / 2 / 5-min standing walk timer
mindful_screen.dart 5-4-3-2-1 grounding
posture_check_screen.dart 5-question self-check + tailored follow-up
tension_screen.dart Body-area picker β custom session builder
sleep_screen.dart Hours + quality entry
pain_journal_screen.dart Per-area pain log with body heatmap + 14-day sparkline + share
body_heatmap.dart Stack-based front-view body silhouette, tints by pain
body_coverage_radar.dart Hexagonal radar of per-area minutes (last 7 days)
consistency_heatmap.dart GitHub-style 13-week Γ 7-day grid
weekly_plan_screen.dart Adaptive 7-day plan view
custom_builder.dart Pick exercises, set durations
onboarding_screen.dart First-run flow (4 pages incl. pain pre-tag)
# Algorithms (pure, testable)
recommendations.dart Recommender β picks the next session
smart_coach.dart Coach lines for the dashboard
adaptive_plan.dart 7-day plan generator
moment_of_pride.dart Ranked picker for the celebration hero
whats_working.dart Picks 1β3 positive observations from recent activity
records.dart Lifetime PersonalRecords
wellness_score.dart Composite Streak/Variety/Volume/Today score
movement_dna.dart Activity-mix profiling
energy_hours.dart When-do-you-move heatmap
body_coverage.dart Which areas have you neglected
insights.dart Weekly insights aggregation
daily_challenge.dart Day-seeded challenge generator
daily_mantra.dart Day-seeded mantra
achievements.dart 18 achievement definitions + check engine + per-badge progress
# Services
notification_service.dart TZ-aware reminders, quiet-hours filter, showTestNow
tts_service.dart flutter_tts wrapper with 3 personalities
# UI helpers + share renderers
animated_widgets.dart StaggeredFadeIn cascade
transitions.dart FadeThroughRoute
exercise_library.dart 30+ exercises across 4 categories + featured plans
share_card.dart Render shareable PNG of a session
pain_report_card.dart 30-day pain report PNG (1080Γ1920) for physiotherapist
weekly_recap_card.dart Weekly recap PNG (1080Γ1920) for social share
mantra_share_card.dart Daily mantra PNG (1080Γ1920) β quote-card share
notes_journal_screen.dart Searchable, date-grouped journal of every session note
demo_seeder.dart Generate a 30-day realistic snapshot for demos
wellness_detail_screen.dart Score breakdown drill-down
weekly_review.dart Monday-morning weekly summary popup
calendar_screen.dart Month grid of activity
mood_picker.dart, note_picker.dart Reusable session widgets
android/app/src/main/
AndroidManifest.xml App shortcuts intent-filters + meta-data
kotlin/.../MainActivity.kt MethodChannel for shortcut routing
res/xml/shortcuts.xml Pain Β· Stretch Β· Breathe long-press shortcuts
res/drawable/ Branded splash gradient + M-monogram vector
test/
widget_test.dart Exercise library invariants
records_test.dart PersonalRecords algorithms
adaptive_plan_test.dart Adaptive 7-day plan generator
storage_test.dart Pain / sleep / quiet-hours storage round-trips
demo_seeder_test.dart Demo snapshot shape + downstream effects
moment_of_pride_test.dart Pride algorithm priority + selection rules
whats_working_test.dart What's-Working observation picker (rhythm, pain drop, cap)
.github/workflows/
ci.yml Flutter analyze + test on push / PR
flutter pub get
flutter run -d <android-device-id>Release APK build:
flutter build apk --release
# output: build/app/outputs/flutter-apk/app-release.apkInstall + launch a debug build on a connected phone:
flutter install -d <device-id> --debug
adb -s <device-id> shell am start -n pl.movemate.movemate/.MainActivityflutter analyze
flutter testCoverage focuses on the algorithmic core (records, adaptive plan, storage,
demo seeder, moment of pride, what's-working). The 33 tests in test/ are
framework-light (shared_preferences is mocked via setMockInitialValues),
run in under 6 seconds, and exercise the interesting branches: streak gaps,
day-sums, plan variation under sleep deficit and pain flags, quiet-hours
wrap-around past midnight, demo seeder produces a healing trend, pride
algorithm picks pain-drop over streak when both qualify, what's-working
flags 4+ active days and surfaces a back-pain trending-down observation,
etc.
The included GitHub Actions workflow (.github/workflows/ci.yml) runs
flutter analyze --no-fatal-infos + flutter test --reporter expanded on
every push and pull request to main.
- No "log your steps" guilt. The sit-timer pill warns gently after a custom interval (default 2 h) but never shouts.
- Pain comes first. When the user has flagged real pain, the coach surfaces it above streaks and goals β physiotherapy first. The Moment of Pride algorithm ranks pain drops above streaks too.
- Wins, not just nags. Three celebration moments (achievement, daily goal, streak milestone) each have their own dedicated confetti dialog, picked to fire independently in the post-session flow.
- Streak freezes prevent shame spirals. A 7-day streak earns a freeze. Miss a day, and a freeze is consumed silently. The streak survives. The rescue banner only appears when freezes are already gone and the day still has hours left β it's a backstop, not a guilt trip.
- Adaptive plan is transparent. Every day card shows why it's there ("Targets back + neck", "You haven't worked shoulders recently"). No black-box recommendations.
- Wind-down after intensity. Cardio sessions and any session β₯ 5 min trigger a 4-cycle box-breathing modal before the mood prompt β closing the loop on intensity with a calm reset rather than a hard stop.
- One-tap is the bar. The Home dashboard is laid out so the most-common next actions (start a recommended session, log mood, soothe a hot pain area, jump to Pain / Eye / Walk / Breathe / Mindful) are reachable in a single tap from the top of the screen.
- Posture detection via on-device ML (
google_mlkit_pose_detection) β camera-driven posture overlay - Health Connect integration β pull step count + heart rate
- Localization β Polish + English language packs
- Adaptive plan editing β drag-to-rearrange days
- Multi-page physiotherapist PDF export
- Apple Health + iOS support
Built solo for the PhysTech hackathon Β· v1.0.0