Offline sync: indikator status sinkron di Riwayat + retry antrean otomatis
This commit is contained in:
@@ -34,11 +34,35 @@ class OfflineQueueService {
|
||||
bool get isOnline => _isOnline;
|
||||
bool get hasPendingItems => _queue.isNotEmpty;
|
||||
|
||||
/// ID transaksi (sale.id) yang masih menunggu sinkronisasi ke server.
|
||||
/// Dipakai UI untuk menandai transaksi offline di Riwayat.
|
||||
Set<String> get pendingSaleIds {
|
||||
return _queue
|
||||
.map((item) => item['sale']?['id'] as String?)
|
||||
.whereType<String>()
|
||||
.toSet();
|
||||
}
|
||||
|
||||
/// Cek apakah transaksi dengan [saleId] masih dalam antrean offline
|
||||
/// (belum terkirim ke server).
|
||||
bool isPending(String? saleId) {
|
||||
if (saleId == null) return false;
|
||||
return _queue.any((item) => item['sale']?['id'] == saleId);
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
await _loadQueue();
|
||||
_connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
|
||||
_connectivity.onConnectivityChanged.listen((result) {
|
||||
_updateConnectionStatus(result);
|
||||
if (_isOnline && _queue.isNotEmpty) {
|
||||
_processQueue().then((_) => retryNow());
|
||||
}
|
||||
});
|
||||
await _checkConnection();
|
||||
if (_isOnline) await _processQueue();
|
||||
if (_isOnline) {
|
||||
await retryNow();
|
||||
retryNow();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadQueue() async {
|
||||
@@ -61,12 +85,14 @@ class OfflineQueueService {
|
||||
}
|
||||
|
||||
/// Coba kirim antrean sekarang. Dipanggil setiap refresh/poll sukses
|
||||
/// (server terbukti reachable), bukan hanya saat event connectivity berubah.
|
||||
/// (server terbukti reachable), bukan hanya saat event connectivity
|
||||
/// berubah. Dipanggil juga dari `init()` agar offline queue dikosongkan
|
||||
/// pas app nyala, dan setiap kali server terbukti reachable lagi.
|
||||
Future<void> retryNow() async {
|
||||
await _checkConnection();
|
||||
if (!_isOnline || _queue.isEmpty || _syncing) return;
|
||||
// Verifikasi server benar-benar bisa dijangkau (radio nyala belum tentu
|
||||
// berarti Supabase reachable, misal sinyal buruk).
|
||||
// berarti Supabase reachable, misal sinyal buruk). Ping ringan 5 detik.
|
||||
try {
|
||||
await _supabase.from('products').select('id').limit(1).timeout(
|
||||
const Duration(seconds: 5),
|
||||
@@ -82,7 +108,7 @@ class OfflineQueueService {
|
||||
void _updateConnectionStatus(List<ConnectivityResult> result) {
|
||||
_isOnline = result.any((r) => r != ConnectivityResult.none);
|
||||
if (_isOnline && _queue.isNotEmpty) {
|
||||
_processQueue();
|
||||
_processQueue().then((_) => retryNow());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +116,7 @@ class OfflineQueueService {
|
||||
_queue.add(transaction);
|
||||
await _saveQueue();
|
||||
if (_isOnline) {
|
||||
await _processQueue();
|
||||
await _processQueue().then((_) => retryNow());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user