Offline queue: retry kirim setelah refresh/poll sukses + verifikasi server reachable + log gagal sinkron + izin INTERNET/ACCESS_NETWORK_STATE Android
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!-- Akses jaringan: API Supabase + deteksi konektivitas offline queue -->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
||||||
<!-- Camera permission for barcode scanning -->
|
<!-- Camera permission for barcode scanning -->
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,25 @@ class OfflineQueueService {
|
|||||||
_updateConnectionStatus(result);
|
_updateConnectionStatus(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Coba kirim antrean sekarang. Dipanggil setiap refresh/poll sukses
|
||||||
|
/// (server terbukti reachable), bukan hanya saat event connectivity berubah.
|
||||||
|
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).
|
||||||
|
try {
|
||||||
|
await _supabase.from('products').select('id').limit(1).timeout(
|
||||||
|
const Duration(seconds: 5),
|
||||||
|
onTimeout: () => throw TimeoutException('Ping server timeout'),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('OfflineQueue skip sync: server tidak terjangkau: $e');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await _processQueue();
|
||||||
|
}
|
||||||
|
|
||||||
void _updateConnectionStatus(List<ConnectivityResult> result) {
|
void _updateConnectionStatus(List<ConnectivityResult> result) {
|
||||||
_isOnline = result.any((r) => r != ConnectivityResult.none);
|
_isOnline = result.any((r) => r != ConnectivityResult.none);
|
||||||
if (_isOnline && _queue.isNotEmpty) {
|
if (_isOnline && _queue.isNotEmpty) {
|
||||||
@@ -86,6 +105,7 @@ class OfflineQueueService {
|
|||||||
_queue.removeAt(0);
|
_queue.removeAt(0);
|
||||||
await _saveQueue();
|
await _saveQueue();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
debugPrint('OfflineQueue gagal sinkron item ${item['sale']?['id']}: $e');
|
||||||
_syncing = false;
|
_syncing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,6 +224,8 @@ class AppState extends ChangeNotifier {
|
|||||||
await _loadProducts();
|
await _loadProducts();
|
||||||
await _loadSales();
|
await _loadSales();
|
||||||
dataReady = true;
|
dataReady = true;
|
||||||
|
// Server terbukti reachable → coba kirim antrean transaksi offline.
|
||||||
|
await _offlineQueue.retryNow();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
productsError ??= e.toString();
|
productsError ??= e.toString();
|
||||||
if (retries > 0) {
|
if (retries > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user