مقارنة مع المراجعة السابقة · 16 مشكلة فُحصت
Timer.periodicممتاز▶تم حذف updateLocation() كاملاً واستبدالها بـ startUpdateLocationTimer() و stopUpdateLocationTimer(). التايمر مسجّل في onClose() و _stopAllServices(). إصلاح ممتاز.
startUpdateLocationTimer() من أي مكان. يجب التأكد أنها تُستدعى من الـ View أو من startRideFromDriver().myLocation في _handleLocationUpdate()▶void _handleLocationUpdate(geo.Position pos) {
final newLoc = LatLng(pos.latitude, pos.longitude);
myLocation = newLoc; // ← [Fix C-4] ✅ صحيح
// ...checkForNextStep() مع _checkNavigationStep()▶checkForNextStep أصبحت wrapper بسيط يستدعي _checkNavigationStep. منطق واحد، لا تعارض.
disposeEverything() لا تستدعي onClose() يدوياً▶void disposeEverything() {
_stopAllServices(); // ✅ بدون onClose()
}_parseDistanceToMeters() مشتركة▶تم استخراج منطق تحليل المسافة إلى دالة واحدة تستخدمها كلا finishRideFromDriver() و _validateTripDistance(). يحل مشكلة التضارب في الوحدات.
M-1: jitterMeters → jitterKm = 0.01 ✅
M-2: distance المحلية → distToPassenger ✅
M-6: تعليق يوضح أن الوحدة كيلومتر ✅
N-1: &directionsmode → ?directionsmode ✅
N-5: إضافة update() في getLocationArea() ✅
M-3: حذف _performanceReadings والمتغيرات الميتة ✅
Completer في C-2 يُسبب Deadlock عند إغلاق الديالوج بـ Backحرج▶الإصلاح استخدم Completer بشكل صحيح لحل مشكلة الـ callback الآني، لكنه أدخل مشكلة أخرى: لو أغلق المستخدم الديالوج بزر الرجوع (Back) في Android بدون ضغط OK، فإن completer.future لن تكتمل أبداً، والدالة ستبقى معلّقة (deadlock) لأن _validateTripDistance() هي async وتنتظر نتيجة لن تأتي:
final completer = Completer<bool>();
MyDialog().getDialog('Exit Ride?'.tr, '', () {
if (!completer.isCompleted) completer.complete(true);
Get.back();
});
return await completer.future; // ← ينتظر للأبد إذا أُغلق بـ Back
barrierDismissible: false للديالوج، أو استخدم completer.complete(false) عند إغلاق الديالوج بدون تأكيد (عبر WillPopScope أو onDismissed callback في MyDialog).رغم إضافة _parseDistanceToMeters()، تدفق الكود لا يزال يُقدّم ديالوجَين:
// finishRideFromDriver(isFromSlider: false):
MyDialog().getDialog('Are you sure to exit ride?', '', () {
Get.back();
finishRideFromDriver1(); // ← isFromSlider = false افتراضياً
});
// finishRideFromDriver1():
if (!await _validateTripDistance(false)) return; // ← يُقدّم ديالوجاً ثانياً!
المستخدم يرى "هل أنت متأكد؟" → يضغط OK → يرى "Exit Ride?" مرة ثانية → ينتظر مجدداً.
finishRideFromDriver() وأبقه في _validateTripDistance() فقط. أو مرّر isFromSlider: true لما يأتي من موافقة مسبقة.String غير قابلة للـ null▶if (isSocialPressed == true && passengerId != null && rideId != null) {
// ^^^^^^^^^^^ دائماً non-null
لو passengerId == '' يمر الشرط ويُرسل بيانات فارغة للسيرفر. الفحص الصحيح: passengerId.isNotEmpty && rideId.isNotEmpty.
argumentLoading()▶await Future.delayed(const Duration(seconds: 1)); await getRoute(...);
لا يزال موجوداً. Race condition يجب معالجته بـ Completer بدلاً من تخمين الوقت.
step0 إلى step4 بدلاً من List<String>▶String step0 = ''; String step1 = ''; // ... step0 = Get.arguments['step0']?.toString() ?? ''; step1 = Get.arguments['step1']?.toString() ?? '';
لا تزال 5 متغيرات منفصلة. List<String> steps = List.filled(5, '') أوضح وأسهل في المعالجة.
_suggestOptimization() لا تزال موجودة لكن لا يستدعيها أحد▶بعد حذف _performanceReadings و _analyzePerformance()، بقيت _suggestOptimization() معزولة. إما أن تُستدعى من مكان ما أو تُحذف.
dart:math و geolocator لا تزال▶import 'dart:math'; import 'dart:math' as math; // مكرر import 'package:geolocator/geolocator.dart' as geo; import 'package:geolocator/geolocator.dart'; // مكرر
يُسبب تحذيرات من المحلل ويُشوّش قراءة الكود. احذف النسخة غير المعرّفة.