Update: 2026-06-12 22:40:40

This commit is contained in:
Hamza-Ayed
2026-06-12 22:40:40 +03:00
parent f907212c57
commit 0ae368dbc8
24 changed files with 1197 additions and 303 deletions

View File

@@ -28,6 +28,7 @@ import '../../../views/auth/syria/pending_driver_page.dart';
import '../../firebase/firbase_messge.dart';
import '../../firebase/local_notification.dart';
import '../../firebase/notification_service.dart';
import '../../functions/country_logic.dart';
import '../../functions/encrypt_decrypt.dart';
import '../../functions/package_info.dart';
import '../../functions/secure_storage.dart';
@@ -66,38 +67,39 @@ class LoginDriverController extends GetxController {
@override
void onInit() async {
box.write(BoxName.countryCode, 'Syria');
// كشف الدولة تلقائياً عبر الموقع الجغرافي
await CountryLogic.initializeCountry();
// box.write(BoxName.driverID, '34feffd3fa72d6bee56b');
// await getAppTester();
getJWT();
super.onInit();
}
getAppTester() async {
var res = await CRUD().get(
link: AppLink.getTesterApp,
payload: {'appPlatform': AppInformation.appName});
// Log.print('res: ${res}');
if (res != 'failure') {
var d = jsonDecode(res);
isTest = d['message'][0]['isTest'];
// Log.print('isTest: ${isTest}');
box.write(BoxName.isTest, isTest);
// getAppTester() async {
// var res = await CRUD().get(
// link: AppLink.getTesterApp,
// payload: {'appPlatform': AppInformation.appName});
// // Log.print('res: ${res}');
// if (res != 'failure') {
// var d = jsonDecode(res);
// isTest = d['message'][0]['isTest'];
// // Log.print('isTest: ${isTest}');
// box.write(BoxName.isTest, isTest);
// Log.print('isTest: ${box.read(BoxName.isTest)}');
update();
} else {
isTest = 0;
box.write(BoxName.isTest, isTest);
update();
return false;
}
}
// // Log.print('isTest: ${box.read(BoxName.isTest)}');
// update();
// } else {
// isTest = 0;
// box.write(BoxName.isTest, isTest);
// update();
// return false;
// }
// }
updateAppTester(String appPlatform) async {
await CRUD().post(
link: AppLink.updateTesterApp, payload: {'appPlatform': appPlatform});
}
// updateAppTester(String appPlatform) async {
// await CRUD().post(
// link: AppLink.updateTesterApp, payload: {'appPlatform': appPlatform});
// }
isPhoneVerified() async {
var res = await CRUD().post(
@@ -319,17 +321,14 @@ class LoginDriverController extends GetxController {
}
}
loginWithGoogleCredential(String driverID, email) async {
loginDriver(String driverID, email) async {
isloading = true;
update();
// await SecurityHelper.performSecurityChecks();
// Log.print('(BoxName.emailDriver): ${box.read(BoxName.emailDriver)}');
// await getJWT();
var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: {
// 'email': email ?? 'yet',
'id': driverID,
});
Log.print('loginWithGoogleCredential: ${res}');
var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: {});
Log.print('loginDriver: ${res}');
if (res == 'failure') {
await isPhoneVerified();
isloading = false; // <--- أضفت هذا أيضاً
@@ -478,10 +477,7 @@ class LoginDriverController extends GetxController {
// await SecurityHelper.performSecurityChecks();
// Log.print('(BoxName.emailDriver): ${box.read(BoxName.emailDriver)}');
var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: {
'email': email ?? 'yet',
'id': driverID,
});
var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: {});
// print('res is $res');
// if (res == 'failure') {
@@ -563,32 +559,34 @@ class LoginDriverController extends GetxController {
loginUsingCredentialsWithoutGoogle(String password, email) async {
isloading = true;
isGoogleLogin = true;
update();
var res = await CRUD()
.get(link: AppLink.loginUsingCredentialsWithoutGoogle, payload: {
'email': (email),
'password': password,
});
box.write(BoxName.emailDriver, (email).toString());
// print(res);
if (res == 'failure') {
//Failure
if (box.read(BoxName.phoneVerified).toString() == '1') {
// Get.offAll(() => SyrianCardAI());
Get.offAll(() => RegistrationView());
} else {
Get.offAll(() => SmsSignupEgypt());
}
isloading = false;
update();
} else {
var jsonDecoeded = jsonDecode(res);
var d = jsonDecoeded['data'][0];
if (jsonDecoeded.isNotEmpty) {
if (jsonDecoeded['status'] == 'success' &&
d['is_verified'].toString() == '1') {
try {
var fingerPrint = await DeviceHelper.getDeviceFingerprint();
var payload = {
'email': email,
'password': password,
'fingerPrint': fingerPrint,
'aud': AppInformation.appName,
};
var response = await http.post(
Uri.parse(AppLink.loginUsingCredentialsWithoutGoogle),
body: payload,
);
if (response.statusCode == 200 || response.statusCode == 201) {
var jsonDecoeded = jsonDecode(response.body);
if (jsonDecoeded['status'] == 'success') {
var d = jsonDecoeded['data'][0];
var jwt = jsonDecoeded['jwt'];
// حفظ التوكن أولاً
if (jwt != null) {
box.write(BoxName.jwt, c(jwt));
await storage.write(key: BoxName.jwt, value: c(jwt));
}
box.write(BoxName.emailDriver, (d['email']));
box.write(BoxName.driverID, (d['id']));
box.write(BoxName.isTest, '1');
@@ -602,83 +600,24 @@ class LoginDriverController extends GetxController {
BoxName.nameDriver,
'${(d['first_name'])}'
' ${(d['last_name'])}');
if ((d['model'].toString().contains('دراجه') ||
d['make'].toString().contains('دراجه '))) {
if ((d['gender']).toString() == 'Male') {
box.write(BoxName.carTypeOfDriver, 'Scooter');
} else {
box.write(BoxName.carTypeOfDriver, 'Pink Bike');
}
} else if (int.parse(d['year'].toString()) > 2017) {
if ((d['gender']).toString() != 'Male') {
box.write(BoxName.carTypeOfDriver, 'Lady');
} else {
box.write(BoxName.carTypeOfDriver, 'Comfort');
}
} else if (int.parse(d['year'].toString()) > 2002 &&
int.parse(d['year'].toString()) < 2017) {
box.write(BoxName.carTypeOfDriver, 'Speed');
} else if (int.parse(d['year'].toString()) < 2002) {
box.write(BoxName.carTypeOfDriver, 'Awfar Car');
}
updateAppTester(AppInformation.appName);
var fingerPrint = await DeviceHelper.getDeviceFingerprint();
await storage.write(key: BoxName.fingerPrint, value: fingerPrint);
var token = await CRUD().get(
link: AppLink.getDriverToken,
payload: {'captain_id': box.read(BoxName.driverID).toString()});
if (token != 'failure') {
if ((jsonDecode(token)['data'][0]['token']) !=
(box.read(BoxName.tokenDriver))) {
// Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP(
// 'token change'.tr,
// 'change device'.tr,
// (jsonDecode(token)['data'][0]['token']).toString(),
// [],
// 'ding.wav');
NotificationService.sendNotification(
target: (jsonDecode(token)['data'][0]['token']).toString(),
title: 'token change'.tr,
body: 'token change'.tr,
isTopic: false, // Important: this is a token
tone: 'cancel',
driverList: [], category: 'token change',
);
Get.defaultDialog(
title: 'you will use this device?'.tr,
middleText: '',
confirm: MyElevatedButton(
title: 'Ok'.tr,
onPressed: () async {
await CRUD()
.post(link: AppLink.addTokensDriver, payload: {
'token': box.read(BoxName.tokenDriver),
'captain_id': box.read(BoxName.driverID).toString(),
'fingerPrint': (fingerPrint).toString()
});
Get.back();
}));
}
}
Get.off(() => HomeCaptain());
// Get.off(() => LoginCaptin());
} else {
Get.offAll(() => SmsSignupEgypt());
mySnackeBarError('Login failed'.tr);
isloading = false;
update();
}
} else {
mySnackeBarError('');
mySnackeBarError('Server error'.tr);
isloading = false;
update();
}
} catch (e) {
mySnackeBarError('Network error'.tr);
isloading = false;
update();
}
}

View File

@@ -17,7 +17,8 @@ class PhoneAuthHelper {
// Define your server URLs
static final String _sendOtpUrl = '${AppLink.server}/auth/otp/request.php';
static final String _verifyOtpUrl = '${AppLink.server}/auth/otp/verify.php';
static final String _registerUrl = '${AppLink.server}/auth/syria/driver/register_driver.php';
static final String _registerUrl =
'${AppLink.server}/auth/syria/driver/register_driver.php';
// removed formatSyrianPhone
/// Sends an OTP to the provided phone number.
@@ -89,7 +90,7 @@ class PhoneAuthHelper {
box.write(BoxName.driverID, driver['id']);
box.write(BoxName.emailDriver, driver['email']);
await Get.find<LoginDriverController>().loginWithGoogleCredential(
await Get.find<LoginDriverController>().loginDriver(
driver['id'].toString(), driver['email'].toString());
} else {
// ✅ رقم الهاتف تم التحقق منه لكن السائق غير مسجل

View File

@@ -113,7 +113,7 @@ class RegisterCaptainController extends GetxController {
backgroundColor: AppColor.greenColor);
box.write(BoxName.phoneVerified, '1');
box.write(BoxName.phone, ('+2${phoneController.text}'));
await Get.put(LoginDriverController()).loginWithGoogleCredential(
await Get.put(LoginDriverController()).loginDriver(
box.read(BoxName.driverID).toString(),
(box.read(BoxName.emailDriver).toString()),
);
@@ -229,7 +229,7 @@ class RegisterCaptainController extends GetxController {
mySnackbarSuccess('Phone number is already verified'.tr);
box.write(BoxName.phoneVerified, '1');
box.write(BoxName.phone, ('+2${phoneController.text}'));
Get.put(LoginDriverController()).loginWithGoogleCredential(
Get.put(LoginDriverController()).loginDriver(
box.read(BoxName.driverID).toString(),
box.read(BoxName.emailDriver).toString(),
);

View File

@@ -371,7 +371,8 @@ class RegistrationController extends GetxController {
data.forEach((k, v) => request.fields[k] = v);
// المهلة الزمنية 120 ثانية لتناسب الاتصالات الضعيفة
final streamed = await request.send().timeout(const Duration(seconds: 120));
final streamed =
await request.send().timeout(const Duration(seconds: 120));
final res = await http.Response.fromStream(streamed);
if (res.statusCode != 200) {
@@ -469,7 +470,8 @@ class RegistrationController extends GetxController {
}
final statusOk = j['status'] == 'success';
final fileUrl = (j['file_url'] ?? j['message']?['file_url'])?.toString();
final fileUrl =
(j['file_url'] ?? j['message']?['file_url'])?.toString();
if (resp.statusCode == 200 &&
statusOk &&
@@ -512,14 +514,23 @@ class RegistrationController extends GetxController {
final isSyria = box.read(BoxName.countryCode) == 'Syria';
if (idFrontUrl == null || idFrontUrl.isEmpty ||
idBackUrl == null || idBackUrl.isEmpty ||
driverLicenseUrl == null || driverLicenseUrl.isEmpty ||
(isSyria && (driverLicenseBackUrl == null || driverLicenseBackUrl.isEmpty)) ||
profilePicUrl == null || profilePicUrl.isEmpty ||
carFrontUrl == null || carFrontUrl.isEmpty ||
carBackUrl == null || carBackUrl.isEmpty) {
mySnackbarWarning('Please wait for all documents to finish uploading before registering.'.tr);
if (idFrontUrl == null ||
idFrontUrl.isEmpty ||
idBackUrl == null ||
idBackUrl.isEmpty ||
driverLicenseUrl == null ||
driverLicenseUrl.isEmpty ||
(isSyria &&
(driverLicenseBackUrl == null || driverLicenseBackUrl.isEmpty)) ||
profilePicUrl == null ||
profilePicUrl.isEmpty ||
carFrontUrl == null ||
carFrontUrl.isEmpty ||
carBackUrl == null ||
carBackUrl.isEmpty) {
mySnackbarWarning(
'Please wait for all documents to finish uploading before registering.'
.tr);
return;
}
@@ -626,7 +637,8 @@ class RegistrationController extends GetxController {
_addField(fields, 'id_front', idFrontUrl);
_addField(fields, 'id_back', idBackUrl);
_addField(fields, 'driver_license', driverLicenseUrl);
if (isSyria) _addField(fields, 'driver_license_back', driverLicenseBackUrl);
if (isSyria)
_addField(fields, 'driver_license_back', driverLicenseBackUrl);
_addField(fields, 'profile_picture', profilePicUrl);
_addField(fields, 'criminal_record', criminalRecordUrl);
_addField(fields, 'car_license_front', carFrontUrl);
@@ -671,7 +683,7 @@ class RegistrationController extends GetxController {
final c = Get.isRegistered<LoginDriverController>()
? Get.find<LoginDriverController>()
: Get.put(LoginDriverController());
c.loginWithGoogleCredential(driverID, email);
c.loginDriver(driverID, email);
} else {
final msg = (json?['message'] ?? 'Registration failed.').toString();
mySnackeBarError(msg);

View File

@@ -1,5 +1,11 @@
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import 'package:siro_driver/constant/box_name.dart';
import 'package:siro_driver/constant/country_polygons.dart';
import 'package:siro_driver/constant/city_polygons.dart';
import 'package:siro_driver/main.dart';
import '../../print.dart';
class CountryLogic {
/// Formats the phone number based on the country's dialing rules.
@@ -91,4 +97,99 @@ class CountryLogic {
final country = box.read(BoxName.countryCode) ?? 'Syria';
return formatPhone(cleanPhone, country);
}
/// التحقق مما إذا كانت نقطة داخل مضلع (Ray Casting Algorithm)
static bool isPointInPolygon(LatLng point, List<LatLng> polygon) {
int intersections = 0;
for (int i = 0; i < polygon.length; i++) {
final v1 = polygon[i];
final v2 = polygon[(i + 1) % polygon.length];
if ((v1.latitude <= point.latitude && v2.latitude > point.latitude) ||
(v2.latitude <= point.latitude && v1.latitude > point.latitude)) {
final t = (point.latitude - v1.latitude) / (v2.latitude - v1.latitude);
if (point.longitude <
v1.longitude + t * (v2.longitude - v1.longitude)) {
intersections++;
}
}
}
return intersections % 2 != 0;
}
/// كشف الدولة تلقائياً عبر الموقع الجغرافي
/// باستخدام مضلعات الدول المحددة في CountryPolygons
/// تعيد 'Syria' | 'Egypt' | 'Jordan' | null (في حال الفشل)
static Future<String?> detectByLocation() async {
try {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
Log.print('[CountryLogic] GPS غير مفعل');
return null;
}
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
Log.print('[CountryLogic] رفض الإذن');
return null;
}
}
if (permission == LocationPermission.deniedForever) return null;
final pos = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low,
timeLimit: const Duration(seconds: 8),
);
final point = LatLng(pos.latitude, pos.longitude);
// فحص المضلعات بالترتيب: Jordan → Syria → Egypt
if (isPointInPolygon(point, CountryPolygons.jordanBoundary)) {
return 'Jordan';
}
if (isPointInPolygon(point, CountryPolygons.syriaBoundary)) {
return 'Syria';
}
if (isPointInPolygon(point, CountryPolygons.egyptBoundary)) {
return 'Egypt';
}
Log.print('[CountryLogic] الموقع خارج جميع المضلعات');
} catch (e) {
Log.print('[CountryLogic] detectByLocation error: $e');
}
return null;
}
/// تهيئة الدولة عند بدء التطبيق
/// إذا لم تكن الدولة محددة مسبقاً → يكشفها عبر الموقع
/// إذا فشل الكشف → Jordan كخيار افتراضي
static Future<void> initializeCountry() async {
final existing = box.read(BoxName.countryCode);
if (existing != null && existing.toString().isNotEmpty) {
Log.print('[CountryLogic] الدولة موجودة مسبقاً: $existing');
return;
}
Log.print('[CountryLogic] كشف الدولة عبر الموقع...');
final country = await detectByLocation();
if (country != null) {
box.write(BoxName.countryCode, country);
Log.print('[CountryLogic] تم الكشف: $country');
} else {
box.write(BoxName.countryCode, 'Jordan');
Log.print('[CountryLogic] افتراضي: Jordan');
}
}
/// إرجاع مضلع المدينة بناءً على الدولة الحالية
static List<LatLng> getCurrentCityPolygon() {
final country = box.read(BoxName.countryCode) ?? 'Jordan';
if (country == 'Syria') return CityPolygons.damascusPolygon;
if (country == 'Egypt') return CityPolygons.cairoPolygon;
return CityPolygons.ammanPolygon;
}
}

View File

@@ -189,7 +189,7 @@ class AI extends GetxController {
// DeviceController().getDeviceSerialNumber();
box.write(BoxName.phoneVerified, true);
Get.find<LoginDriverController>().loginWithGoogleCredential(
Get.find<LoginDriverController>().loginDriver(
box.read(BoxName.driverID).toString(),
box.read(BoxName.emailDriver).toString(),
);

View File

@@ -46,7 +46,7 @@ class SmsEgyptController extends GetxController {
('+2${Get.find<RegisterCaptainController>().phoneController.text}'));
box.write(BoxName.phoneVerified, '1');
await Get.put(LoginDriverController()).loginWithGoogleCredential(
await Get.put(LoginDriverController()).loginDriver(
box.read(BoxName.driverID).toString(),
(box.read(BoxName.emailDriver).toString()),
);

View File

@@ -130,7 +130,7 @@ class SplashScreenController extends GetxController
await initializer.initializeApp();
await EncryptionHelper.initialize();
await loginController.loginWithGoogleCredential(
await loginController.loginDriver(
box.read(BoxName.driverID).toString(),
box.read(BoxName.emailDriver).toString(),
);