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

@@ -33,6 +33,8 @@ import '../widgets/map/compass_widget.dart';
import '../widgets/map/detailed_compass_dialog.dart';
import '../widgets/map/drawing_layer.dart';
import '../widgets/map/drawing_toolbar.dart';
import '../widgets/map/location_trail_layer.dart';
import '../widgets/map/trail_controls.dart';
import '../widgets/messages/sar_update_sheet.dart';
import '../l10n/app_localizations.dart';
import 'map_management_screen.dart';
@@ -135,6 +137,16 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
// Position updates trigger UI rebuild for markers
});
// Add location point to trail when tracking is active
final mapProvider = context.read<MapProvider>();
if (_locationService.isTracking) {
mapProvider.addTrailPoint(
LatLng(position.latitude, position.longitude),
accuracy: position.accuracy,
speed: position.speed,
);
}
// Rotate map if rotation mode is enabled and heading is available
if (_isMapReady && _rotateMarkerWithHeading && position.heading >= 0) {
try {
@@ -1149,6 +1161,8 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
);
},
),
// Location trail layer (rendered after paths, before drawings)
const LocationTrailLayer(),
// Drawing layer (rendered after paths, before markers)
DrawingLayer(
drawings: drawingProvider.drawings,
@@ -1339,6 +1353,9 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
objectCount: messagesProvider.objectMarkers.length,
),
),
// Trail stats overlay (top-left, below legend if shown)
if (!_isFullscreen)
const TrailStatsOverlay(),
// Map controls - right side (hidden in fullscreen mode)
if (!_isFullscreen)
Positioned(
@@ -1383,6 +1400,9 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
child: const Icon(Icons.my_location),
),
const SizedBox(height: 8),
// Trail controls button
const TrailControls(),
const SizedBox(height: 8),
FloatingActionButton.small(
heroTag: 'layer_selector',
onPressed: () => _showLayerSelector(context),