2026-04-03-maplibra come next

This commit is contained in:
Hamza-Ayed
2026-04-03 16:23:14 +03:00
parent c6b27d06d4
commit e325405dff
13 changed files with 363 additions and 830 deletions

View File

@@ -45,7 +45,7 @@ import '../../main.dart';
import '../../models/model/locations.dart';
import '../../models/model/painter_copoun.dart';
import '../../print.dart';
import '../../services/ride_tracking_native.dart';
import '../../services/pip_service.dart';
import '../../views/home/map_widget.dart/cancel_raide_page.dart';
import '../../views/home/map_widget.dart/car_details_widget_to_go.dart';
import '../../views/home/map_widget.dart/select_driver_mishwari.dart';
@@ -357,49 +357,83 @@ class MapPassengerController extends GetxController {
.setTransports(['websocket'])
.disableAutoConnect()
.setQuery({'id': passengerId})
// ✅ [FIX] إعادة اتصال شبه-لانهائية (999 محاولة) بدلاً من 20
.setReconnectionAttempts(20)
.setReconnectionDelay(2400)
// ✅ أضف هذا السطر لحل مشكلة الـ Heartbeat مع PHPSocketIO
// ✅ [FIX] تأخير أقل (1.5 ثانية) مع حد أقصى (8 ثواني) للتسريع
.setReconnectionDelay(1500)
.setReconnectionDelayMax(8000)
.enableReconnection()
.setExtraHeaders({'Connection': 'Upgrade'})
.build(),
);
socket.connect();
// ✅ إضافة النبضة (Heartbeat) لمنع السيرفر من قطع الاتصال
_heartbeatTimer?.cancel(); // إيقاف أي نبضة قديمة
_heartbeatTimer = Timer.periodic(const Duration(seconds: 25), (timer) {
if (isSocketConnected && socket != null && socket!.connected) {
socket!.emit('heartbeat', {'passenger_id': passengerId});
// Log.print("💓 Socket Heartbeat sent"); // اختياري للتأكد أنه يعمل
} else {
timer.cancel(); // إيقاف النبضة إذا انقطع السوكيت
}
});
// ✅ معالج الاتصال
// ✅ معالج الاتصال الأول
socket.onConnect((_) {
Log.print("✅ Socket Connected Successfully");
isSocketConnected = true;
_reconnectAttempts = 0;
_startHeartbeat(); // ← أضف هذا
_startHeartbeat();
// ✅ [FIX] الاشتراك مجدداً في أحداث الرحلة عند كل اتصال
if (rideId != null && rideId != 'yet' && driverId.isNotEmpty) {
socket.emit('subscribe_driver_location', {
'ride_id': rideId,
'driver_id': driverId,
});
Log.print("📡 Re-subscribed to driver location after connect");
}
update();
});
// دالة منفصلة للـ heartbeat
// ⚠️ معالج الانقطاع
socket.onDisconnect((_) {
Log.print("⚠️ Socket Disconnected");
Log.print("⚠️ Socket Disconnected — Auto-Reconnect will handle it");
isSocketConnected = false;
// تفعيل Polling أسرع كـ Fallback
// تفعيل Polling أسرع كـ Fallback مؤقت (سيتم إيقافه عند عودة الاتصال)
if (_isActiveRideState()) {
Log.print("🔄 Switching to Fast Polling Mode (6s interval)");
Log.print("🔄 Enabling Fast Polling Fallback (4s) until reconnect...");
_startMasterTimerWithInterval(4);
}
update();
});
// 🔁 [FIX] معالج إعادة الاتصال الناجحة
socket.onReconnect((_) {
Log.print("🔁 Socket Reconnected Successfully!");
isSocketConnected = true;
_reconnectAttempts = 0;
// استئناف النبضة فوراً
_startHeartbeat();
// إعادة الاشتراك في أحداث الرحلة
if (rideId != null && rideId != 'yet' && driverId.isNotEmpty) {
socket.emit('subscribe_driver_location', {
'ride_id': rideId,
'driver_id': driverId,
});
Log.print("📡 Re-subscribed to driver location after reconnect");
}
// ✅ [FIX] إيقاف الـ Fast Polling لأن السوكيت عاد
if (_isActiveRideState()) {
Log.print("✅ Socket back online — stopping Fast Polling Fallback");
_masterTimer?.cancel();
_masterTimer = null;
}
update();
});
// 🔄 [FIX] معالج محاولات إعادة الاتصال (للتشخيص)
socket.onReconnectAttempt((attemptNumber) {
Log.print("🔄 Socket Reconnect Attempt #$attemptNumber...");
});
// ❌ معالج الأخطاء
socket.onError((error) {
Log.print("❌ Socket Error: $error");
@@ -724,6 +758,7 @@ class MapPassengerController extends GetxController {
if (Get.isDialogOpen == true) Get.back();
await RideLiveNotification.cancel();
IosLiveActivityService.endRideActivity(); // ✅ أضف هذا السطر
PipService.disablePip(); // ✅ إيقاف PiP عند انتهاء الرحلة
if (Get.isDialogOpen == true) Get.back();
await RideLiveNotification.cancel();
Get.defaultDialog(
@@ -771,6 +806,7 @@ class MapPassengerController extends GetxController {
stopAllTimers();
await RideLiveNotification.cancel();
IosLiveActivityService.endRideActivity(); // ✅ أضف هذا السطر
PipService.disablePip(); // ✅ إيقاف PiP
_isCancelProcessed = false;
currentRideState.value = RideState.noRide;
resetAllMapStates();
@@ -959,6 +995,7 @@ class MapPassengerController extends GetxController {
'tone1',
);
IosLiveActivityService.endRideActivity();
PipService.disablePip(); // ✅ إيقاف PiP
await RideLiveNotification.cancel();
// 5. استخراج البيانات والانتقال
if (driverList.length >= 4) {
@@ -1272,20 +1309,24 @@ class MapPassengerController extends GetxController {
timeToPassengerFromDriverAfterApplied; // مثلاً من السيرفر
final double distanceDriverToPassengerMeters =
double.parse(distanceByPassenger);
await RideTrackingNative.updateRideTracking(
driverName: driverName,
driverPhone: driverPhone,
carDetails: '$make$carColor$licensePlate',
driverLat: driverCarsLocationToPassengerAfterApplied.last.latitude,
driverLng: driverCarsLocationToPassengerAfterApplied.last.longitude,
passengerLat: passengerLocation.latitude,
passengerLng: passengerLocation.longitude,
destLat: myDestination.latitude,
destLng: myDestination.longitude,
rideState: 'waiting', // يعني السائق بالطريق للراكب
estimatedTimeMinutes: (timeToPassengerSeconds / 60).round(),
totalDistanceMeters: distanceDriverToPassengerMeters,
);
// [PiP] تم تعطيل الإشعار المستمر القديم (Foreground Service) واستبداله بـ PiP
// await RideTrackingNative.updateRideTracking(
// driverName: driverName,
// driverPhone: driverPhone,
// carDetails: '$make • $carColor • $licensePlate',
// driverLat: driverCarsLocationToPassengerAfterApplied.last.latitude,
// driverLng: driverCarsLocationToPassengerAfterApplied.last.longitude,
// passengerLat: passengerLocation.latitude,
// passengerLng: passengerLocation.longitude,
// destLat: myDestination.latitude,
// destLng: myDestination.longitude,
// rideState: 'waiting',
// estimatedTimeMinutes: (timeToPassengerSeconds / 60).round(),
// totalDistanceMeters: distanceDriverToPassengerMeters,
// );
// [PiP] تفعيل PiP عند بدء الرحلة (سيدخل وضع النافذة العائمة عند خروج المستخدم)
PipService.enablePip();
// 6. بدء تتبع الموقع الدوري (Polling Backup + Smart Rerouting)
// سيبدأ العمل بعد 6 ثواني
@@ -1918,21 +1959,21 @@ class MapPassengerController extends GetxController {
durationToRide; // موجود عندك من التايمر
final double totalDistanceMeters = double.parse(distanceByPassenger);
// 2) استدعاء خدمة الأندرويد لتحديث الإشعار لحالة "inProgress"
await RideTrackingNative.updateRideTracking(
driverName: driverName,
driverPhone: driverPhone,
carDetails: carDetails,
driverLat: driverLat,
driverLng: driverLng,
passengerLat: passengerLat,
passengerLng: passengerLng,
destLat: destLat,
destLng: destLng,
rideState: 'inProgress',
estimatedTimeMinutes: (timeToDestinationSeconds / 60).round(),
totalDistanceMeters: totalDistanceMeters,
);
// [PiP] تم تعطيل الإشعار المستمر القديم (Foreground Service) واستبداله بـ PiP
// await RideTrackingNative.updateRideTracking(
// driverName: driverName,
// driverPhone: driverPhone,
// carDetails: carDetails,
// driverLat: driverLat,
// driverLng: driverLng,
// passengerLat: passengerLat,
// passengerLng: passengerLng,
// destLat: destLat,
// destLng: destLng,
// rideState: 'inProgress',
// estimatedTimeMinutes: (timeToDestinationSeconds / 60).round(),
// totalDistanceMeters: totalDistanceMeters,
// );
// 3) بدء التايمر الداخلي الخاص بك (للـ ETA داخل التطبيق نفسه)
rideIsBeginPassengerTimer();
@@ -4894,6 +4935,7 @@ Intaleq Team''';
currentRideState.value = RideState.cancelled;
await RideLiveNotification.cancel(); // إغلاق أندرويد
IosLiveActivityService.endRideActivity(); // ✅ إغلاق iOS
PipService.disablePip(); // ✅ إيقاف PiP عند الإلغاء
// 4. الاتصال بالسيرفر لإلغاء الرحلة وإبلاغ السائق
if (rideId != 'yet' && rideId != null) {