Update: 2026-06-14 05:48:58
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
30
siro_driver/lib/controller/functions/translate_helper.dart
Normal file
30
siro_driver/lib/controller/functions/translate_helper.dart
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user