129 lines
3.5 KiB
Dart
129 lines
3.5 KiB
Dart
import 'dart:async';
|
|
import 'package:equatable/equatable.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:geolocator/geolocator.dart';
|
|
import 'package:intaleq_maps/intaleq_maps.dart';
|
|
import '../data/maps_repository.dart';
|
|
import '../data/models/place_model.dart';
|
|
|
|
/// حالة شاشة الخريطة الرئيسية.
|
|
class HomeState extends Equatable {
|
|
final bool loading;
|
|
final LatLng? currentLocation;
|
|
final LatLng? cameraTarget;
|
|
final PlaceModel? pickup;
|
|
final PlaceModel? destination;
|
|
final String? error;
|
|
|
|
const HomeState({
|
|
this.loading = true,
|
|
this.currentLocation,
|
|
this.cameraTarget,
|
|
this.pickup,
|
|
this.destination,
|
|
this.error,
|
|
});
|
|
|
|
HomeState copyWith({
|
|
bool? loading,
|
|
LatLng? currentLocation,
|
|
LatLng? cameraTarget,
|
|
PlaceModel? pickup,
|
|
PlaceModel? destination,
|
|
String? error,
|
|
bool clearPickup = false,
|
|
bool clearDestination = false,
|
|
bool clearError = false,
|
|
}) {
|
|
return HomeState(
|
|
loading: loading ?? this.loading,
|
|
currentLocation: currentLocation ?? this.currentLocation,
|
|
cameraTarget: cameraTarget ?? this.cameraTarget,
|
|
pickup: clearPickup ? null : (pickup ?? this.pickup),
|
|
destination: clearDestination ? null : (destination ?? this.destination),
|
|
error: clearError ? null : (error ?? this.error),
|
|
);
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [loading, currentLocation, cameraTarget, pickup, destination, error];
|
|
}
|
|
|
|
/// إدارة موقع المستخدم الحالي + الخريطة.
|
|
class HomeCubit extends Cubit<HomeState> {
|
|
final MapsRepository _mapsRepo;
|
|
|
|
HomeCubit(this._mapsRepo) : super(const HomeState()) {
|
|
initLocation();
|
|
}
|
|
|
|
Future<void> initLocation() async {
|
|
try {
|
|
emit(state.copyWith(loading: true, clearError: true));
|
|
|
|
LocationPermission permission = await Geolocator.checkPermission();
|
|
if (permission == LocationPermission.denied) {
|
|
permission = await Geolocator.requestPermission();
|
|
if (permission == LocationPermission.denied ||
|
|
permission == LocationPermission.deniedForever) {
|
|
emit(state.copyWith(
|
|
loading: false,
|
|
error: 'Location permission denied',
|
|
));
|
|
return;
|
|
}
|
|
}
|
|
|
|
final pos = await Geolocator.getCurrentPosition(
|
|
locationSettings: const LocationSettings(
|
|
accuracy: LocationAccuracy.high,
|
|
timeLimit: Duration(seconds: 10),
|
|
),
|
|
);
|
|
final loc = LatLng(pos.latitude, pos.longitude);
|
|
|
|
// جلب العنوان العكسي للموقع الحالي.
|
|
final place = await _mapsRepo.reverseGeocode(pos.latitude, pos.longitude);
|
|
|
|
emit(state.copyWith(
|
|
loading: false,
|
|
currentLocation: loc,
|
|
cameraTarget: loc,
|
|
pickup: place,
|
|
));
|
|
} catch (e) {
|
|
emit(state.copyWith(
|
|
loading: false,
|
|
error: e.toString(),
|
|
));
|
|
}
|
|
}
|
|
|
|
void updateCameraTarget(LatLng target) {
|
|
emit(state.copyWith(cameraTarget: target));
|
|
}
|
|
|
|
void setPickup(PlaceModel place) {
|
|
emit(state.copyWith(pickup: place));
|
|
}
|
|
|
|
void setPickupFromLatLng(LatLng loc, {String? address}) {
|
|
emit(state.copyWith(
|
|
pickup: PlaceModel(
|
|
name: address ?? '',
|
|
address: address,
|
|
lat: loc.latitude,
|
|
lng: loc.longitude,
|
|
),
|
|
));
|
|
}
|
|
|
|
void setDestination(PlaceModel place) {
|
|
emit(state.copyWith(destination: place));
|
|
}
|
|
|
|
void clearTripData() {
|
|
emit(state.copyWith(clearPickup: true, clearDestination: true, clearError: true));
|
|
}
|
|
}
|