18 Commits

Author SHA1 Message Date
Mikkeli Matlock f9037a6697 v2.2.2: Enhanced background persistence and overlay communication
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>
2025-08-27 23:36:11 +09:00
Mikkeli Matlock bd594601f1 v2.2.0: Fix floating window sizing and state synchronization
- 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>
2025-08-27 00:14:41 +09:00
Mikkeli Matlock 2910706e87 CRITICAL FIX: Resolve StackOverflow in debug function
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>
2025-08-26 23:48:37 +09:00
Mikkeli Matlock d1d7521805 floating overlay size change 2025-08-26 23:41:12 +09:00
Mikkeli Matlock 3e79a448ec Make debug output production-ready with conditional printing
- 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>
2025-08-26 23:40:30 +09:00
Mikkeli Matlock 7ae660156e Complete working floating window implementation
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>
2025-08-26 23:36:16 +09:00
Mikkeli Matlock 9cd497f4f5 Merge master branch improvements into dev/floating-window-wip
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>
2025-08-26 19:33:56 +09:00
Mikkeli Matlock 057f33fc50 Improve floating window sizing and layout ratios
- 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>
2025-08-26 19:31:33 +09:00
Mikkeli Matlock 550755fad9 Update project documentation for v2.1.0 and dev branch strategy
- Updated TODO.md and CLAUDE.md to reflect current branch structure
- Master branch (v2.1.0): stable release with basic floating window
- Dev branch: advanced floating window marked as seriously WIP
- Clear documentation of branch strategy and known issues

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 19:31:21 +09:00
Mikkeli Matlock 940aaee135 Complete floating window WIP documentation updates 2025-08-25 23:41:27 +09:00
Mikkeli Matlock 6c9bada84d Add floating window overlay implementation (seriously WIP)
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>
2025-08-25 23:40:58 +09:00
Mikkeli Matlock 63ee536ef1 minor formatting update 2025-08-25 23:06:46 +09:00
Mikkeli Matlock 2c2267e5ae v2.1.0: Add floating window overlay functionality
Major Features:
- Floating overlay window with system-level persistence
- Split decimal display (main speed prominent, decimal smaller/faded)
- Optimized content sizing for maximum readability
- Navigation icon trigger for overlay activation
- Multiple close options (overlay button + long-press navigation)

Technical Implementation:
- Added flutter_overlay_window dependency
- Android SYSTEM_ALERT_WINDOW permissions
- Overlay service configuration in AndroidManifest
- Enhanced flex ratios for better space utilization
- BoxFit.contain for improved content scaling

