feat: Implement command queue for BLE command handling

- Added BleCommandQueue to manage command serialization and responses in BleCommandSender.
- Updated writeData, writeDataAndWaitForAck, and writeDataAndWaitForResponse methods to utilize the command queue.
- Enhanced BleResponseHandler to complete commands based on responses received from the BLE device.
- Introduced new commands for channel management, including getChannel and setChannel.
- Created LocationTrailLayer and TrailControls widgets for displaying and managing location trails on the map.
- Added PermissionRequestDialog to handle location permission requests on app startup.
- Updated LocationTrackingService to allow GPS tracking without a BLE connection.
This commit is contained in:
Janez T
2025-10-18 21:12:02 +02:00
parent f88c9cfdd3
commit c50a260263
35 changed files with 1854 additions and 59 deletions

View File

@@ -18,12 +18,14 @@ import 'device_config_screen.dart';
import 'packet_log_screen.dart';
import '../utils/toast_logger.dart';
import '../l10n/app_localizations.dart';
import '../widgets/permission_request_dialog.dart';
class HomeScreen extends StatefulWidget {
final Function(AppThemeMode) onThemeChanged;
final Function(Locale?) onLocaleChanged;
final AppThemeMode currentTheme;
final Locale? currentLocale;
final bool shouldShowPermissionDialog;
const HomeScreen({
super.key,
@@ -31,6 +33,7 @@ class HomeScreen extends StatefulWidget {
required this.onLocaleChanged,
required this.currentTheme,
required this.currentLocale,
this.shouldShowPermissionDialog = false,
});
@override
@@ -58,6 +61,13 @@ class _HomeScreenState extends State<HomeScreen>
});
});
_loadRxTxPreference();
// Show permission dialog after the first frame if needed
if (widget.shouldShowPermissionDialog) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_showPermissionDialog();
});
}
}
Future<void> _loadRxTxPreference() async {
@@ -75,6 +85,34 @@ class _HomeScreenState extends State<HomeScreen>
super.dispose();
}
void _showPermissionDialog() {
if (!mounted) return;
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => PermissionRequestDialog(
onPermissionsGranted: () {
debugPrint('✅ Location permissions granted');
},
onPermissionsDenied: () {
debugPrint('⚠️ Location permissions denied');
// Show a snackbar to inform the user
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
AppLocalizations.of(context)!.locationPermissionRequired,
),
duration: const Duration(seconds: 5),
),
);
}
},
),
);
}
Future<void> _advertiseDevice(BuildContext context) async {
final connectionProvider = context.read<ConnectionProvider>();