Update: 2026-06-14 22:10:07

This commit is contained in:
Hamza-Ayed
2026-06-14 22:10:08 +03:00
parent 8e3b9eca4d
commit f021ba5a35
21 changed files with 3669 additions and 636 deletions

View File

@@ -82,7 +82,7 @@ class CountryLogic {
/// Helper to format phone using the current country in box.
static String formatCurrentCountryPhone(String phone) {
String cleanPhone = phone.replaceAll(RegExp(r'[ \-\(\)\+]'), '').trim();
// 1. Explicit International Code Detection
if (cleanPhone.startsWith('00963')) {
cleanPhone = cleanPhone.replaceFirst('00963', '963');

View File

@@ -172,6 +172,7 @@ class RideLifecycleController extends GetxController {
bool _isCancelProcessed = false;
bool _isAcceptanceProcessed = false;
bool _isRatingScreenOpen = false;
bool _isReviewProcessed = false; // 🛡️ Gatekeeper لمنع فتح التقييم مرتين
bool _isRecalculatingRoute = false;
String _rideAcceptedViaSource = "Unknown";
@@ -652,10 +653,18 @@ class RideLifecycleController extends GetxController {
}
Future<void> _checkLastRideForReview() async {
// 🛡️ Gatekeeper: منع فتح التقييم مرتين (Race Condition)
if (_isReviewProcessed) {
Log.print("✋ _checkLastRideForReview: Already processed. Skipping.");
return;
}
_isReviewProcessed = true;
Log.print('⭐ FORCE OPEN RATING PAGE (Get.to mode)');
await getRideStatusFromStartApp();
if (rideStatusFromStartApp['data'] == null) {
_isReviewProcessed = false;
currentRideState.value = RideState.noRide;
startMasterTimer();
return;
@@ -1183,6 +1192,13 @@ class RideLifecycleController extends GetxController {
}
Future<void> tripFinishedFromDriver() async {
// 🛑 Race Condition Guard: إذا تمت معالجتها مسبقاً، تخطى فوراً
if (_isFinishProcessed) {
Log.print("✋ tripFinishedFromDriver: Already processed. Skipping.");
return;
}
_isFinishProcessed = true;
Log.print('🧹 Cleaning UI for Finish');
if (Get.isDialogOpen == true) Get.back();
if (Get.isBottomSheetOpen == true) Get.back();
@@ -1692,8 +1708,7 @@ class RideLifecycleController extends GetxController {
box.write(BoxName.countryCode, newCountry);
box.write(BoxName.serverChosen, AppLink.server);
if (newCountry != previousCountry) {
}
if (newCountry != previousCountry) {}
return newCountry;
}
@@ -1773,11 +1788,12 @@ class RideLifecycleController extends GetxController {
void applyPromoCodeToPassenger(BuildContext context) async {
if (promoTaken == true) {
MyDialog().getDialog('Promo Already Used'.tr, 'You have already used this promo code.'.tr, () => Get.back());
MyDialog().getDialog('Promo Already Used'.tr,
'You have already used this promo code.'.tr, () => Get.back());
return;
}
if (!promoFormKey.currentState!.validate()) return;
try {
final res = await CRUD().post(link: AppLink.getPrices, payload: {
'distance': distance.toString(),
@@ -1791,7 +1807,7 @@ class RideLifecycleController extends GetxController {
'walletVal': box.read(BoxName.passengerWalletTotal)?.toString() ?? '0',
'activeMenuWaypointCount': activeMenuWaypointCount.toString(),
'promo_code': promo.text,
'passenger_id' :box.read(BoxName.passengerID),
'passenger_id': box.read(BoxName.passengerID),
'country': box.read(BoxName.countryCode) ?? '',
});
@@ -1800,29 +1816,40 @@ class RideLifecycleController extends GetxController {
if (response['status'] == 'success') {
var data = response['data'];
totalPassengerSpeed = data['totalPassengerSpeed']?.toString() ?? '0';
totalPassengerBalash = data['totalPassengerBalash']?.toString() ?? '0';
totalPassengerComfort = data['totalPassengerComfort']?.toString() ?? '0';
totalPassengerElectric = data['totalPassengerElectric']?.toString() ?? '0';
totalPassengerBalash =
data['totalPassengerBalash']?.toString() ?? '0';
totalPassengerComfort =
data['totalPassengerComfort']?.toString() ?? '0';
totalPassengerElectric =
data['totalPassengerElectric']?.toString() ?? '0';
totalPassengerLady = data['totalPassengerLady']?.toString() ?? '0';
totalPassengerScooter = data['totalPassengerScooter']?.toString() ?? '0';
totalPassengerScooter =
data['totalPassengerScooter']?.toString() ?? '0';
totalPassengerVan = data['totalPassengerVan']?.toString() ?? '0';
totalPassengerRayehGai = data['totalPassengerRayehGai']?.toString() ?? '0';
totalPassengerRayehGaiComfort = data['totalPassengerRayehGaiComfort']?.toString() ?? '0';
totalPassengerRayehGaiBalash = data['totalPassengerRayehGaiBalash']?.toString() ?? '0';
totalPassengerRayehGai =
data['totalPassengerRayehGai']?.toString() ?? '0';
totalPassengerRayehGaiComfort =
data['totalPassengerRayehGaiComfort']?.toString() ?? '0';
totalPassengerRayehGaiBalash =
data['totalPassengerRayehGaiBalash']?.toString() ?? '0';
promoTaken = true;
update();
Confetti.launch(
context,
options: const ConfettiOptions(particleCount: 100, spread: 70, y: 0.6),
options:
const ConfettiOptions(particleCount: 100, spread: 70, y: 0.6),
);
} else {
MyDialog().getDialog('Promo Error'.tr, response['message']?.toString() ?? 'Invalid Promo'.tr, () => Get.back());
MyDialog().getDialog(
'Promo Error'.tr,
response['message']?.toString() ?? 'Invalid Promo'.tr,
() => Get.back());
return;
}
}
Get.back();
Get.back();
await Future.delayed(const Duration(milliseconds: 120));
} catch (e) {
Get.snackbar('Error'.tr, e.toString(),
@@ -1866,16 +1893,23 @@ class RideLifecycleController extends GetxController {
if (response['status'] == 'success') {
var data = response['data'];
totalPassengerSpeed = data['totalPassengerSpeed']?.toString() ?? '0';
totalPassengerBalash = data['totalPassengerBalash']?.toString() ?? '0';
totalPassengerComfort = data['totalPassengerComfort']?.toString() ?? '0';
totalPassengerElectric = data['totalPassengerElectric']?.toString() ?? '0';
totalPassengerBalash =
data['totalPassengerBalash']?.toString() ?? '0';
totalPassengerComfort =
data['totalPassengerComfort']?.toString() ?? '0';
totalPassengerElectric =
data['totalPassengerElectric']?.toString() ?? '0';
totalPassengerLady = data['totalPassengerLady']?.toString() ?? '0';
totalPassengerScooter = data['totalPassengerScooter']?.toString() ?? '0';
totalPassengerScooter =
data['totalPassengerScooter']?.toString() ?? '0';
totalPassengerVan = data['totalPassengerVan']?.toString() ?? '0';
totalPassengerRayehGai = data['totalPassengerRayehGai']?.toString() ?? '0';
totalPassengerRayehGaiComfort = data['totalPassengerRayehGaiComfort']?.toString() ?? '0';
totalPassengerRayehGaiBalash = data['totalPassengerRayehGaiBalash']?.toString() ?? '0';
totalPassengerRayehGai =
data['totalPassengerRayehGai']?.toString() ?? '0';
totalPassengerRayehGaiComfort =
data['totalPassengerRayehGaiComfort']?.toString() ?? '0';
totalPassengerRayehGaiBalash =
data['totalPassengerRayehGaiBalash']?.toString() ?? '0';
totalPassenger = totalPassengerSpeed;
totalCostPassenger = totalPassenger;
}
@@ -3907,8 +3941,7 @@ class RideLifecycleController extends GetxController {
}
Future<void> _stagePricingAndState() async {
try {
} catch (e) {
try {} catch (e) {
Log.print("Error: $e");
}
try {
@@ -4259,6 +4292,7 @@ class RideLifecycleController extends GetxController {
mapEngine.update();
update();
}
initilizeGetStorage() async {
if (box.read(BoxName.addWork) == null) {
box.write(BoxName.addWork, 'addWork');
@@ -4322,5 +4356,4 @@ class RideLifecycleController extends GetxController {
);
}
}
}

View File

@@ -13,6 +13,7 @@ import 'package:siro_rider/main.dart';
import 'package:siro_rider/views/widgets/mycircular.dart';
import '../../../constant/style.dart';
import '../../../controller/functions/country_logic.dart';
import '../../../controller/functions/log_out.dart';
// ─────────────────────────────────────────────────────────────────────────────
@@ -721,9 +722,14 @@ class _PassengerProfilePageState extends State<PassengerProfilePage> {
_sheetSaveButton(
onPressed: () async {
Get.back();
// لو الحقل هو sosPhone، قم بتنسيق الرقم حسب الدولة الحالية
String value = tempCtrl.text.trim();
if (fieldKey == 'sosPhone' && value.isNotEmpty) {
value = CountryLogic.formatCurrentCountryPhone(value);
}
await controller.updateColumn({
'id': box.read(BoxName.passengerID).toString(),
fieldKey: tempCtrl.text.trim(),
fieldKey: value,
});
onSaved?.call();
},