re factor rog
This commit is contained in:
109
lib/features/location/location_provider.dart
Normal file
109
lib/features/location/location_provider.dart
Normal file
@ -0,0 +1,109 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:rogapp/features/data/user_location.dart';
|
||||
import 'package:rogapp/features/state/game_view_model.dart';
|
||||
|
||||
/// The state for the location feature
|
||||
class LocationState {
|
||||
final Position? currentPosition;
|
||||
final bool isStreamPaused;
|
||||
|
||||
LocationState({
|
||||
this.currentPosition,
|
||||
this.isStreamPaused = false,
|
||||
});
|
||||
|
||||
LocationState copyWith({
|
||||
Position? currentPosition,
|
||||
bool? isStreamPaused,
|
||||
}) {
|
||||
return LocationState(
|
||||
currentPosition: currentPosition ?? this.currentPosition,
|
||||
isStreamPaused: isStreamPaused ?? this.isStreamPaused,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A StateNotifier that manages the location state
|
||||
class LocationNotifier extends StateNotifier<LocationState> {
|
||||
final Ref ref;
|
||||
LocationNotifier(this.ref) : super(LocationState()) {
|
||||
startListening();
|
||||
startPeriodicUpdates();
|
||||
}
|
||||
|
||||
StreamSubscription<Position>? _positionSubscription;
|
||||
Position? _lastPosition;
|
||||
final double _distanceThreshold = 220.0;
|
||||
Timer? _periodicUpdateTimer;
|
||||
|
||||
void startPeriodicUpdates() {
|
||||
_periodicUpdateTimer?.cancel();
|
||||
_periodicUpdateTimer = Timer.periodic(Duration(seconds: 5), (timer) {
|
||||
if (state.currentPosition != null) {
|
||||
// Convert Position to UserLocation
|
||||
UserLocation userLocation =
|
||||
UserLocation.fromPosition(state.currentPosition!);
|
||||
ref.read(gameViewModelProvider.notifier).updateLocation(userLocation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void startListening() {
|
||||
_positionSubscription =
|
||||
Geolocator.getPositionStream().listen((Position position) {
|
||||
if (_shouldUpdatePosition(position)) {
|
||||
state = state.copyWith(currentPosition: position);
|
||||
_lastPosition = position;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool _shouldUpdatePosition(Position newPosition) {
|
||||
if (_lastPosition == null) return true;
|
||||
|
||||
double distance = Geolocator.distanceBetween(
|
||||
_lastPosition!.latitude,
|
||||
_lastPosition!.longitude,
|
||||
newPosition.latitude,
|
||||
newPosition.longitude,
|
||||
);
|
||||
|
||||
return distance < _distanceThreshold;
|
||||
}
|
||||
|
||||
void stopListening() {
|
||||
_positionSubscription?.cancel();
|
||||
_positionSubscription = null;
|
||||
state = state.copyWith(
|
||||
currentPosition: null); // Reset the position state or handle as needed
|
||||
}
|
||||
|
||||
void pauseListening() {
|
||||
_positionSubscription?.pause();
|
||||
}
|
||||
|
||||
void resumeListening() {
|
||||
_positionSubscription?.resume();
|
||||
}
|
||||
|
||||
void updateCurrentPosition(Position? position) {
|
||||
state = state.copyWith(currentPosition: position);
|
||||
}
|
||||
|
||||
void updateStreamPaused(bool isPaused) {
|
||||
state = state.copyWith(isStreamPaused: isPaused);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_positionSubscription?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
final locationNotifierProvider =
|
||||
StateNotifierProvider<LocationNotifier, LocationState>((ref) {
|
||||
return LocationNotifier(ref); // Pass ref directly
|
||||
});
|
||||
Reference in New Issue
Block a user