Update codebase

This commit is contained in:
Hamza-Ayed
2026-08-09 16:56:13 +03:00
parent 95e2e4f35d
commit b64debaa88
1058 changed files with 164327 additions and 113928 deletions
@@ -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),