Files
tripz-llc/apps/driver/lib/features/home/cubit/driver_cubit.dart
T

119 lines
3.2 KiB
Dart

import 'dart:async';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../data/driver_repository.dart';
import '../data/driver_location_service.dart';
import '../data/models/driver_profile_model.dart';
/// حالة DriverCubit.
class DriverState extends Equatable {
final DriverProfileModel? profile;
final bool loading;
final bool online;
final String? error;
const DriverState({
this.profile,
this.loading = true,
this.online = false,
this.error,
});
DriverState copyWith({
DriverProfileModel? profile,
bool? loading,
bool? online,
String? error,
bool clearError = false,
}) {
return DriverState(
profile: profile ?? this.profile,
loading: loading ?? this.loading,
online: online ?? this.online,
error: clearError ? null : (error ?? this.error),
);
}
@override
List<Object?> get props => [profile, loading, online, error];
}
/// Cubit مُتّصل/مُنقطع — يدير ملف السائق وتبديل الحالة وموقع الخلفية.
///
/// يُقدّم:
/// - جلب الملف عند بدء التشغيل
/// - تبديل الحالة (online/offline)
/// - بدء/إيقاف تتبع الموقع عند التنشيط
class DriverCubit extends Cubit<DriverState> {
final DriverRepository _repo;
DriverLocationService? _locationService;
Timer? _heartbeatTimer;
DriverCubit(this._repo) : super(const DriverState(loading: true));
/// جلب ملف السائق وتحديد الحالة الأولية.
Future<void> loadProfile() async {
try {
final profile = await _repo.getProfile();
if (profile != null) {
emit(state.copyWith(
profile: profile,
online: profile.online,
loading: false,
));
// إذا كان مُتصلاً مسبقاً، أعد بدء التتبع.
if (profile.online) {
_startLocationTracking();
}
} else {
emit(state.copyWith(loading: false));
}
} catch (e) {
emit(state.copyWith(loading: false, error: e.toString()));
}
}
/// تبديل الحالة (مُتصل/مُنقطع).
Future<void> toggleOnline() async {
final newOnline = !state.online;
emit(state.copyWith(online: newOnline));
final result = await _repo.setOnline(newOnline);
if (!result) {
// فشل — أعد الحالة السابقة.
emit(state.copyWith(online: !newOnline));
return;
}
if (newOnline) {
_startLocationTracking();
} else {
_stopLocationTracking();
}
}
/// بدء تتبع الموقع.
void _startLocationTracking() {
if (_locationService?.isActive == true) return;
_locationService = DriverLocationService((lat, lng, {heading, speed}) async {
await _repo.sendLocation(lat: lat, lng: lng, heading: heading, speed: speed);
});
_locationService!.start();
}
/// إيقاف تتبع الموقع.
void _stopLocationTracking() {
_locationService?.stop();
_locationService = null;
_heartbeatTimer?.cancel();
_heartbeatTimer = null;
}
@override
Future<void> close() {
_stopLocationTracking();
return super.close();
}
}