payfrit-app/lib/services/order_polling_service.dart
John Mizerek 2491c961e0 Add address management and user account features
- 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>
2026-01-08 20:22:37 -08:00

121 lines
3.6 KiB
Dart
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)';
}