Update: 2026-06-14 05:48:58

This commit is contained in:
Hamza-Ayed
2026-06-14 05:48:58 +03:00
parent 2645ed0cf1
commit 8e3b9eca4d
22 changed files with 789 additions and 179 deletions

View File

@@ -17,6 +17,7 @@ import '../../../constant/colors.dart';
import '../../../views/auth/captin/ai_page.dart';
import '../../../views/auth/syria/registration_view.dart';
import '../../../views/home/Captin/home_captain/home_captin.dart';
import '../../functions/country_logic.dart';
import '../../functions/sms_egypt_controller.dart';
class RegisterCaptainController extends GetxController {
@@ -385,11 +386,13 @@ class RegisterCaptainController extends GetxController {
if (formKey.currentState!.validate()) {
isLoading = true;
update();
final fixedPhone =
CountryLogic.formatCurrentCountryPhone(phoneController.text);
var res = await CRUD().post(link: AppLink.signUpCaptin, payload: {
'first_name': name.split(' ')[1],
'last_name': name.split(' ')[0],
'email': emailController.text,
'phone': phoneController.text,
'phone': fixedPhone,
'password': passwordController.text,
'gender': sex,
'site': address,

View File

@@ -211,9 +211,11 @@ class FirebaseMessagesController extends GetxController {
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'ding', '');
}
MyDialog().getDialog(title, body, () {
// Empty callback, MyDialog already closes itself using pop().
});
MyDialog().getChatDialog(
title.isNotEmpty ? title : 'message From passenger'.tr,
body,
() {},
);
break;
case 'token change':

View File

@@ -83,17 +83,55 @@ class CountryLogic {
/// Helper to format phone using the current country in box.
static String formatCurrentCountryPhone(String phone) {
String cleanPhone = phone.replaceAll(RegExp(r'[ \-\(\)]'), '').trim();
if (cleanPhone.startsWith('+963') || cleanPhone.startsWith('00963')) {
String cleanPhone = phone.replaceAll(RegExp(r'[ \-\(\)\+]'), '').trim();
// 1. Explicit International Code Detection
if (cleanPhone.startsWith('00963')) {
cleanPhone = cleanPhone.replaceFirst('00963', '963');
}
if (cleanPhone.startsWith('00962')) {
cleanPhone = cleanPhone.replaceFirst('00962', '962');
}
if (cleanPhone.startsWith('0020')) {
cleanPhone = cleanPhone.replaceFirst('0020', '20');
}
if (cleanPhone.startsWith('963')) {
return formatPhone(cleanPhone, 'Syria');
}
if (cleanPhone.startsWith('+20') || cleanPhone.startsWith('0020')) {
if (cleanPhone.startsWith('962')) {
return formatPhone(cleanPhone, 'Jordan');
}
if (cleanPhone.startsWith('20')) {
return formatPhone(cleanPhone, 'Egypt');
}
if (cleanPhone.startsWith('+962') || cleanPhone.startsWith('00962')) {
// 2. Local/National Format Detection by Country-Specific Mobile Prefixes
// Jordan: 07x / 7x (9 national digits)
if (cleanPhone.startsWith('07') && cleanPhone.length == 10) {
return formatPhone(cleanPhone, 'Jordan');
}
if (cleanPhone.startsWith('7') && cleanPhone.length == 9) {
return formatPhone(cleanPhone, 'Jordan');
}
// Syria: 09x / 9x (9 national digits)
if (cleanPhone.startsWith('09') && cleanPhone.length == 10) {
return formatPhone(cleanPhone, 'Syria');
}
if (cleanPhone.startsWith('9') && cleanPhone.length == 9) {
return formatPhone(cleanPhone, 'Syria');
}
// Egypt: 01x (10 national digits) / 1x (9 national digits)
if (cleanPhone.startsWith('01') && cleanPhone.length == 11) {
return formatPhone(cleanPhone, 'Egypt');
}
if (cleanPhone.startsWith('1') && cleanPhone.length == 10) {
return formatPhone(cleanPhone, 'Egypt');
}
// 3. Fallback: Default to current user's country code saved in box
final country = box.read(BoxName.countryCode) ?? 'Syria';
return formatPhone(cleanPhone, country);
}

View File

@@ -0,0 +1,30 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
class TranslateHelper {
static Future<String> translateText(String text, String targetLang) async {
if (text.isEmpty) return text;
try {
final url = Uri.parse(
'https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=$targetLang&dt=t&q=${Uri.encodeComponent(text)}'
);
final response = await http.get(url);
if (response.statusCode == 200) {
final decoded = jsonDecode(response.body);
if (decoded != null && decoded is List && decoded.isNotEmpty && decoded[0] is List) {
final List parts = decoded[0];
String translated = '';
for (var part in parts) {
if (part is List && part.isNotEmpty) {
translated += part[0].toString();
}
}
return translated;
}
}
} catch (e) {
// Fallback to original text on any exception
}
return text;
}
}

View File

@@ -67,12 +67,16 @@ class OrderRequestController extends GetxController
String timeToPassenger = "Calculating...".tr;
String distanceToPassenger = "--";
String apiStartName = "";
String apiEndName = "";
// --- الخريطة ---
Set<Polyline> polylines = {};
bool _hasCalculatedFullJourney = false;
// حالة التطبيق والصوت
bool isInBackground = false;
bool isAccepting = false;
final AudioPlayer audioPlayer = AudioPlayer();
@override
@@ -288,6 +292,15 @@ class OrderRequestController extends GetxController
totalTripDuration = tripResult['duration_text'];
polylines.add(tripResult['polyline']);
if (tripResult['start_name'] != null &&
tripResult['start_name'].toString().isNotEmpty) {
apiStartName = tripResult['start_name'].toString();
}
if (tripResult['end_name'] != null &&
tripResult['end_name'].toString().isNotEmpty) {
apiEndName = tripResult['end_name'].toString();
}
// 🔥 تخزين استجابة السيرفر كاملة (بما فيها الـ points والـ instructions)
if (tripResult['raw_response'] != null) {
box.write('cached_trip_route', tripResult['raw_response']);
@@ -385,6 +398,8 @@ class OrderRequestController extends GetxController
'duration_text': durationText,
'polyline': polyline,
'encoded_polyline': encodedPoints,
'start_name': data['startName']?.toString(),
'end_name': data['endName']?.toString(),
'raw_response': response.body, // 🔥 نمرر الـ JSON كاملاً
};
}
@@ -618,91 +633,102 @@ class OrderRequestController extends GetxController
// Accept Order Logic
Future<void> acceptOrder() async {
if (isAccepting) return;
isAccepting = true;
update();
endTimer();
_stopAudio();
// 1. إرسال الطلب
var res = await CRUD()
.post(link: "${AppLink.ride}/rides/acceptRide.php", payload: {
'id': _safeGet(16),
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'passengerToken': _safeGet(9),
'driver_id': box.read(BoxName.driverID),
});
Log.print('res from orderrequestpage: ${res}');
// ============================================================
// تصحيح: فحص الرد بدقة (Map أو String)
// ============================================================
bool isFailure = false;
if (res is Map && res['status'] == 'failure') {
isFailure = true;
} else if (res == 'failure') {
isFailure = true;
}
if (isFailure) {
// ⛔ حالة الفشل: الطلب مأخوذ
MyDialog().getDialog(
"Sorry, the order was taken by another driver.".tr, '', () {
// بما أن MyDialog يغلق نفسه الآن، نحتاج Get.back() واحدة فقط لإغلاق صفحة الطلب
Get.back();
try {
// 1. إرسال الطلب
var res = await CRUD()
.post(link: "${AppLink.ride}/rides/acceptRide.php", payload: {
'id': _safeGet(16),
'rideTimeStart': DateTime.now().toString(),
'status': 'Apply',
'passengerToken': _safeGet(9),
'driver_id': box.read(BoxName.driverID),
});
} else {
// ✅ حالة النجاح
// حماية من الكراش: التأكد من وجود HomeCaptainController قبل استخدامه
if (!Get.isRegistered<HomeCaptainController>()) {
Get.put(HomeCaptainController());
} else {
Get.find<HomeCaptainController>().changeRideId();
Log.print('res from orderrequestpage: ${res}');
// ============================================================
// تصحيح: فحص الرد بدقة (Map أو String)
// ============================================================
bool isFailure = false;
if (res is Map && res['status'] == 'failure') {
isFailure = true;
} else if (res == 'failure') {
isFailure = true;
}
box.write(BoxName.statusDriverLocation, 'on');
changeApplied();
if (isFailure) {
// ⛔ حالة الفشل: الطلب مأخوذ
MyDialog().getDialog(
"Sorry, the order was taken by another driver.".tr, '', () {
// بما أن MyDialog يغلق نفسه الآن، نحتاج Get.back() واحدة فقط لإغلاق صفحة الطلب
Get.back();
});
} else {
// ✅ حالة النجاح
var rideArgs = {
'passengerLocation': '${_safeGet(0)},${_safeGet(1)}',
'passengerDestination': '${_safeGet(3)},${_safeGet(4)}',
'Duration': totalTripDuration,
'totalCost': _safeGet(26),
'Distance': totalTripDistance,
'name': _safeGet(8),
'phone': _safeGet(10),
'email': _safeGet(28),
'WalletChecked': _safeGet(13),
'tokenPassenger': _safeGet(9),
'direction':
'https://www.google.com/maps/dir/${_safeGet(0)}/${_safeGet(1)}/',
'DurationToPassenger': timeToPassenger,
'rideId': _safeGet(16),
'passengerId': _safeGet(7),
'driverId': _safeGet(18),
'durationOfRideValue': totalTripDuration,
'paymentAmount': _safeGet(2),
'paymentMethod': _safeGet(13) == 'true' ? 'visa' : 'cash',
'isHaveSteps': _safeGet(20),
'step0': _safeGet(21),
'step1': _safeGet(22),
'step2': _safeGet(23),
'step3': _safeGet(24),
'step4': _safeGet(25),
'passengerWalletBurc': _safeGet(26),
'timeOfOrder': DateTime.now().toString(),
'totalPassenger': _safeGet(2),
'carType': _safeGet(31),
'kazan': _safeGet(32),
'startNameLocation': _safeGet(29),
'endNameLocation': _safeGet(30),
};
// حماية من الكراش: التأكد من وجود HomeCaptainController قبل استخدامه
if (!Get.isRegistered<HomeCaptainController>()) {
Get.put(HomeCaptainController());
} else {
Get.find<HomeCaptainController>().changeRideId();
}
box.write(BoxName.rideArguments, rideArgs);
box.write(BoxName.statusDriverLocation, 'on');
changeApplied();
// الانتقال النهائي
Get.off(() => PassengerLocationMapPage(), arguments: rideArgs);
var rideArgs = {
'passengerLocation': '${_safeGet(0)},${_safeGet(1)}',
'passengerDestination': '${_safeGet(3)},${_safeGet(4)}',
'Duration': totalTripDuration,
'totalCost': _safeGet(26),
'Distance': totalTripDistance,
'name': _safeGet(8),
'phone': _safeGet(10),
'email': _safeGet(28),
'WalletChecked': _safeGet(13),
'tokenPassenger': _safeGet(9),
'direction':
'https://www.google.com/maps/dir/${_safeGet(0)}/${_safeGet(1)}/',
'DurationToPassenger': timeToPassenger,
'rideId': _safeGet(16),
'passengerId': _safeGet(7),
'driverId': _safeGet(18),
'durationOfRideValue': totalTripDuration,
'paymentAmount': _safeGet(2),
'paymentMethod': _safeGet(13) == 'true' ? 'visa' : 'cash',
'isHaveSteps': _safeGet(20),
'step0': _safeGet(21),
'step1': _safeGet(22),
'step2': _safeGet(23),
'step3': _safeGet(24),
'step4': _safeGet(25),
'passengerWalletBurc': _safeGet(26),
'timeOfOrder': DateTime.now().toString(),
'totalPassenger': _safeGet(2),
'carType': _safeGet(31),
'kazan': _safeGet(32),
'startNameLocation': _safeGet(29),
'endNameLocation': _safeGet(30),
};
box.write(BoxName.rideArguments, rideArgs);
// الانتقال النهائي
Get.off(() => PassengerLocationMapPage(), arguments: rideArgs);
}
} catch (e) {
Log.print("Error in acceptOrder: $e");
} finally {
isAccepting = false;
update();
}
}