import 'dart:async'; import 'package:flutter/material.dart'; import '../services/share_service.dart'; class TrackedPerson { final String shareId; final String name; final Color color; Map? position; Timer? timer; TrackedPerson({ required this.shareId, required this.color, this.name = '', this.position, this.timer, }); } class ShareProvider with ChangeNotifier { final ShareService _shareService; String _shareId = ''; String _geoId = ''; bool _isLoading = false; String _error = ''; Map? _position; final List _trackedPeople = []; final List _markerColors = [ Colors.red, Colors.green, Colors.orange, Colors.purple, Colors.teal, Colors.pink, Colors.brown, Colors.indigo, ]; int _nextColorIndex = 0; ShareProvider({ShareService? shareService}) : _shareService = shareService ?? ShareService(); String get shareId => _shareId; String get geoId => _geoId; bool get isLoading => _isLoading; String get error => _error; Map? get position => _position; List get trackedPeople => List.unmodifiable(_trackedPeople); Future createShare(String token, double x, double y) async { _isLoading = true; _error = ''; notifyListeners(); try { final result = await _shareService.createShare(token, x, y); _geoId = result['geo_id']?.toString() ?? ''; _shareId = result['share_id']?.toString() ?? ''; notifyListeners(); } catch (e) { _error = e.toString(); notifyListeners(); rethrow; } finally { _isLoading = false; notifyListeners(); } } Future getPosition(String token, String shareId) async { _isLoading = true; _error = ''; notifyListeners(); try { _position = await _shareService.getPositionByShareId(token, shareId); notifyListeners(); } catch (e) { _error = e.toString(); notifyListeners(); rethrow; } finally { _isLoading = false; notifyListeners(); } } void clearShare() { _shareId = ''; _geoId = ''; _position = null; notifyListeners(); } Future addTracking(String shareId, String token) async { if (_trackedPeople.any((p) => p.shareId == shareId)) return; final color = _markerColors[_nextColorIndex % _markerColors.length]; _nextColorIndex++; final person = TrackedPerson( shareId: shareId, color: color, name: 'Person ${_trackedPeople.length + 1}', ); _trackedPeople.add(person); notifyListeners(); await _updatePersonPosition(token, person); } Future _updatePersonPosition(String token, TrackedPerson person) async { try { person.position = await _shareService.getPositionByShareId( token, person.shareId, ); notifyListeners(); } catch (e) { _error = e.toString(); notifyListeners(); } } void startTrackingPolling(String token) { for (final person in _trackedPeople) { person.timer = Timer.periodic( const Duration(seconds: 5), (_) => _updatePersonPosition(token, person), ); } } void removeTracking(String shareId) { final index = _trackedPeople.indexWhere((p) => p.shareId == shareId); if (index != -1) { _trackedPeople[index].timer?.cancel(); _trackedPeople.removeAt(index); notifyListeners(); } } void stopAllTracking() { for (final person in _trackedPeople) { person.timer?.cancel(); } _trackedPeople.clear(); _nextColorIndex = 0; notifyListeners(); } }