- Add delivery address list, add, edit, delete, set default functionality - Add order history screen - Add profile settings screen - Add account screen with avatar upload - Update restaurant select gradient direction - Add states API endpoint for address forms - Fix table names (tt_States) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
121 lines
3.6 KiB
Dart
121 lines
3.6 KiB
Dart
import 'dart:async';
|
||
import 'package:flutter/material.dart';
|
||
import 'api.dart';
|
||
|
||
/// Service that polls the backend API for order status updates
|
||
/// Uses a simple polling approach with 6-second intervals for responsive updates
|
||
class OrderPollingService {
|
||
static Timer? _pollingTimer;
|
||
static int? _currentOrderId;
|
||
static int? _lastKnownStatusId;
|
||
static Function(OrderStatusUpdate)? _onStatusUpdate;
|
||
|
||
/// Start polling for order status updates
|
||
static void startPolling({
|
||
required int orderId,
|
||
required int initialStatusId,
|
||
required Function(OrderStatusUpdate) onStatusUpdate,
|
||
}) {
|
||
print('[OrderPolling] 🔄 Starting polling for OrderID=$orderId, Status=$initialStatusId');
|
||
|
||
// Stop any existing polling
|
||
stopPolling();
|
||
|
||
_currentOrderId = orderId;
|
||
_lastKnownStatusId = initialStatusId;
|
||
_onStatusUpdate = onStatusUpdate;
|
||
|
||
// Poll every 6 seconds for responsive updates
|
||
_pollingTimer = Timer.periodic(const Duration(seconds: 6), (_) {
|
||
_checkForUpdate();
|
||
});
|
||
|
||
// Also check immediately
|
||
_checkForUpdate();
|
||
}
|
||
|
||
/// Stop polling
|
||
static void stopPolling() {
|
||
print('[OrderPolling] ⏹️ Stopping polling');
|
||
_pollingTimer?.cancel();
|
||
_pollingTimer = null;
|
||
_currentOrderId = null;
|
||
_lastKnownStatusId = null;
|
||
_onStatusUpdate = null;
|
||
}
|
||
|
||
/// Check if currently polling
|
||
static bool get isPolling => _pollingTimer != null && _pollingTimer!.isActive;
|
||
|
||
/// Get current order ID being polled
|
||
static int? get currentOrderId => _currentOrderId;
|
||
|
||
/// Internal method to check for updates
|
||
static Future<void> _checkForUpdate() async {
|
||
if (_currentOrderId == null || _lastKnownStatusId == null) {
|
||
print('[OrderPolling] ⚠️ No order to poll, stopping');
|
||
stopPolling();
|
||
return;
|
||
}
|
||
|
||
try {
|
||
print('[OrderPolling] 🔍 Checking status for OrderID=$_currentOrderId');
|
||
|
||
final data = await Api.checkOrderStatus(
|
||
orderId: _currentOrderId!,
|
||
lastKnownStatusId: _lastKnownStatusId!,
|
||
);
|
||
|
||
if (data['OK'] == true && data['HAS_UPDATE'] == true) {
|
||
final orderStatus = data['ORDER_STATUS'];
|
||
final newStatusId = (orderStatus['StatusID'] as num).toInt();
|
||
final statusName = orderStatus['StatusName'] as String;
|
||
final message = orderStatus['Message'] as String;
|
||
|
||
print('[OrderPolling] ✅ Status update detected: $statusName (ID=$newStatusId)');
|
||
|
||
// Update last known status
|
||
_lastKnownStatusId = newStatusId;
|
||
|
||
// Notify listener
|
||
if (_onStatusUpdate != null) {
|
||
_onStatusUpdate!(OrderStatusUpdate(
|
||
orderId: _currentOrderId!,
|
||
statusId: newStatusId,
|
||
statusName: statusName,
|
||
message: message,
|
||
));
|
||
}
|
||
|
||
// Stop polling if order reached terminal state (4=Complete, 5=Cancelled)
|
||
if (newStatusId >= 4) {
|
||
print('[OrderPolling] 🏁 Order reached terminal status ($statusName), stopping polling');
|
||
stopPolling();
|
||
return;
|
||
}
|
||
} else {
|
||
print('[OrderPolling] ℹ️ No status update');
|
||
}
|
||
} catch (e) {
|
||
print('[OrderPolling] ❌ Error checking status: $e');
|
||
}
|
||
}
|
||
}
|
||
|
||
/// Data class representing an order status update
|
||
class OrderStatusUpdate {
|
||
final int orderId;
|
||
final int statusId;
|
||
final String statusName;
|
||
final String message;
|
||
|
||
const OrderStatusUpdate({
|
||
required this.orderId,
|
||
required this.statusId,
|
||
required this.statusName,
|
||
required this.message,
|
||
});
|
||
|
||
@override
|
||
String toString() => 'OrderStatusUpdate(orderId: $orderId, statusId: $statusId, statusName: $statusName, message: $message)';
|
||
}
|