Commit Graph

79 Commits

Author SHA1 Message Date
Mikkeli Matlock 1dd3511047 docs(04): complete phase research 2026-02-12 08:43:40 +09:00
Mikkeli Matlock 7fe6168106 docs(04): capture phase context
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 00:39:35 +09:00
Mikkeli Matlock d0427219a2 docs(03): complete overlay refactor phase
Phase 3 verified: 9/9 must-haves, 6/6 OVRL requirements satisfied.
OverlayService wrapper, staleness detection, error surfacing all verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:35:15 +09:00
Mikkeli Matlock 9fb91f6e3f chore(03): update lockfile for retry dependency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:27:22 +09:00
Mikkeli Matlock 0976b76f44 docs(03-02): complete overlay integration plan
Tasks completed: 2/2
- Task 1: Integrated OverlayService into OverlayProvider with error callbacks and GPS grace period
- Task 2: Added staleness detection to overlay screen and error surfacing to SpeedometerScreen

SUMMARY: .planning/phases/03-overlay-refactor/03-02-SUMMARY.md
2026-02-11 19:26:26 +09:00
Mikkeli Matlock cc11a3d31a feat(03-02): add staleness detection to overlay screen and error surfacing to SpeedometerScreen
Overlay screen staleness:
- Add _lastUpdateTime field to track GPS data freshness
- Add _stalenessCheckTimer for periodic staleness monitoring (1s interval)
- Update _lastUpdateTime from message.timestamp in _listenToMainAppMessages
- Start staleness monitoring in initState, cancel in dispose
- Calculate staleness opacity in build() (0.5 alpha after 3s)
- Apply staleness dimming to speed text, unit text, heading icon, and heading text
- Show "--" for speed after 10s of no data (setState in timer callback)
- Immediate snap-back when fresh data arrives (no AnimatedOpacity)

SpeedometerScreen error surfacing:
- Import permission_handler for openAppSettings
- Register error callback on OverlayProvider in initState postFrameCallback
- Implement _handleOverlayError to show snackbars for overlay errors
- Permission error: snackbar with "Settings" action button that opens app settings
- Creation failure: snackbar with error message (no action button)
- Communication degraded: snackbar with error message (no action button)
- Clean up error callback in dispose (try-catch for disposed provider)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:24:05 +09:00
Mikkeli Matlock 66bdd35995 feat(03-02): integrate OverlayService into OverlayProvider with error callbacks and GPS grace period
- Add OverlayError enum (permission, creationFailed, communicationDegraded)
- Add OverlayService dependency via constructor injection
- Add onError callback field for error surfacing (set by SpeedometerScreen)
- Refactor showOverlay to check permission before showing overlay
- Refactor showOverlay to verify overlay creation via isActive check
- Only set _isOverlayActive after verification succeeds
- Replace all FlutterOverlayWindow calls with OverlayService methods
- Add GPS grace period timer (30s) in _handleOverlayClose
- Cancel grace period if overlay reopens within 30s
- Register OverlayService in MultiProvider before OverlayProvider
- Inject OverlayService into OverlayProvider constructor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:21:58 +09:00
Mikkeli Matlock acfbeb85a2 docs(03-01): complete overlay foundation plan
Tasks completed: 2/2
- Task 1: Create OverlayService and add retry dependency
- Task 2: Add timestamp field to OverlayMessage model