UX Improvements:
- Streamlined overlay launch (removed permission prompts)
- Cleaner visual hierarchy with split speed display
- Responsive design for both portrait and landscape
- Professional overlay styling matching app theme

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-25 23:03:31 +09:00
Mikkeli Matlock e6ffb00b2a Updated speed displays 2025-08-25 07:41:49 +09:00
Mikkeli Matlock b3e85983e7 Changed GPS force update timeout to 5s 2025-08-25 07:30:35 +09:00
Mikkeli Matlock 89ce53bb1b Improve GPS performance and heading display
- 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>
2025-08-25 07:26:20 +09:00
Mikkeli Matlock 56327c00ec Added Yuuparo light palette 2025-08-25 07:09:08 +09:00
Mikkeli Matlock 20a7691ac2 Cleaning up Kotlin messes 2025-08-24 23:52:49 +09:00
9 changed files with 904 additions and 87 deletions
+4 -1
View File
@@ -13,7 +13,10 @@
"Bash(cp:*)",
"Bash(flutter:*)",
"Bash(powershell:*)",
"WebFetch(domain:docs.anthropic.com)"
"WebFetch(domain:docs.anthropic.com)",
"WebSearch",
"WebFetch(domain:pub.dev)",
"Bash(git commit:*)"
],
"defaultMode": "acceptEdits"
},
+38 -8
View File
@@ -3,8 +3,8 @@
## Project Overview
A customizable Flutter GPS speedometer app targeting Android devices, emphasizing modularity and user customization.
## Current Status: v1.1 Complete 
**Enhanced GPS speedometer with improved user experience and customization options.**
## Current Status: v2.1.0 Complete 
**GPS speedometer with floating window overlay functionality and optimized visual design.**
### Architecture Implemented
- **State Management:** Provider pattern
@@ -25,25 +25,50 @@ A customizable Flutter GPS speedometer app targeting Android devices, emphasizin
### Technical Stack
```
Dependencies: geolocator, permission_handler, provider, shared_preferences, flutter_material_color_picker
Dependencies: geolocator, permission_handler, provider, shared_preferences, flutter_material_color_picker, flutter_overlay_window
Platforms: Android (primary), iOS support included but untested
Architecture: Provider + Consumer pattern for reactive state management
Permissions: Location services with graceful degradation
Permissions: Location services + SYSTEM_ALERT_WINDOW for overlay functionality
```
## Recent Updates (v1.1)
## Recent Updates (v2.1.0)
### ✅ Completed Features
### ✅ Completed Features (Master Branch - Stable)
- [x] **Split Decimal Display**: Main speed prominent with smaller, faded decimal fraction for better readability
- [x] **Optimized Content Sizing**: Maximized readability with improved responsive layout and flex ratios
- [x] **Basic Floating Window**: Simple overlay with "GPS SPEEDO" text and close button (stable implementation)
- [x] **Navigation Icon Trigger**: Tap compass/navigation area to launch floating window overlay
- [x] **Multiple Close Options**: Overlay close button and long-press navigation area for easy dismissal
- [x] **Android System Integration**: SYSTEM_ALERT_WINDOW permissions and foreground service configuration
### 🚧 Work in Progress Features (dev/floating-window-wip Branch - Seriously Buggy)
- [ ] **Advanced Floating Window Overlay**: System-level overlay with live GPS data - basic functionality works but seriously buggy
- 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 functionality works but overlay behavior inconsistent
- Performance may impact main app, needs optimization
### Previous Updates (v1.1)
- [x] **Portrait/Landscape Support**: Automatic orientation detection implemented
- [x] **Interactive Gauge**: Click gauge face to switch digital/analog modes
- [x] **Extended Speed Units**: Added knots support with quick selector buttons
## TODO - Future Improvements
### Critical Issues
- [ ] **Dependency Updates**: Update 10 packages to latest compatible versions
### Known Issues
**Master Branch (v2.1.0 - Stable):**
- [ ] **Dependency Updates**: Update packages to latest compatible versions
- [ ] **Orientation Override**: Fix auto-rotate to work regardless of system toggle status
**Dev Branch (floating-window-wip - Seriously Buggy):**
- [ ] **Floating Window Reliability**: Overlay behavior inconsistent across different devices and Android versions
- [ ] **GPS Data Sync**: Real-time GPS synchronization between main app and overlay unreliable
- [ ] **Theme/Unit Sync**: Setting synchronization works partially but not consistently
- [ ] **Overlay Positioning**: Poor positioning stability, sizing calculations need major work
- [ ] **Performance**: Overlay may impact main app performance, needs optimization
### UI/UX Enhancements
- [ ] **Background Customization**: Custom background color selection
- [ ] **Interface Rearrangement**: User-defined layout customization
@@ -66,6 +91,11 @@ Permissions: Location services with graceful degradation
- **Memory**: Project uses automatic Claude Code memory - this file for major decisions only
- **Git**: Active repository at `https://github.com/mikkelimatlock/gps_speedo`
## Branch Strategy
- **master**: Stable releases, ready for production APK builds
- **dev/floating-window-wip**: Advanced floating window development (seriously buggy, not for release)
- Tagged releases: v2.1.0 on master branch contains stable basic floating window
## Code Patterns to Maintain
- Provider pattern for state management
- Separate widgets for reusability
+21 -4
View File
@@ -5,13 +5,22 @@
<!-- Optional: for background location access -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- TODO: Enable for display-over-apps functionality -->
<!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> -->
<!-- Overlay window permissions for floating speedometer -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<!-- Background persistence permissions -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application
android:label="Speedo"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:killAfterRestore="false"
android:largeHeap="true">
<activity
android:name=".MainActivity"
android:exported="true"
@@ -20,7 +29,9 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
android:excludeFromRecents="false"
android:stateNotNeeded="false">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
@@ -34,6 +45,12 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Service for overlay window -->
<service
android:name="flutter.overlay.window.flutter_overlay_window.OverlayService"
android:exported="false" />
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
+15 -2
View File
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
class ColorTheme {
final Color background;
final Color speedText;
final Color speedTextSub;
final Color headingText;
final Color unitText;
final String name;
@@ -10,6 +11,7 @@ class ColorTheme {
const ColorTheme({
required this.background,
required this.speedText,
required this.speedTextSub,
required this.headingText,
required this.unitText,
required this.name,
@@ -22,13 +24,15 @@ class ColorThemes {
name: 'Yuzuki',
background: Color.fromARGB(255, 114, 85, 109),
speedText: Color.fromARGB(255, 246, 224, 255),
speedTextSub: Color.fromARGB(255, 245, 217, 245),
headingText: Color.fromARGB(255, 244, 201, 255),
unitText: Color.fromARGB(255, 244, 201, 255),
),
ColorTheme(
name: 'Yuubari',
name: 'Yuuparo',
background: Color.fromARGB(255, 85, 99, 112),
speedText: Color.fromARGB(255, 255, 166, 0),
speedText: Color.fromARGB(255, 255, 171, 16),
speedTextSub: Color.fromARGB(255, 245, 204, 116),
headingText: Color.fromARGB(255, 228, 235, 238),
unitText: Color.fromARGB(255, 141, 196, 184),
),
@@ -36,9 +40,18 @@ class ColorThemes {
name: 'Yuzuki Light',
background: Color.fromARGB(255, 246, 224, 255),
speedText: Color.fromARGB(255, 114, 85, 109),
speedTextSub: Color.fromARGB(255, 161, 138, 170),
headingText: Color.fromARGB(255, 140, 94, 151),
unitText: Color.fromARGB(255, 114, 85, 109),
),
ColorTheme(
name: 'Yuuparo Light',
background: Color.fromARGB(255, 228, 235, 238),
speedText: Color.fromARGB(255, 85, 99, 112),
speedTextSub: Color.fromARGB(255, 100, 100, 131),
headingText: Color.fromARGB(255, 255, 157, 65),
unitText: Color.fromARGB(255, 98, 124, 118),
),
];
static ColorTheme getTheme(int index) {
+15 -5
View File
@@ -3,11 +3,13 @@ import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';
class GpsService {
static double? _lastValidHeading;
static Stream<Position> get positionStream {
return Geolocator.getPositionStream(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.bestForNavigation,
distanceFilter: 1,
distanceFilter: 0,
),
);
}
@@ -21,16 +23,24 @@ class GpsService {
return await Geolocator.isLocationServiceEnabled();
}
static double getCachedHeading(double heading) {
if (heading >= 0 && heading <= 360) {
_lastValidHeading = heading;
return heading;
}
return _lastValidHeading ?? 0.0;
}
static String getCompassDirection(double heading) {
if (heading < 0) return 'N/A';
final cachedHeading = getCachedHeading(heading);
const directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];
final index = ((heading + 22.5) / 45).floor() % 8;
final index = ((cachedHeading + 22.5) / 45).floor() % 8;
return directions[index];
}
static String formatHeading(double heading) {
if (heading < 0) return 'N/A';
return '${heading.round()} ${getCompassDirection(heading)}';
final cachedHeading = getCachedHeading(heading);
return '${cachedHeading.round()} ${getCompassDirection(heading)}'; // don't add that degree symbol, this is cooler
}
}
+786 -65
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -25,6 +25,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.13.0"
bg_launcher:
dependency: "direct main"
description:
name: bg_launcher
sha256: c4c1dfffdcdb2896411a8f2fce8a8fac4712b1664b243b85f69d5347367ea504
url: "https://pub.dev"
source: hosted
version: "0.1.0"
boolean_selector:
dependency: transitive
description:
@@ -134,6 +142,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.0.0"
flutter_overlay_window:
dependency: "direct main"
description:
name: flutter_overlay_window
sha256: "17988420249da68e421d1b44b511e6113d3de7a9e52c3fbd6d99730508af4580"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
flutter_test:
dependency: "direct dev"
description: flutter
+8 -1
View File
@@ -2,7 +2,7 @@ name: gps_speedo
description: "Speedo - A Flutter application."
publish_to: 'none'
version: 2.0.0+1
version: 2.2.0+1
environment:
sdk: ^3.9.0
@@ -21,6 +21,13 @@ dependencies:
# Keep screen awake during navigation
wakelock_plus: ^1.2.8
# Floating window overlay capability
flutter_overlay_window: ^0.5.0
# Bring app to foreground from background/overlay
bg_launcher: ^0.1.0
dev_dependencies:
flutter_test:
sdk: flutter