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>
- 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>
- 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>
- 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
- 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
- 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)
- 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
- 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
- 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
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>
- 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>
Major improvements to floating window functionality:
- Implemented lazy overlay listener creation/destruction to eliminate ghost overlay
- Added 2Hz cached GPS data push for smooth overlay updates
- Enhanced background persistence with wake locks and heartbeat mechanisms
- Proper Android foreground functionality using bg_launcher package
- Fixed overlay state management race conditions
- Added comprehensive debug logging throughout communication system
- Improved Android manifest with background persistence permissions
- Eliminated overlay status polling interference with data flow
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix overlay size calculation to use physical pixels instead of scaled logical pixels
- Add proper state synchronization between main app and overlay for close events
- Improve overlay close button functionality with bidirectional communication
- Add comprehensive debug output for screen size analysis
- Update overlay visual tweaks (close button sizing, speed display improvements)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed infinite recursion in customDebugPrint function:
- Line 15 was calling customDebugPrint(message) instead of print(message)
- This caused stack overflow crash on any debug output
- Now correctly calls print(message) to avoid recursion
The app was completely broken due to this recursive function bug.
Debug output now works correctly without crashing.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add kDebugMode conditional debug output using debugPrint() helper
- All debug messages (🚀🟢🔴📡📤📐🖱️) only appear in debug builds
- Release builds will be clean without console spam
- Maintains full debug visibility during development
This ensures production APKs have no debug console output while
preserving comprehensive debugging capabilities for development.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements to floating window overlay:
Architecture:
- Clean client-server model: main app as GPS backend, overlay as display client
- Single GPS stream eliminates resource conflicts and sync issues
- Real-time data push: speed, heading, theme, and unit changes sync instantly
Functionality:
- Proper system screen resolution detection and size synchronization
- Main app calculates overlay size, shares exact dimensions with overlay
- Navigation area tap toggles overlay (show/close), long-press always closes
- Comprehensive debug metrics for troubleshooting
Technical fixes:
- Eliminated duplicate GPS streams for better battery life
- Fixed size calculation mismatches between main app and overlay
- Proper overlay state tracking with _isOverlayActive boolean
- Reverted to withOpacity() per NOTES.txt (simpler than Color.fromARGB)
Debug metrics include:
- Creation/destruction signals with 🟢/🔴 indicators
- Real-time data updates with 📡/📤 send/receive tracking
- Window sizing info with 📐 dimensions and font calculations
- User interaction feedback with 🖱️ tap/long-press detection
This implementation provides reliable floating window functionality
with proper data synchronization and efficient resource usage.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Resolved conflicts:
- CLAUDE.md: Updated documentation to match master branch structure
- main.dart: Hybrid overlay sizing - proportional with reasonable limits (280-400w, 140-300h)
This brings the layout improvements from master (better flex ratios and sizing)
into the advanced floating window development branch.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Increase overlay window size from 180x100 to 320x280 for better visibility
- Adjust portrait layout flex ratios: speed area 65, compass area 32
- Better proportions for overlay and main app interface
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
DEVELOPMENT BRANCH - NOT READY FOR PRODUCTION
Floating window overlay functionality:
- Basic GPS data synchronization implemented but unreliable
- Theme/unit sync between main app and overlay works partially
- Proportional sizing and positioning needs major refinement
- Close button works but overlay behavior inconsistent
- Android SYSTEM_ALERT_WINDOW permissions configured
Known issues:
- Overlay reliability inconsistent across devices/Android versions
- GPS sync unreliable, performance impact possible
- Positioning and sizing calculations need major work
This is a work-in-progress development branch. Main functionality
works but is seriously buggy and not ready for release.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Reduce GPS distanceFilter to 0 for faster updates
- Add timeLimit to ensure regular position updates
- Implement cached heading to avoid showing N/A when GPS heading unavailable
- Add speed display logic: show "--" when stationary with no heading data
- Add rotating navigation icon that points in heading direction
- Fix degree symbol in heading format display
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Responsive portrait/landscape layout system
- Precise tap targets: speed text cycles units, compass area cycles themes
- Screen wake lock to prevent dimming during navigation
- Custom DIN1451Alt font integration
- Updated app icons and Flutter dependencies
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Features added:
- Auto-rotate support for portrait/landscape orientations
- Interactive gauge: tap to switch between digital and analog modes
- Extended speed units: added knots with quick selector buttons
- New SpeedUnitSelector widget for convenient unit switching
Known issues identified:
- 10 package dependencies need updates to latest compatible versions
- Orientation switching needs to override system auto-rotate toggle
- Background color customization moved back to TODO (build issues)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>