SUMMARY: .planning/phases/03-overlay-refactor/03-01-SUMMARY.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:16:21 +09:00
Mikkeli Matlock 9e3decc91a feat(03-01): add timestamp field to OverlayMessage model
- Add timestamp field with auto-population via DateTime.now()
- Update all factory constructors to include timestamp
- Serialize timestamp as millisecondsSinceEpoch in toMap()
- Deserialize with fallback to DateTime.now() in fromMap()
- Add timestamp parameter to copyWith() method
- Remove const modifiers to allow DateTime.now() runtime values

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:13:39 +09:00
Mikkeli Matlock 505219c858 feat(03-01): create OverlayService and add retry dependency
- Add retry package (^3.1.2) for robust platform operations
- Create OverlayService wrapper for all FlutterOverlayWindow calls
- Implement showOverlay/closeOverlay with 3-attempt retry logic
- Add shareData fire-and-forget with warn-level logging
- Add isActive, overlayListener, checkPermission helpers
- Define staleness constants: 3s dim, 10s dash, 0.5 opacity, 1s check
- Define GPS_GRACE_PERIOD constant (30 seconds)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:12:23 +09:00
Mikkeli Matlock c58183b4fb docs(03): create phase plan for overlay refactor
Phase 3: Overlay Refactor
- 2 plan(s) in 2 wave(s)
- Sequential execution (Plan 02 depends on Plan 01)
- Ready for execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:00:39 +09:00
Mikkeli Matlock 07d446d912 docs(03): research overlay communication and staleness patterns
Phase 3: Overlay Refactor
- Standard stack identified: flutter_overlay_window 0.5.0, retry package, permission_handler
- Architecture patterns documented: OverlayService wrapper, timestamp-based staleness, error surfacing
- Pitfalls catalogued: communication blackhole, permission race conditions, opacity performance
- User decisions integrated: 3s dim threshold, 10s dashes, no recovery animation, 30s grace period

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 18:54:38 +09:00
Mikkeli Matlock 9001a42196 docs(03): capture phase context
Phase 03: Overlay Refactor
- Implementation decisions documented
- Phase boundary established

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:14:45 +09:00
Mikkeli Matlock a27e6b7f3e docs(02): complete provider migration phase
- Phase 2 verified: 20/20 must-haves passed
- STATE-01 through STATE-07 marked Complete in REQUIREMENTS.md
- VERIFICATION.md confirms codebase matches all success criteria
- ROADMAP.md and STATE.md updated for phase completion
2026-02-10 22:28:42 +09:00
Mikkeli Matlock 66320e122b chore(02): update lockfile and generated plugin registrant
- pubspec.lock updated for provider and shared_preferences dependencies
- macOS plugin registrant regenerated by Flutter toolchain
2026-02-10 22:21:48 +09:00
Mikkeli Matlock 09c80011b8 docs(02-02): complete MultiProvider wiring and screen migration plan
Tasks completed: 2/2
- Task 1: Wire MultiProvider in main.dart with async SharedPreferences
- Task 2: Migrate SpeedometerScreen from setState to Provider

SUMMARY: .planning/phases/02-provider-migration/02-02-SUMMARY.md
2026-02-10 22:21:04 +09:00
Mikkeli Matlock 7d111ca202 feat(02-02): migrate SpeedometerScreen from setState to Provider
- Remove all shared state variables (unit, theme, GPS data, overlay status)
- Keep only local widget state (_errorMessage, _isInBackground, timer)
- Replace GPS initialization with context.read<GpsDataManager>().initialize()
- Replace overlay show/close/toggle with OverlayProvider methods
- Replace theme/unit cycling with SettingsProvider.cycleTheme/Unit()
- Remove isOverlayMode parameter (not used, overlay runs in separate isolate)
- Wrap build with Selector<SettingsProvider, ColorTheme> for scaffold background
- Use Selector<GpsDataManager, double> for speed display (rebuilds only on speed change)
- Use Selector<SettingsProvider, String> for unit label (rebuilds only on unit change)
- Use Selector<GpsDataManager, (heading, displayHeading)> for compass (rebuilds only on heading change)
- Use context.read<> for event handlers (non-rebuilding access)
- Simplify dispose() - only cancel background heartbeat timer and disable wakelock
- Background heartbeat uses OverlayProvider.pushCurrentData() instead of inline logic
- setState remains ONLY for _errorMessage (purely local error UI state)
- Remove unused imports (speed_unit.dart, processed_gps_data.dart)
- Portrait and landscape layouts both use Provider pattern
2026-02-10 22:18:34 +09:00
Mikkeli Matlock 9867fe8c46 feat(02-02): wire MultiProvider with pre-initialized SharedPreferences
- Make main() async with WidgetsFlutterBinding.ensureInitialized()
- Pre-initialize SharedPreferences before runApp() to eliminate flash of defaults
- Wire MultiProvider with 4 providers in dependency order:
  1. Provider.value(SharedPreferences) - pre-initialized dependency
  2. ChangeNotifierProvider(SettingsProvider) - theme + unit state
  3. ChangeNotifierProvider(GpsDataManager) - GPS data stream
  4. ChangeNotifierProxyProvider2(OverlayProvider) - depends on GPS + Settings
- Remove isOverlayMode parameter from SpeedoApp (unused, overlay runs in separate isolate)
- Keep overlayMain() unchanged (separate isolate entry point)
2026-02-10 22:15:31 +09:00
Mikkeli Matlock 3c5ce89ded docs(02-01): complete provider infrastructure plan
Tasks completed: 3/3
- Task 1: Add provider dependencies and refactor GpsDataManager to ChangeNotifier
- Task 2: Create SettingsProvider for theme and unit state
- Task 3: Create OverlayProvider for overlay lifecycle and messaging

