Update: 2026-07-02 05:27:04
This commit is contained in:
@@ -199,7 +199,8 @@ class LoginController extends GetxController {
|
||||
final Map<String, dynamic> payload = jsonDecode(decodedPayload);
|
||||
|
||||
if (payload['token_type'] == 'registration') {
|
||||
Log.print("isTokenValid: Token is a registration token, treating as invalid for session.");
|
||||
Log.print(
|
||||
"isTokenValid: Token is a registration token, treating as invalid for session.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -288,13 +289,14 @@ class LoginController extends GetxController {
|
||||
);
|
||||
|
||||
if (res == 'token_expired' || res == 'failure' || res == 'error') {
|
||||
Log.print('loginUsingCredentials: $res. Redirecting to PhoneNumberScreen to re-verify.');
|
||||
Log.print(
|
||||
'loginUsingCredentials: $res. Redirecting to PhoneNumberScreen to re-verify.');
|
||||
box.erase();
|
||||
storage.deleteAll();
|
||||
Get.offAll(() => PhoneNumberScreen());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 2) فك JSON مرة واحدة والتحقق من النجاح
|
||||
final decoded = res is String ? jsonDecode(res) : res;
|
||||
if (decoded is! Map || decoded.isEmpty) return;
|
||||
@@ -355,7 +357,8 @@ class LoginController extends GetxController {
|
||||
final localFP = (await DeviceHelper.getDeviceFingerprint()).toString();
|
||||
await storage.write(key: BoxName.fingerPrint, value: localFP);
|
||||
await box.write(BoxName.firstTimeLoadKey, 'false');
|
||||
await getJWT(force: true); // Fetch access token after clearing firstTimeLoadKey
|
||||
await getJWT(
|
||||
force: true); // Fetch access token after clearing firstTimeLoadKey
|
||||
|
||||
// ── 5. المقارنة: FCM token + fingerprint ──────────────────────
|
||||
if (email != '962798583052@intaleqapp.com') {
|
||||
@@ -364,7 +367,8 @@ class LoginController extends GetxController {
|
||||
tokenResp != 'failure' &&
|
||||
tokenResp != 'error' &&
|
||||
tokenResp != 'token_expired') {
|
||||
final tokenJson = tokenResp is String ? jsonDecode(tokenResp) : tokenResp;
|
||||
final tokenJson =
|
||||
tokenResp is String ? jsonDecode(tokenResp) : tokenResp;
|
||||
final serverData = tokenJson['data'] ?? tokenJson['message'];
|
||||
if (serverData is Map) {
|
||||
serverFCM = serverData['token']?.toString() ?? '';
|
||||
@@ -484,6 +488,7 @@ class LoginController extends GetxController {
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
var jsonDecoeded = jsonDecode(response.body);
|
||||
Log.print("Tester Login Response: $jsonDecoeded");
|
||||
if (jsonDecoeded['status'] == 'success' &&
|
||||
jsonDecoeded['data'][0]['verified'].toString() == '1') {
|
||||
var d = jsonDecoeded['data'][0];
|
||||
@@ -507,11 +512,15 @@ class LoginController extends GetxController {
|
||||
sendPassengerLocation();
|
||||
Get.offAll(() => const MapPagePassenger());
|
||||
} else {
|
||||
Log.print(
|
||||
"Tester Login Failed due to condition mismatch: status=${jsonDecoeded['status']}, verified=${jsonDecoeded['data']?[0]?['verified']}");
|
||||
Get.offAll(() => LoginPage());
|
||||
isloading = false;
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
Log.print(
|
||||
"Tester Login Failed with status code: ${response.statusCode}, body: ${response.body}");
|
||||
isloading = false;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -1947,6 +1947,15 @@ class RideLifecycleController extends GetxController {
|
||||
|
||||
double costForDriver = 0;
|
||||
|
||||
// ─── بيانات مقارنة أسعار المنافسين ───
|
||||
bool hasCompetitorData = false;
|
||||
double? competitorAvgPrice;
|
||||
double? savingsPercent;
|
||||
String? savingsLabel;
|
||||
String? topCompetitor;
|
||||
String? driverExtraLabel;
|
||||
double? driverExtraAmount;
|
||||
|
||||
Future bottomSheet() async {
|
||||
durationToAdd = Duration(seconds: durationToRide);
|
||||
hours = durationToAdd.inHours;
|
||||
@@ -2019,6 +2028,46 @@ class RideLifecycleController extends GetxController {
|
||||
|
||||
update();
|
||||
mapEngine.changeBottomSheetShown(forceValue: true);
|
||||
|
||||
// جلب مقارنة أسعار المنافسين في الخلفية بعد عرض الأسعار
|
||||
fetchCompetitorContext();
|
||||
}
|
||||
|
||||
/// يجلب مقارنة سعر سيرو مع المنافسين ويحدّث الواجهة بشكل غير مُوقِف
|
||||
Future<void> fetchCompetitorContext() async {
|
||||
try {
|
||||
final String passengerLat = mapEngine.polylineCoordinates.isNotEmpty
|
||||
? mapEngine.polylineCoordinates.first.latitude.toString()
|
||||
: newMyLocation.latitude.toString();
|
||||
final String passengerLng = mapEngine.polylineCoordinates.isNotEmpty
|
||||
? mapEngine.polylineCoordinates.first.longitude.toString()
|
||||
: newMyLocation.longitude.toString();
|
||||
|
||||
final res = await CRUD().post(
|
||||
link: AppLink.getCompetitorContext,
|
||||
payload: {
|
||||
'passenger_lat': passengerLat,
|
||||
'passenger_lng': passengerLng,
|
||||
'distance': distance.toString(),
|
||||
'country': box.read(BoxName.countryCode) ?? '',
|
||||
'siro_price': totalPassengerSpeed,
|
||||
'car_type': 'Speed',
|
||||
},
|
||||
);
|
||||
|
||||
if (res is Map && res['status'] == 'success') {
|
||||
hasCompetitorData = res['has_competitor_data'] == true;
|
||||
competitorAvgPrice = double.tryParse(res['competitor_avg_price']?.toString() ?? '');
|
||||
savingsPercent = double.tryParse(res['savings_percent']?.toString() ?? '');
|
||||
savingsLabel = res['savings_label']?.toString();
|
||||
topCompetitor = res['top_competitor']?.toString();
|
||||
driverExtraLabel = res['driver_extra_label']?.toString();
|
||||
driverExtraAmount = double.tryParse(res['driver_extra_amount']?.toString() ?? '');
|
||||
update();
|
||||
}
|
||||
} catch (e) {
|
||||
Log.print('[CompetitorContext] fetch failed: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// حساب المسار بين السائق والراكب وعرضه على الخريطة.
|
||||
@@ -2426,7 +2475,12 @@ class RideLifecycleController extends GetxController {
|
||||
double tripDurationInMinutes = durationToPassenger / 5;
|
||||
int loopCount = tripDurationInMinutes.ceil();
|
||||
for (var i = 0; i < loopCount; i++) {
|
||||
// [Fix Loop-1] فحص إغلاق الكنترولر قبل وبعد التأخير لمنع crash
|
||||
if (isClosed ||
|
||||
currentRideState.value == RideState.finished ||
|
||||
currentRideState.value == RideState.preCheckReview) return;
|
||||
await Future.delayed(const Duration(seconds: 5));
|
||||
if (isClosed) return;
|
||||
if (rideTimerBegin == true || statusRide == 'Apply') {
|
||||
await getDriverCarsLocationToPassengerAfterApplied();
|
||||
}
|
||||
@@ -2438,7 +2492,12 @@ class RideLifecycleController extends GetxController {
|
||||
int loopCount = tripDurationInMinutes.ceil();
|
||||
mapEngine.clearMarkersExceptStartEndAndDriver();
|
||||
for (var i = 0; i < loopCount; i++) {
|
||||
// [Fix Loop-2] فحص إغلاق الكنترولر لمنع استدعاء الدوال على كنترولر مغلق
|
||||
if (isClosed ||
|
||||
currentRideState.value == RideState.finished ||
|
||||
currentRideState.value == RideState.preCheckReview) return;
|
||||
await Future.delayed(const Duration(seconds: 4));
|
||||
if (isClosed) return;
|
||||
await getDriverCarsLocationToPassengerAfterApplied();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user