Update codebase
This commit is contained in:
@@ -2,9 +2,9 @@ import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tripz_driver/constant/box_name.dart';
|
||||
import 'package:tripz_driver/constant/links.dart';
|
||||
import 'package:tripz_driver/controller/functions/crud.dart';
|
||||
import 'package:siro_driver/constant/box_name.dart';
|
||||
import 'package:siro_driver/constant/links.dart';
|
||||
import 'package:siro_driver/controller/functions/crud.dart';
|
||||
|
||||
import '../../../constant/table_names.dart';
|
||||
import '../../../main.dart';
|
||||
|
||||
@@ -2,10 +2,10 @@ import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import 'package:tripz_driver/constant/links.dart';
|
||||
import 'package:tripz_driver/controller/functions/crud.dart';
|
||||
import 'package:tripz_driver/controller/functions/tts.dart';
|
||||
import 'package:tripz_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:siro_driver/constant/links.dart';
|
||||
import 'package:siro_driver/controller/functions/crud.dart';
|
||||
import 'package:siro_driver/controller/functions/tts.dart';
|
||||
import 'package:siro_driver/views/widgets/error_snakbar.dart';
|
||||
|
||||
class DestinationController extends GetxController {
|
||||
bool isLoading = false;
|
||||
@@ -43,17 +43,14 @@ class DestinationController extends GetxController {
|
||||
payload: {'action': 'get'},
|
||||
);
|
||||
|
||||
if (response != null &&
|
||||
response is Map &&
|
||||
response['status'] == 'success') {
|
||||
if (response != null && response is Map && response['status'] == 'success') {
|
||||
final data = response['message'];
|
||||
if (data != null) {
|
||||
final lat =
|
||||
double.tryParse(data['target_latitude']?.toString() ?? '0') ??
|
||||
0.0;
|
||||
final lng =
|
||||
double.tryParse(data['target_longitude']?.toString() ?? '0') ??
|
||||
0.0;
|
||||
// عند غياب وجهة نشطة يردّ السيرفر نصاً ("No active destination set.")
|
||||
// لا خريطة، وفهرسته كخريطة كان يرمي
|
||||
// type 'String' is not a subtype of type 'int'.
|
||||
if (data is Map) {
|
||||
final lat = double.tryParse(data['target_latitude']?.toString() ?? '0') ?? 0.0;
|
||||
final lng = double.tryParse(data['target_longitude']?.toString() ?? '0') ?? 0.0;
|
||||
activeLatLng = LatLng(lat, lng);
|
||||
activeName = data['destination_name']?.toString() ?? "";
|
||||
} else {
|
||||
@@ -72,8 +69,7 @@ class DestinationController extends GetxController {
|
||||
// --- 2. Autocomplete search suggestions ---
|
||||
void onSearchChanged(String query) {
|
||||
if (_debounce?.isActive ?? false) _debounce!.cancel();
|
||||
_debounce = Timer(
|
||||
const Duration(milliseconds: 500), () => getPlacesSuggestions(query));
|
||||
_debounce = Timer(const Duration(milliseconds: 500), () => getPlacesSuggestions(query));
|
||||
}
|
||||
|
||||
Future<void> getPlacesSuggestions(String query) async {
|
||||
@@ -122,12 +118,9 @@ class DestinationController extends GetxController {
|
||||
} else {
|
||||
final msg = response['message']?.toString() ?? "";
|
||||
if (msg.contains("الحد الأقصى") || msg.contains("limit")) {
|
||||
mySnackbarWarning(
|
||||
'You have reached the daily limit of 2 destination settings.'
|
||||
.tr);
|
||||
mySnackbarWarning('You have reached the daily limit of 2 destination settings.'.tr);
|
||||
} else {
|
||||
mySnackbarWarning(
|
||||
'Failed to set destination. Please try again.'.tr);
|
||||
mySnackbarWarning('Failed to set destination. Please try again.'.tr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -153,9 +146,7 @@ class DestinationController extends GetxController {
|
||||
payload: {'action': 'clear'},
|
||||
);
|
||||
|
||||
if (response != null &&
|
||||
response is Map &&
|
||||
response['status'] == 'success') {
|
||||
if (response != null && response is Map && response['status'] == 'success') {
|
||||
activeLatLng = null;
|
||||
activeName = "";
|
||||
mySnackbarSuccess('Destination cleared!'.tr);
|
||||
@@ -173,8 +164,7 @@ class DestinationController extends GetxController {
|
||||
|
||||
// --- 5. Reverse geocoding (for map picker) ---
|
||||
Future<String> reverseGeocode(LatLng location) async {
|
||||
final url =
|
||||
'${AppLink.reverseGeocoding}?lat=${location.latitude}&lng=${location.longitude}';
|
||||
final url = '${AppLink.reverseGeocoding}?lat=${location.latitude}&lng=${location.longitude}';
|
||||
try {
|
||||
final response = await CRUD().getMapSaas(link: url);
|
||||
if (response != null && response is List && response.isNotEmpty) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:tripz_driver/views/widgets/elevated_btn.dart';
|
||||
import 'package:siro_driver/views/widgets/elevated_btn.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tripz_driver/constant/box_name.dart';
|
||||
import 'package:tripz_driver/constant/links.dart';
|
||||
import 'package:tripz_driver/controller/functions/crud.dart';
|
||||
import 'package:tripz_driver/main.dart';
|
||||
import 'package:tripz_driver/models/model/driver/rides_summary_model.dart';
|
||||
import 'package:siro_driver/constant/box_name.dart';
|
||||
import 'package:siro_driver/constant/links.dart';
|
||||
import 'package:siro_driver/controller/functions/crud.dart';
|
||||
import 'package:siro_driver/main.dart';
|
||||
import 'package:siro_driver/models/model/driver/rides_summary_model.dart';
|
||||
|
||||
import '../../../views/widgets/error_snakbar.dart';
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:tripz_driver/constant/box_name.dart';
|
||||
import 'package:tripz_driver/constant/links.dart';
|
||||
import 'package:tripz_driver/controller/functions/crud.dart';
|
||||
import 'package:tripz_driver/main.dart';
|
||||
import 'package:tripz_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:siro_driver/constant/box_name.dart';
|
||||
import 'package:siro_driver/constant/links.dart';
|
||||
import 'package:siro_driver/controller/functions/crud.dart';
|
||||
import 'package:siro_driver/main.dart';
|
||||
import 'package:siro_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class AssuranceHealthController extends GetxController {
|
||||
|
||||
@@ -5,11 +5,8 @@ import 'package:get/get.dart';
|
||||
|
||||
import '../../../../constant/box_name.dart';
|
||||
import '../../../../constant/links.dart';
|
||||
import '../../../../constant/style.dart';
|
||||
import '../../../../main.dart';
|
||||
import '../../../../views/widgets/elevated_btn.dart';
|
||||
import '../../../functions/crud.dart';
|
||||
import '../../../functions/encrypt_decrypt.dart';
|
||||
|
||||
class HelpController extends GetxController {
|
||||
bool isLoading = false;
|
||||
@@ -20,6 +17,9 @@ class HelpController extends GetxController {
|
||||
String status = '';
|
||||
String qustion = '';
|
||||
late int indexQuestion = 0;
|
||||
|
||||
Map<int, String> aiReplies = {};
|
||||
|
||||
getIndex(int i, String qustion1) async {
|
||||
indexQuestion = i;
|
||||
qustion = qustion1;
|
||||
@@ -38,13 +38,15 @@ class HelpController extends GetxController {
|
||||
update();
|
||||
if (d['status'].toString() == 'success') {
|
||||
getHelpQuestion();
|
||||
// Get.snackbar('Feedback data saved successfully'.tr, '',
|
||||
// backgroundColor: AppColor.greenColor,
|
||||
// snackPosition: SnackPosition.BOTTOM);
|
||||
helpQuestionController.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void getHelpQuestion() async {
|
||||
getHelpQuestionFuture();
|
||||
}
|
||||
|
||||
Future<void> getHelpQuestionFuture() async {
|
||||
isLoading = true;
|
||||
update();
|
||||
var res = await CRUD().get(link: AppLink.gethelpCenter, payload: {
|
||||
@@ -52,27 +54,9 @@ class HelpController extends GetxController {
|
||||
});
|
||||
if (res == "failure") {
|
||||
isLoading = false;
|
||||
helpQuestionDate = {'message': []};
|
||||
update();
|
||||
Get.defaultDialog(
|
||||
title: 'There is no help Question here'.tr,
|
||||
titleStyle: AppStyle.title,
|
||||
middleText: '',
|
||||
confirm: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
MyElevatedButton(
|
||||
title: 'Add Question'.tr,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
}),
|
||||
MyElevatedButton(
|
||||
title: 'Back'.tr,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
Get.back();
|
||||
}),
|
||||
],
|
||||
));
|
||||
return;
|
||||
}
|
||||
helpQuestionDate = jsonDecode(res);
|
||||
isLoading = false;
|
||||
@@ -89,14 +73,20 @@ class HelpController extends GetxController {
|
||||
status = 'not yet';
|
||||
isLoading = false;
|
||||
update();
|
||||
} else {
|
||||
status = 'done';
|
||||
helpQuestionRepleyDate = jsonDecode(res);
|
||||
isLoading = false;
|
||||
update();
|
||||
}
|
||||
helpQuestionRepleyDate = jsonDecode(res);
|
||||
isLoading = false;
|
||||
update();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
final storedReplies = box.read<Map<String, dynamic>>('ai_replies') ?? {};
|
||||
aiReplies = storedReplies
|
||||
.map((key, value) => MapEntry(int.parse(key), value.toString()));
|
||||
|
||||
getHelpQuestion();
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:tripz_driver/constant/box_name.dart';
|
||||
import 'package:tripz_driver/constant/links.dart';
|
||||
import 'package:tripz_driver/controller/functions/crud.dart';
|
||||
import 'package:tripz_driver/main.dart';
|
||||
import 'package:siro_driver/constant/box_name.dart';
|
||||
import 'package:siro_driver/constant/links.dart';
|
||||
import 'package:siro_driver/controller/functions/crud.dart';
|
||||
import 'package:siro_driver/main.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class MaintainCenterController extends GetxController {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:tripz_driver/constant/links.dart';
|
||||
import 'package:tripz_driver/main.dart';
|
||||
import 'package:tripz_driver/controller/functions/crud.dart';
|
||||
import 'package:tripz_driver/print.dart';
|
||||
import 'package:tripz_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:siro_driver/constant/links.dart';
|
||||
import 'package:siro_driver/main.dart';
|
||||
import 'package:siro_driver/controller/functions/crud.dart';
|
||||
import 'package:siro_driver/print.dart';
|
||||
import 'package:siro_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:tripz_driver/constant/box_name.dart';
|
||||
import 'package:siro_driver/constant/box_name.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import '../../../constant/links.dart';
|
||||
@@ -32,7 +32,8 @@ class HomeCaptainController extends GetxController {
|
||||
Timer? activeTimer;
|
||||
Map data = {};
|
||||
bool isHomeMapActive = true;
|
||||
InlqBitmap carIcon = InlqBitmap.fromStyleImage('car_icon', size: 2.3);
|
||||
InlqBitmap carIcon =
|
||||
InlqBitmap.fromStyleImage('car_icon', size: 2.3);
|
||||
bool isMapReadyForCommands = false;
|
||||
bool isLoading = true;
|
||||
late double kazan = 0;
|
||||
@@ -298,7 +299,7 @@ class HomeCaptainController extends GetxController {
|
||||
void goToWalletFromConnect() {
|
||||
Get.back();
|
||||
Get.back();
|
||||
Get.to(() => WalletCaptainRefactored());
|
||||
Get.to(() => const WalletCaptainRefactored());
|
||||
}
|
||||
|
||||
void changeRideId() {
|
||||
@@ -603,7 +604,7 @@ class HomeCaptainController extends GetxController {
|
||||
update();
|
||||
}
|
||||
|
||||
// late TripzMapController mapHomeCaptainController;
|
||||
// late SiroMapController mapHomeCaptainController;
|
||||
IntaleqMapController? mapHomeCaptainController;
|
||||
CameraPosition? currentCameraPosition;
|
||||
LatLng? _lastCameraLoc; // لتتبع آخر موقع حرك الكاميرا
|
||||
@@ -938,13 +939,18 @@ class HomeCaptainController extends GetxController {
|
||||
bool isZeroCommissionActive = false;
|
||||
|
||||
getCountRideToday() async {
|
||||
var res = await CRUD().get(
|
||||
var res = await CRUD().getWallet(
|
||||
link: AppLink.getCountRide,
|
||||
payload: {'driver_id': box.read(BoxName.driverID).toString()});
|
||||
data = jsonDecode(res);
|
||||
|
||||
countRideToday = data['message'][0]['count'].toString();
|
||||
update();
|
||||
if (res != 'failure' && res != 'token_expired' && res != 'rate_limited') {
|
||||
try {
|
||||
var dataDecoded = res is String ? jsonDecode(res) : res;
|
||||
if (dataDecoded is Map && dataDecoded['status'] == 'success' && dataDecoded['message'] != null) {
|
||||
countRideToday = dataDecoded['message'][0]['count'].toString();
|
||||
update();
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
// Fetch Gamification Streak as well
|
||||
getDriverStreak();
|
||||
|
||||
@@ -6,9 +6,9 @@ import 'dart:math';
|
||||
import 'dart:math' as math;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:tripz_driver/controller/home/captin/home_captain_controller.dart';
|
||||
import 'package:tripz_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:tripz_driver/views/widgets/mydialoug.dart';
|
||||
import 'package:siro_driver/controller/home/captin/home_captain_controller.dart';
|
||||
import 'package:siro_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:siro_driver/views/widgets/mydialoug.dart';
|
||||
import 'package:bubble_head/bubble.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart' as geo;
|
||||
@@ -535,6 +535,18 @@ class MapDriverController extends GetxController
|
||||
);
|
||||
|
||||
if (response['status'] == 'success') {
|
||||
// 💰 التعويض عن عدم حضور الراكب — يحسبه الخادم من مسافة الاقتراب
|
||||
// ودقائق الانتظار، ويُضيفه لمحفظة السائق. صفر يعني أن الإلغاء وقع
|
||||
// قبل تسجيل الوصول أو قبل اكتمال مدة الانتظار المقررة.
|
||||
final num compensation = response['compensation'] ?? 0;
|
||||
if (compensation > 0) {
|
||||
final int waited = response['waited_minutes'] ?? 0;
|
||||
mySnackbarSuccess(
|
||||
"تم تعويضك $compensation عن المسافة و $waited دقيقة انتظار."
|
||||
.tr,
|
||||
);
|
||||
}
|
||||
|
||||
// 🔥🔥 معالجة الحظر (The Penalty Logic) 🔥🔥
|
||||
bool isBlocked = response['is_blocked'] ?? false;
|
||||
|
||||
@@ -1401,9 +1413,8 @@ class MapDriverController extends GetxController
|
||||
// الثابتين (distance/duration) اللذين يمثلان المسار المخطط أصلاً
|
||||
// ولا يُحدَّثان أبداً أثناء الرحلة — كانا يُبطلان فعلياً حماية
|
||||
// "إعادة حساب السعر من المسافة الفعلية" في الباك إند.
|
||||
final double actualDistanceKm = currentRideDistanceKm > 0
|
||||
? currentRideDistanceKm
|
||||
: safeParseDouble(distance);
|
||||
final double actualDistanceKm =
|
||||
currentRideDistanceKm > 0 ? currentRideDistanceKm : safeParseDouble(distance);
|
||||
final int actualDurationMinutes = _rideStartTime != null
|
||||
? (DateTime.now().difference(_rideStartTime!).inSeconds / 60).ceil()
|
||||
: safeParseInt(duration);
|
||||
@@ -1872,7 +1883,7 @@ class MapDriverController extends GetxController
|
||||
box.write(BoxName.countryCode, 'Jordan');
|
||||
update(); // [Fix N-5]
|
||||
// box.write(BoxName.serverChosen,
|
||||
// AppLink.TripzSyriaServer); // مثال: اختر سيرفر سوريا للبيانات
|
||||
// AppLink.SiroSyriaServer); // مثال: اختر سيرفر سوريا للبيانات
|
||||
return 'Jordan';
|
||||
}
|
||||
|
||||
@@ -1898,7 +1909,7 @@ class MapDriverController extends GetxController
|
||||
|
||||
/// **جلب ورسم المسار (OSRM - New Standard System)**
|
||||
///
|
||||
/// تستخدم السيرفر الجديد: https://routesy.tripz.xyz/route/v1/driving
|
||||
/// تستخدم السيرفر الجديد: https://routesy.intaleq.xyz/route/v1/driving
|
||||
Future<void> getRoute({
|
||||
required LatLng origin,
|
||||
required LatLng destination,
|
||||
@@ -2581,10 +2592,42 @@ class MapDriverController extends GetxController
|
||||
}
|
||||
}
|
||||
|
||||
/// يسأل الخادم عن آخر رحلة منتهية لم يقيّم السائق راكبها، ويفتح شاشة
|
||||
/// التقييم إن وُجدت. لا ينتظر ولا يرمي — لا يعطّل بدء العمل.
|
||||
void _checkPendingPassengerRating() async {
|
||||
try {
|
||||
final res = await CRUD().post(
|
||||
link: AppLink.pendingRating,
|
||||
payload: {'role': 'driver'},
|
||||
);
|
||||
|
||||
final data = res is Map ? (res['message'] ?? res['data']) : null;
|
||||
if (data is! Map || data['pending'] != true) return;
|
||||
|
||||
Get.to(
|
||||
() => RatePassenger(),
|
||||
arguments: {
|
||||
'passengerId': data['targetId']?.toString() ?? '',
|
||||
'rideId': data['rideId']?.toString() ?? '',
|
||||
'price': data['price']?.toString() ?? '',
|
||||
'walletChecked': 'false',
|
||||
},
|
||||
preventDuplicates: true,
|
||||
);
|
||||
} catch (e) {
|
||||
Log.print('⚠️ تعذّر فحص التقييم المتأخر: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
mapAPIKEY = await storage.read(key: BoxName.mapAPIKEY);
|
||||
await argumentLoading();
|
||||
|
||||
// شاشة تقييم الراكب تُفتح مباشرة بعد إنهاء الرحلة (Get.off أدناه)،
|
||||
// لكن السائق الذي يغلقها أو يُقفل تطبيقه لا يُطلب منه التقييم ثانيةً.
|
||||
// هذا الفحص يلتقط المتأخر عند أول فتح للتطبيق.
|
||||
_checkPendingPassengerRating();
|
||||
Get.put(FirebaseMessagesController());
|
||||
runGoogleMapDirectly();
|
||||
addCustomCarIcon();
|
||||
@@ -2881,8 +2924,7 @@ class MapDriverController extends GetxController
|
||||
polyLines.removeWhere(
|
||||
(p) => p.polylineId.value.startsWith('passenger_walk_line'));
|
||||
|
||||
if (!isRideStarted &&
|
||||
isArrivedSend &&
|
||||
if (!isRideStarted && isArrivedSend &&
|
||||
upcomingPathPoints.isNotEmpty &&
|
||||
latLngPassengerLocation.latitude != 0) {
|
||||
final LatLng lastRoadPt = upcomingPathPoints.last;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import 'package:tripz_driver/constant/api_key.dart';
|
||||
import 'package:tripz_driver/constant/box_name.dart';
|
||||
import 'package:tripz_driver/constant/links.dart';
|
||||
import 'package:tripz_driver/controller/functions/crud.dart';
|
||||
import 'package:tripz_driver/controller/functions/tts.dart';
|
||||
import 'package:siro_driver/constant/api_key.dart';
|
||||
import 'package:siro_driver/constant/box_name.dart';
|
||||
import 'package:siro_driver/constant/links.dart';
|
||||
import 'package:siro_driver/controller/functions/crud.dart';
|
||||
import 'package:siro_driver/controller/functions/tts.dart';
|
||||
|
||||
import '../../../main.dart';
|
||||
|
||||
|
||||
@@ -4,12 +4,13 @@ import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
|
||||
import 'package:trip_overlay_plugin/trip_overlay_plugin.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:tripz_driver/views/widgets/error_snakbar.dart';
|
||||
import 'package:siro_driver/views/widgets/error_snakbar.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import '../../../constant/box_name.dart';
|
||||
@@ -49,6 +50,36 @@ class OrderRequestController extends GetxController
|
||||
List<dynamic>? myList;
|
||||
Map<dynamic, dynamic>? myMapData;
|
||||
|
||||
/// نوع الطلب: 'exclusive' خلال ثواني السبق الحصري، 'public' بعد إطلاقه
|
||||
/// للجميع، و null في وضع البثّ الحر (DISPATCH_MODE غير مضبوط) — عندها
|
||||
/// لا تُعرض أي شارة.
|
||||
///
|
||||
/// المصدر: حقل offer_type في حمولة السوكِت (new_ride_request /
|
||||
/// market_new_ride). الطلبات القادمة عبر FCM أو القائمة المسبقة لا تحمله.
|
||||
Map<String, dynamic>? get offerInfo {
|
||||
final t = myMapData?['offer_type'];
|
||||
if (t == null) return null;
|
||||
return {
|
||||
'offer_type': t.toString(),
|
||||
'offer_expires_in': myMapData?['offer_expires_in'],
|
||||
};
|
||||
}
|
||||
|
||||
/// معلومات الحجز المسبق إن كانت الرحلة مجدولة.
|
||||
///
|
||||
/// يصل الحقلان من buildMarketPayload عبر السوكِت (خريطة)، أو من الفهرسين
|
||||
/// 39/40 عبر FCM (قائمة). _getValueAt يوحّد الشكلين.
|
||||
Map<String, dynamic>? get scheduleInfo {
|
||||
final flag = myMapData?['is_scheduled'] ?? _getValueAt(39);
|
||||
final v = flag?.toString();
|
||||
if (v != '1' && v != 'true') return null;
|
||||
return {
|
||||
'is_scheduled': '1',
|
||||
'scheduled_at':
|
||||
(myMapData?['scheduled_at'] ?? _getValueAt(40))?.toString() ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
IntaleqMapController? mapController;
|
||||
|
||||
// الإحداثيات (أزلنا late لتجنب الأخطاء القاتلة)
|
||||
@@ -641,6 +672,12 @@ class OrderRequestController extends GetxController
|
||||
if (takenRideId == myCurrentRideId && whoTookIt != myDriverId) {
|
||||
_isRideTakenHandled = true;
|
||||
endTimer();
|
||||
|
||||
// إغلاق نافذة الأوفرلي إن كانت معروضة فوق تطبيق آخر. كانت
|
||||
// الصفحة تُغلق وحدها وتبقى النافذة معلّقة بعدّاد يعمل على رحلة
|
||||
// لم تعد موجودة. نغلق النافذتين: فلاتر (السوكِت) والأصلية (FCM).
|
||||
_closeAnyOverlay();
|
||||
|
||||
// 1. حذف الإشعار من شريط التنبيهات فوراً
|
||||
NotificationController().cancelOrderNotification();
|
||||
if (Get.isSnackbarOpen) Get.closeCurrentSnackbar();
|
||||
@@ -669,6 +706,22 @@ class OrderRequestController extends GetxController
|
||||
}
|
||||
}
|
||||
|
||||
/// إغلاق أي نافذة عرض معروضة، أياً كان نظامها. لا يرمي أبداً: فشل
|
||||
/// الإغلاق يجب ألا يمنع بقية معالجة "أخذها سائق آخر".
|
||||
void _closeAnyOverlay() async {
|
||||
if (!Platform.isAndroid) return;
|
||||
try {
|
||||
if (await FlutterOverlayWindow.isActive()) {
|
||||
await FlutterOverlayWindow.closeOverlay();
|
||||
}
|
||||
if (await TripOverlayPlugin.isOverlayActive()) {
|
||||
await TripOverlayPlugin.hideOverlay();
|
||||
}
|
||||
} catch (e) {
|
||||
Log.print("⚠️ closeAnyOverlay: $e");
|
||||
}
|
||||
}
|
||||
|
||||
void _checkOverlay() async {
|
||||
if (Platform.isAndroid && await FlutterOverlayWindow.isActive()) {
|
||||
await FlutterOverlayWindow.closeOverlay();
|
||||
@@ -755,8 +808,7 @@ class OrderRequestController extends GetxController
|
||||
'step2': _safeGet(23),
|
||||
'step3': _safeGet(24),
|
||||
'step4': _safeGet(25),
|
||||
'passengerWalletBurc':
|
||||
_safeGet(27), // 27 = passenger_wallet (كان 26 = price_for_driver)
|
||||
'passengerWalletBurc': _safeGet(27), // 27 = passenger_wallet (كان 26 = price_for_driver)
|
||||
'timeOfOrder': DateTime.now().toString(),
|
||||
'totalPassenger': _safeGet(2),
|
||||
'carType': _safeGet(31),
|
||||
|
||||
Reference in New Issue
Block a user