SUMMARY: .planning/phases/02-provider-migration/02-01-SUMMARY.md
2026-02-10 22:11:49 +09:00
Mikkeli Matlock 6b8bba8686 feat(02-01): create OverlayProvider for overlay lifecycle and messaging
- Created lib/providers/overlay_provider.dart
- Extends ChangeNotifier for reactive overlay state management
- Centralizes ALL overlay operations: show, close, toggle, status monitoring, messaging
- updateDependencies() called by ProxyProvider when GPS or Settings change
- Subscribes to GpsDataManager.dataStream on first update (persist subscription)
- Skips overlay sends when inactive (if-check, not unsubscribe)
- _isDisposed guards on all async-accessible methods
- showOverlay() sends initial data with overlay size info
- _pushDataToOverlay() sends GPS data with current theme/unit
- _startListeningToOverlayMessages() handles overlay→main IPC
- _startOverlayStatusCheck() polls overlay status at 1s interval
- _handleOverlayClose() manages cleanup and optional bring-to-front
- pushCurrentData() public method for background heartbeat usage
- dispose() cancels 4 subscriptions/timers, calls super.dispose() last
2026-02-10 22:05:39 +09:00
Mikkeli Matlock 1961651151 feat(02-01): create SettingsProvider for theme and unit state
- Created lib/providers/settings_provider.dart
- Extends ChangeNotifier for reactive state management
- Constructor accepts pre-initialized SharedPreferences instance
- Loads theme index and speed unit synchronously from SharedPreferences
- cycleTheme() and cycleUnit() methods with haptic feedback
- Persists settings to SharedPreferences on every change
- Both cycle methods call notifyListeners() for reactive UI updates
- No notifyListeners() in constructor (runs before first build)
2026-02-10 22:04:00 +09:00
Mikkeli Matlock f458b62eea chore(02-01): add provider dependencies and refactor GpsDataManager
- Added provider ^6.1.2 and shared_preferences ^2.3.4 to pubspec.yaml
- Removed singleton pattern from GpsDataManager (deleted _instance and instance getter)
- Changed GpsDataManager._internal() to public GpsDataManager() constructor
- Extended ChangeNotifier to enable reactive state updates
- Added _isDisposed guard field to prevent disposed notifications
- Updated _updateData() to call notifyListeners() after stream emission
- Added _isDisposed guards to _onGpsError() and _handleStaleDataTimeout()
- Updated dispose() to set _isDisposed, call super.dispose() last, removed _isInitialized reset
2026-02-10 22:03:13 +09:00
Mikkeli Matlock ee73a1a48d docs(02): phase 2 planned, paused before execution
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 11:31:42 +09:00
Mikkeli Matlock 755c4b7b06 fix(02): revise plans based on checker feedback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 11:17:01 +09:00
Mikkeli Matlock 630cf1c578 docs(02): create phase plan
Phase 02: Provider Migration
- 2 plan(s) in 2 wave(s)
- Wave 1: Create providers (GpsDataManager + SettingsProvider + OverlayProvider)
- Wave 2: Wire MultiProvider and migrate SpeedometerScreen
- Ready for execution
2026-02-10 11:13:29 +09:00
Mikkeli Matlock 8ff74b36e1 docs(02): research phase domain
Phase 02: Provider Migration
- Standard stack identified (provider v6.1.5+1)
- Architecture patterns documented (ChangeNotifier, Consumer, Selector)
- Pitfalls catalogued (7 common errors with solutions)
- Migration strategy validated against context decisions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 11:05:17 +09:00
Mikkeli Matlock 919b239c6e docs(02): capture phase context
Phase 02: Provider Migration
- Implementation decisions documented
- Phase boundary established
2026-02-10 10:58:15 +09:00
Mikkeli Matlock 5c9f3d225e wip: foundation complete, paused before phase 2
Phase 1 fully executed and verified (9/9 must-haves).
Ready to resume with Phase 2 (Provider Migration).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:58:56 +09:00
Mikkeli Matlock 8e3ad7f00c docs(01): complete foundation phase
Phase 1: Foundation - 2 plans executed in 19.6 minutes
- 01-01: Infrastructure, Logger, Constants, Models (12.8 min)
- 01-02: Screen extraction (6.8 min)
- Verification: 9/9 must-haves passed
- Requirements ORG-01 through ORG-08 marked Complete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:55:01 +09:00
Mikkeli Matlock c3865b318a docs(01-02): complete screen extraction plan
Tasks completed: 2/2
- SpeedometerScreen extracted to screens/speedometer_screen.dart (802 lines)
- OverlaySpeedometer extracted to screens/overlay_screen.dart (303 lines)
- main.dart slimmed to 39 lines (entry points only)

