Update: 2026-08-07 01:53:09
This commit is contained in:
@@ -41,9 +41,16 @@ class OrderOverlay extends StatefulWidget {
|
||||
class _OrderOverlayState extends State<OrderOverlay>
|
||||
with WidgetsBindingObserver {
|
||||
// === State Variables ===
|
||||
/// مدة مرحلة "الطلب العام" بعد انتهاء السبق الحصري.
|
||||
static const int kPublicWindowSeconds = 15;
|
||||
|
||||
OrderData? orderData;
|
||||
Timer? timer;
|
||||
int remainingSeconds = 10;
|
||||
int remainingSeconds = kPublicWindowSeconds;
|
||||
|
||||
/// هل ما زلنا داخل ثواني السبق الحصري؟ تنقلب إلى false تلقائياً حين
|
||||
/// يتبقّى من العدّاد ما يساوي مدة المرحلة العامة.
|
||||
bool isExclusive = false;
|
||||
final AudioPlayer audioPlayer = AudioPlayer();
|
||||
bool buttonsEnabled = true;
|
||||
final String mapApiKey = AK.mapAPIKEY;
|
||||
@@ -113,20 +120,29 @@ class _OrderOverlayState extends State<OrderOverlay>
|
||||
|
||||
void _processEventData(dynamic event) {
|
||||
_log("Received event: $event");
|
||||
if (event is List<dynamic>) {
|
||||
try {
|
||||
myList = event;
|
||||
final newOrder = OrderData.fromList(event);
|
||||
_log("Parsed OrderData: ${newOrder.toMap()}");
|
||||
setState(() {
|
||||
orderData = newOrder;
|
||||
});
|
||||
_resetAndStartTimer();
|
||||
} catch (e, s) {
|
||||
_log("Error parsing OrderData: $e\nStackTrace: $s");
|
||||
|
||||
// مساران يغذّيان هذه النافذة بشكلين مختلفين:
|
||||
// • FCM → قائمة مفهرسة
|
||||
// • السوكِت → خريطة JSON
|
||||
// كان الشرط يقبل القائمة وحدها، فحمولة السوكِت تُرفض بصمت ولا تظهر
|
||||
// نافذة إطلاقاً. OrderData.fromAny يوحّد الشكلين.
|
||||
try {
|
||||
final newOrder = OrderData.fromAny(event);
|
||||
if (newOrder == null) {
|
||||
_log("Unexpected data format: $event");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
_log("Unexpected data format: $event");
|
||||
|
||||
if (event is List) myList = event;
|
||||
|
||||
_log("Parsed OrderData: ${newOrder.toMap()}");
|
||||
setState(() {
|
||||
orderData = newOrder;
|
||||
isExclusive = newOrder.offerType == 'exclusive';
|
||||
});
|
||||
_resetAndStartTimer();
|
||||
} catch (e, s) {
|
||||
_log("Error parsing OrderData: $e\nStackTrace: $s");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,13 +167,16 @@ class _OrderOverlayState extends State<OrderOverlay>
|
||||
_startTimer();
|
||||
}
|
||||
|
||||
/// المدة الكلية للنافذة = ثواني السبق الحصري + مدة الطلب العام.
|
||||
///
|
||||
/// في وضع الإسناد بالدفعات: ٥ ثوانٍ الطلب خاص بهذا السائق، ثم ١٥ ثانية
|
||||
/// طلب عام يتنافس فيها مع غيره — أي نافذة ٢٠ ثانية إجمالاً.
|
||||
/// في البثّ الحر (بلا offerType): ١٥ ثانية عامة فقط، بلا شارة.
|
||||
int _calculateTimerDuration() {
|
||||
if (orderData?.durationToPassengerMinutes != null &&
|
||||
orderData!.durationToPassengerMinutes > 0) {
|
||||
int duration = orderData!.durationToPassengerMinutes * 60;
|
||||
return duration > 10 ? 10 : duration;
|
||||
}
|
||||
return 10;
|
||||
final int head = orderData?.offerType == 'exclusive'
|
||||
? (orderData!.offerExpiresIn > 0 ? orderData!.offerExpiresIn : 5)
|
||||
: 0;
|
||||
return head + kPublicWindowSeconds;
|
||||
}
|
||||
|
||||
void _startTimer() {
|
||||
@@ -171,6 +190,11 @@ class _OrderOverlayState extends State<OrderOverlay>
|
||||
setState(() {
|
||||
if (remainingSeconds > 0) {
|
||||
remainingSeconds--;
|
||||
// انتهى السبق: الطلب صار عاماً. النافذة لا تُغلق — السائق يظل
|
||||
// قادراً على القبول لكنه صار يتنافس.
|
||||
if (isExclusive && remainingSeconds <= kPublicWindowSeconds) {
|
||||
isExclusive = false;
|
||||
}
|
||||
} else {
|
||||
timer.cancel();
|
||||
_stopAudio();
|
||||
@@ -450,12 +474,22 @@ class _OrderOverlayState extends State<OrderOverlay>
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.drive_eta_rounded, color: AppColors.white, size: 24),
|
||||
Icon(
|
||||
isExclusive ? Icons.star_rounded : Icons.drive_eta_rounded,
|
||||
color: isExclusive ? const Color(0xFFFFD54F) : AppColors.white,
|
||||
size: 24,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
// العنوان يحمل حالة العرض: خاص خلال السبق، عام بعده، و"طلب
|
||||
// جديد" في البثّ الحر حيث لا معنى للتمييز.
|
||||
Text(
|
||||
"طلب جديد".tr,
|
||||
style: const TextStyle(
|
||||
color: AppColors.white,
|
||||
orderData?.offerType == null
|
||||
? "طلب جديد".tr
|
||||
: (isExclusive ? "⭐ طلب خاص لك".tr : "🌐 طلب عام".tr),
|
||||
style: TextStyle(
|
||||
color: isExclusive
|
||||
? const Color(0xFFFFD54F)
|
||||
: AppColors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user