|
|
|
|
@@ -1,6 +1,7 @@
|
|
|
|
|
import 'dart:async';
|
|
|
|
|
import 'package:Intaleq/services/offline_map_service.dart';
|
|
|
|
|
import 'package:Intaleq/services/emergency_signal_service.dart';
|
|
|
|
|
import 'package:Intaleq/views/widgets/mycircular.dart';
|
|
|
|
|
import 'dart:convert';
|
|
|
|
|
import 'dart:io';
|
|
|
|
|
import 'dart:math' show Random, atan2, cos, max, min, pi, pow, sin, sqrt;
|
|
|
|
|
@@ -1517,17 +1518,17 @@ class MapPassengerController extends GetxController {
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RideState.searching:
|
|
|
|
|
// effectivePollingInterval = 5;
|
|
|
|
|
|
|
|
|
|
// 1. التحقق من حالة الطلب (هل قبله أحد؟)
|
|
|
|
|
try {
|
|
|
|
|
String statusFromServer = await getRideStatus(rideId);
|
|
|
|
|
if (statusFromServer == 'Apply' || statusFromServer == 'Applied') {
|
|
|
|
|
await processRideAcceptance(source: "Polling");
|
|
|
|
|
break;
|
|
|
|
|
// 1. التحقق من حالة الطلب (هل قبله أحد؟) عبر البولينج فقط إذا كان السوكيت غير متصل
|
|
|
|
|
if (!isSocketConnected) {
|
|
|
|
|
try {
|
|
|
|
|
String statusFromServer = await getRideStatus(rideId);
|
|
|
|
|
if (statusFromServer == 'Apply' || statusFromServer == 'Applied') {
|
|
|
|
|
await processRideAcceptance(source: "Polling");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print('Error polling getRideStatus: $e');
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print('Error polling getRideStatus: $e');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final now = DateTime.now();
|
|
|
|
|
@@ -1587,18 +1588,21 @@ class MapPassengerController extends GetxController {
|
|
|
|
|
rideAppliedFromDriver(true);
|
|
|
|
|
_isDriverAppliedLogicExecuted = true;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
String statusFromServer = await getRideStatus(rideId);
|
|
|
|
|
if (statusFromServer == 'Arrived') {
|
|
|
|
|
currentRideState.value = RideState.driverArrived;
|
|
|
|
|
break;
|
|
|
|
|
} else if (statusFromServer == 'Begin' ||
|
|
|
|
|
statusFromServer == 'inProgress') {
|
|
|
|
|
processRideBegin();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (!isSocketConnected) {
|
|
|
|
|
try {
|
|
|
|
|
String statusFromServer = await getRideStatus(rideId);
|
|
|
|
|
if (statusFromServer == 'Arrived') {
|
|
|
|
|
currentRideState.value = RideState.driverArrived;
|
|
|
|
|
break;
|
|
|
|
|
} else if (statusFromServer == 'Begin' ||
|
|
|
|
|
statusFromServer == 'inProgress') {
|
|
|
|
|
processRideBegin();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print('Error polling for Arrived/Begin status: $e');
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print('Error polling for Arrived/Begin status: $e');
|
|
|
|
|
}
|
|
|
|
|
getDriverCarsLocationToPassengerAfterApplied();
|
|
|
|
|
break;
|
|
|
|
|
@@ -1615,31 +1619,33 @@ class MapPassengerController extends GetxController {
|
|
|
|
|
case RideState.inProgress:
|
|
|
|
|
// effectivePollingInterval = 6;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
String statusFromServer = await getRideStatus(rideId);
|
|
|
|
|
if (!isSocketConnected) {
|
|
|
|
|
try {
|
|
|
|
|
String statusFromServer = await getRideStatus(rideId);
|
|
|
|
|
|
|
|
|
|
// !!! هنا التغيير الجذري !!!
|
|
|
|
|
if (statusFromServer == 'Finished' ||
|
|
|
|
|
statusFromServer == 'finished') {
|
|
|
|
|
Log.print(
|
|
|
|
|
'🏁 DETECTED FINISHED: Killing processes and forcing Review.');
|
|
|
|
|
// !!! هنا التغيير الجذري !!!
|
|
|
|
|
if (statusFromServer == 'Finished' ||
|
|
|
|
|
statusFromServer == 'finished') {
|
|
|
|
|
Log.print(
|
|
|
|
|
'🏁 DETECTED FINISHED: Killing processes and forcing Review.');
|
|
|
|
|
|
|
|
|
|
// 1. قتل العمليات فوراً
|
|
|
|
|
stopAllTimers();
|
|
|
|
|
// 1. قتل العمليات فوراً
|
|
|
|
|
stopAllTimers();
|
|
|
|
|
|
|
|
|
|
// 2. تغيير الحالة الداخلية لمنع أي كود آخر من العمل
|
|
|
|
|
currentRideState.value = RideState.preCheckReview;
|
|
|
|
|
// 2. تغيير الحالة الداخلية لمنع أي كود آخر من العمل
|
|
|
|
|
currentRideState.value = RideState.preCheckReview;
|
|
|
|
|
|
|
|
|
|
// 3. تنظيف الواجهة
|
|
|
|
|
tripFinishedFromDriver();
|
|
|
|
|
// 3. تنظيف الواجهة
|
|
|
|
|
tripFinishedFromDriver();
|
|
|
|
|
|
|
|
|
|
// 4. استدعاء شاشة التقييم فوراً
|
|
|
|
|
_checkLastRideForReview();
|
|
|
|
|
// 4. استدعاء شاشة التقييم فوراً
|
|
|
|
|
_checkLastRideForReview();
|
|
|
|
|
|
|
|
|
|
return; // خروج نهائي من الدالة لمنع أي كود بالأسفل من التنفيذ
|
|
|
|
|
return; // خروج نهائي من الدالة لمنع أي كود بالأسفل من التنفيذ
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print('Error polling status: $e');
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print('Error polling status: $e');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// بقية كود التتبع العادي (لن يتم الوصول إليه إذا انتهت الرحلة)
|
|
|
|
|
@@ -2906,8 +2912,17 @@ class MapPassengerController extends GetxController {
|
|
|
|
|
isStartAppHasRide = false;
|
|
|
|
|
Log.print(
|
|
|
|
|
"No rides found for the given passenger ID within the last hour.");
|
|
|
|
|
} else {
|
|
|
|
|
var decoded = jsonDecode(res);
|
|
|
|
|
if (decoded['status'] == 'failure') {
|
|
|
|
|
rideStatusFromStartApp = {
|
|
|
|
|
'data': {'status': 'NoRide', 'needsReview': false}
|
|
|
|
|
};
|
|
|
|
|
isStartAppHasRide = false;
|
|
|
|
|
} else {
|
|
|
|
|
rideStatusFromStartApp = decoded;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rideStatusFromStartApp = jsonDecode(res);
|
|
|
|
|
if (rideStatusFromStartApp['data']['status'] == 'Begin' ||
|
|
|
|
|
rideStatusFromStartApp['data']['status'] == 'Apply' ||
|
|
|
|
|
rideStatusFromStartApp['data']['status'] == 'Applied') {
|
|
|
|
|
@@ -6020,35 +6035,58 @@ Intaleq Team''';
|
|
|
|
|
Log.print(
|
|
|
|
|
'🔔 showDrawingBottomSheet called. isDrawingRoute: $isDrawingRoute');
|
|
|
|
|
|
|
|
|
|
// استخدام addPostFrameCallback لضمان ظهور الإشعار بعد انتهاء بناء الإطار
|
|
|
|
|
final context = Get.context;
|
|
|
|
|
if (context == null) return;
|
|
|
|
|
|
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
|
|
Get.rawSnackbar(
|
|
|
|
|
titleText: Text(
|
|
|
|
|
'Drawing route on map...'.tr,
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
// إغلاق أي سناك بار مفتوح حالياً لتجنب التكرار
|
|
|
|
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
|
|
|
|
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
|
SnackBar(
|
|
|
|
|
content: Row(
|
|
|
|
|
children: [
|
|
|
|
|
const SizedBox(
|
|
|
|
|
width: 24,
|
|
|
|
|
height: 24,
|
|
|
|
|
child: MyCircularProgressIndicator(),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 16),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
'Drawing route on map...'.tr,
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 4),
|
|
|
|
|
Text(
|
|
|
|
|
'Please wait while we prepare your trip.'.tr,
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
color: Colors.white70,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
messageText: Text(
|
|
|
|
|
'Please wait while we prepare your trip.'.tr,
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
color: Colors.white70,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
backgroundColor: AppColor.primaryColor.withOpacity(0.95),
|
|
|
|
|
duration: const Duration(seconds: 3),
|
|
|
|
|
behavior: SnackBarBehavior.floating,
|
|
|
|
|
margin: const EdgeInsets.fromLTRB(16, 0, 16, 110),
|
|
|
|
|
shape: RoundedRectangleBorder(
|
|
|
|
|
borderRadius: BorderRadius.circular(16),
|
|
|
|
|
),
|
|
|
|
|
elevation: 8,
|
|
|
|
|
),
|
|
|
|
|
showProgressIndicator: true,
|
|
|
|
|
progressIndicatorBackgroundColor: Colors.white24,
|
|
|
|
|
progressIndicatorValueColor:
|
|
|
|
|
const AlwaysStoppedAnimation<Color>(Colors.white),
|
|
|
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
|
|
|
backgroundColor: AppColor.primaryColor.withOpacity(0.9),
|
|
|
|
|
duration: const Duration(seconds: 3),
|
|
|
|
|
margin: const EdgeInsets.fromLTRB(16, 0, 16, 110),
|
|
|
|
|
borderRadius: 16,
|
|
|
|
|
icon: const Icon(Icons.map_outlined, color: Colors.white),
|
|
|
|
|
isDismissible: true,
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
@@ -7484,16 +7522,22 @@ Intaleq Team''';
|
|
|
|
|
);
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
var json = jsonDecode(res);
|
|
|
|
|
kazan = double.parse(json['message'][0]['kazan']);
|
|
|
|
|
naturePrice = double.parse(json['message'][0]['naturePrice']);
|
|
|
|
|
heavyPrice = double.parse(json['message'][0]['heavyPrice']);
|
|
|
|
|
latePrice = double.parse(json['message'][0]['latePrice']);
|
|
|
|
|
comfortPrice = double.parse(json['message'][0]['comfortPrice']);
|
|
|
|
|
speedPrice = double.parse(json['message'][0]['speedPrice']);
|
|
|
|
|
deliveryPrice = double.parse(json['message'][0]['deliveryPrice']);
|
|
|
|
|
mashwariPrice = double.parse(json['message'][0]['freePrice']);
|
|
|
|
|
familyPrice = double.parse(json['message'][0]['familyPrice']);
|
|
|
|
|
fuelPrice = double.parse(json['message'][0]['fuelPrice']);
|
|
|
|
|
// التحقق الديناميكي من 'data' أو 'message'
|
|
|
|
|
var dataList = json['data'] ?? json['message'];
|
|
|
|
|
|
|
|
|
|
if (dataList != null && dataList is List && dataList.isNotEmpty) {
|
|
|
|
|
var firstRow = dataList[0];
|
|
|
|
|
kazan = double.parse(firstRow['kazan'].toString());
|
|
|
|
|
naturePrice = double.parse(firstRow['naturePrice'].toString());
|
|
|
|
|
heavyPrice = double.parse(firstRow['heavyPrice'].toString());
|
|
|
|
|
latePrice = double.parse(firstRow['latePrice'].toString());
|
|
|
|
|
comfortPrice = double.parse(firstRow['comfortPrice'].toString());
|
|
|
|
|
speedPrice = double.parse(firstRow['speedPrice'].toString());
|
|
|
|
|
deliveryPrice = double.parse(firstRow['deliveryPrice'].toString());
|
|
|
|
|
mashwariPrice = double.parse(firstRow['freePrice'].toString());
|
|
|
|
|
familyPrice = double.parse(firstRow['familyPrice'].toString());
|
|
|
|
|
fuelPrice = double.parse(firstRow['fuelPrice'].toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -7502,7 +7546,8 @@ Intaleq Team''';
|
|
|
|
|
link: AppLink.getPassengerRate,
|
|
|
|
|
payload: {'passenger_id': box.read(BoxName.passengerID)});
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
var message = jsonDecode(res)['message'];
|
|
|
|
|
var json = jsonDecode(res);
|
|
|
|
|
var message = json['data'] ?? json['message'];
|
|
|
|
|
if (message['rating'] == null) {
|
|
|
|
|
passengerRate = 5.0; // Default rating
|
|
|
|
|
} else {
|
|
|
|
|
|