Phase 1 Foundation: COMPLETE (2/2 plans, 19.6 min total)

SUMMARY: .planning/phases/01-foundation/01-02-SUMMARY.md
2026-02-09 21:48:38 +09:00
Mikkeli Matlock ad077d1f32 feat(01-02): extract OverlaySpeedometer to screens/overlay_screen.dart
- Created lib/screens/overlay_screen.dart with OverlaySpeedometer and _OverlaySpeedometerState
- All state, methods, gesture handling preserved exactly
- main.dart imports screens/overlay_screen.dart
- OverlaySpeedometer removed from main.dart
- main.dart slimmed to 39 lines (under 60 line target)
- main.dart now contains only: main(), overlayMain(), SpeedoApp class
- Zero analyzer errors (except intentional SCREAMING_SNAKE warnings)
2026-02-09 21:45:56 +09:00
Mikkeli Matlock bc36076134 feat(01-02): extract SpeedometerScreen to screens/speedometer_screen.dart
- Created lib/screens/speedometer_screen.dart with SpeedometerScreen and _SpeedometerScreenState
- All state, methods, layout builders preserved exactly
- main.dart imports screens/speedometer_screen.dart
- SpeedometerScreen removed from main.dart
- Zero analyzer errors (except intentional SCREAMING_SNAKE warnings)
2026-02-09 21:43:41 +09:00
Mikkeli Matlock 88293716a4 docs(01-01): complete plan execution with summary and state updates
- Create 01-01-SUMMARY.md: Comprehensive execution summary with 12.8 min duration
- Update STATE.md: Progress 50% (1/2 plans complete), velocity metrics, decisions table
- Document 5 key decisions made during execution
- Record zero deviations, one minor bug (missing import)
- Phase 1 ready to proceed with plan 01-02
2026-02-09 21:37:02 +09:00
Mikkeli Matlock a0d93d7f6d refactor(01-01): rewire all imports, replace logging, apply constants
- Update gps_data_manager.dart: import ProcessedGpsData from models/, use GpsConfig constants, replace all print() with Logger calls
- Update gps_service.dart: use GpsConfig.VALID_HEADING_MIN/MAX for heading validation
- Update main.dart: import from config/, models/, replace all customDebugPrint() and print() with Logger, use TimingConfig/OverlayConfig constants, convert overlay IPC to OverlayMessage typed class
- Delete customDebugPrint() function definition
- Delete lib/speed_units.dart and lib/color_themes.dart (moved to config/)
- Zero analyzer errors, zero bare print() calls remaining
2026-02-09 21:33:28 +09:00
Mikkeli Matlock 5122be4bc1 feat(01-01): extract models and move config files to new structure
- Move SpeedUnit enum to config/speed_unit.dart
- Move ColorTheme/ColorThemes classes to config/color_themes.dart
- Extract ProcessedGpsData model from gps_data_manager to models/
- Create OverlayMessage typed class for overlay IPC (replaces raw Maps)
- Create ThemeModel with palette rotation and state management
2026-02-09 21:23:49 +09:00
Mikkeli Matlock 2b2fc8fbd3 chore(01-01): create directory structure and infrastructure files
- Create lib/screens/, lib/widgets/, lib/providers/, lib/models/, lib/config/ directories
- Add Logger utility with error/warn/info/debug levels (kDebugMode guarded)
- Add GpsConfig constants (timeouts, heading validation)
- Add TimingConfig constants (heartbeat, overlay intervals)
- Add OverlayConfig constants (sizing, opacity ratios)
2026-02-09 21:22:19 +09:00
Mikkeli Matlock 7e9ed22e40 fix(01): revise plans based on checker feedback
- Clarified ThemeModel delegation rationale (Issue 1)
- Documented why Task 3 is one atomic task (Issue 2)
- Made customDebugPrint deletion step unambiguous (Issue 3)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:13:09 +09:00
Mikkeli Matlock 7f8075b76d docs(01): create phase plan
Phase 01: Foundation
- 2 plan(s) in 2 wave(s)
- 2 autonomous, 0 checkpoint-only
- Ready for execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:08:34 +09:00
Mikkeli Matlock c3b38c25a2 docs(01): research phase domain
Phase 01: Foundation
- Standard stack identified
- Architecture patterns documented
- Pitfalls catalogued

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:02:20 +09:00
Mikkeli Matlock d41e29a1b9 docs(01): capture phase context
Phase 01: Foundation
- Implementation decisions documented
- Phase boundary established

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 20:54:59 +09:00
Mikkeli Matlock 92f3f83a9c docs: create roadmap (4 phases)
Phases:
1. Foundation: code organization, model extraction (ORG-01–08)
2. Provider migration: setState → ChangeNotifier/Consumer (STATE-01–07)
3. Overlay refactor: fix data staleness, error surfacing (OVRL-01–06)
4. GPS & power: adaptive precision, lifecycle management (GPS-01–04, PWR-01–06)

