Offline sync: indikator status sinkron di Riwayat + retry antrean otomatis

This commit is contained in:
Onie
2026-10-18 20:21:40 +07:00
parent e557a82faa
commit 903eb9fc42
4 changed files with 66 additions and 6 deletions

View File

@@ -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());
}
}