import 'dart:async'; import 'package:flutter/foundation.dart'; import '../../data/models/gps_speed.dart'; import '../../data/services/telemetry_bridge.dart'; /// Polls the native GPS speed snapshot. Starting never asks for permission; it /// simply returns false when precise location is not already allowed or GPS is /// disabled. class GpsSpeedController extends ChangeNotifier { GpsSpeedController(this._platform, {DateTime Function()? clock}) : _clock = clock ?? DateTime.now; final TelemetryPlatform _platform; final DateTime Function() _clock; GpsSpeed _state = const GpsSpeed(); Timer? _timer; bool _active = false; bool _polling = false; bool _disposed = false; bool get hasPermission => _state.hasPermission; bool get hasSpeed => _state.isFresh(_clock()); double? get speedKmh => hasSpeed ? _state.speedKmh : null; Future start() async { if (_active) return; _active = true; final started = await _platform.startGpsSpeed(); if (!started) { _notify(); return; } _timer = Timer.periodic(const Duration(seconds: 1), (_) => _poll()); await _poll(); } void stop() { _active = false; _timer?.cancel(); _timer = null; _state = const GpsSpeed(); unawaited(_platform.stopGpsSpeed()); _notify(); } Future _poll() async { if (!_active || _polling) return; _polling = true; try { final next = await _platform.getGpsSpeed(); if (next != _state) { _state = next; _notify(); } } finally { _polling = false; } } void _notify() { if (!_disposed) notifyListeners(); } @override void dispose() { _disposed = true; _timer?.cancel(); unawaited(_platform.stopGpsSpeed()); super.dispose(); } }