All v1 requirements mapped to phases.
2026-02-09 20:35:40 +09:00
Mikkeli Matlock f4a2caeb65 docs: define v1 requirements
30 requirements across 6 categories
4 requirements deferred to v2
2026-02-09 19:36:03 +09:00
Mikkeli Matlock 3c4231d307 docs: complete project research
Files:
- STACK.md (recommended Provider + existing packages, no new dependencies)
- FEATURES.md (restructure patterns, MVVM architecture requirements)
- ARCHITECTURE.md (layer separation, overlay communication, data flow)
- PITFALLS.md (async lifecycle issues, GPS leaks, battery drain)
- SUMMARY.md (synthesis with 4-phase roadmap recommendations)

Key findings:
- Stack: Provider 6.1.x + existing geolocator/overlay packages (no additions needed)
- Architecture: MVVM with layer-first structure, isolate-aware overlay messaging
- Critical pitfall: setState after dispose during Provider migration (audit async patterns first)

Overall confidence: HIGH
Estimated effort: 52-70 hours
Highest risk: Phase 2 (Provider migration) and Phase 3 (Overlay refactor)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 19:28:28 +09:00
Mikkeli Matlock 308b2c549f chore: add project config
Mode: yolo
Depth: quick
Parallelization: enabled
Workflow agents: research=on, plan_check=on, verifier=on
2026-02-09 19:16:23 +09:00
Mikkeli Matlock 64d210af5c docs: initialize project
Restructure GPS speedometer: modular architecture, Provider state management, overlay reliability fixes, speed-adaptive GPS precision, cooperative Android GPS access.
2026-02-09 19:14:32 +09:00
Mikkeli Matlock a686e6b0fb docs: map existing codebase
- STACK.md - Technologies and dependencies
- ARCHITECTURE.md - System design and patterns
- STRUCTURE.md - Directory layout
- CONVENTIONS.md - Code style and patterns
- TESTING.md - Test structure
- INTEGRATIONS.md - External services
- CONCERNS.md - Technical debt and issues
2026-02-09 18:51:11 +09:00
Mikkeli Matlock 316c730061 Procedural commit, I don't know what's been done 2025-10-02 21:43:29 +09:00
Mikkeli Matlock b185ce0999 feat: implement separate GPS timeouts and update project documentation
GPS Timeout Improvements:
- Add separate GPS timeouts: 20s for initial fix, 2s for ongoing updates
- Resolve indoor GPS timeout issues that caused stream termination
- Prevent GPS stream from stopping immediately due to aggressive timeouts
- Enhanced GPS manager initialization with initial position fetch

Documentation Updates:
- Update TODO.md with v2.3.0-dev architecture completion status
- Update CLAUDE.md with GPS manager architecture details
- Document clean data flow and separate timeout strategy
- Update branch strategy to reflect current development state

Technical Notes:
- GPS manager now handles initial cold start with long timeout
- Ongoing updates use shorter timeout for responsive behavior
- Architecture ready for intelligent caching logic implementation
- All overlay functionality preserved while improving GPS reliability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 14:53:29 +09:00
Mikkeli Matlock 6d1cf5fac3 feat: implement GpsDataManager architecture with modular design
- Add GpsDataManager singleton service for centralized GPS data processing
- Refactor main app to use processed GPS data streams instead of raw position data
- Add haptic feedback to all main UI tap interactions (theme, unit, navigation)
- Implement faster GPS update frequency (500ms timeLimit in LocationSettings)
- Clean up verbose debug logging while preserving essential error logs
- Remove unused debug variables and imports
- Preserve existing background survival mechanisms and overlay lifecycle
- Add temporary GPS simulation while resolving geolocator engine conflicts

Architecture improvements:
- Clean data flow: GPS Hardware → GpsDataManager → Main App → Overlay
- Single source of truth for processed GPS data in manager
- Separation of concerns: GPS logic isolated from UI components
- Foundation ready for intelligent caching logic implementation

Technical notes:
- GPS engine conflict detected, temporarily using simulation data
- All functionality tested and working with test data
- Real GPS integration pending engine conflict resolution

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 01:15:00 +09:00
Mikkeli Matlock 4050bac983 Unsuccessful fix on floating window interactions & new icons 2025-08-28 22:12:41 +09:00