MIF_E31221222/sigap-mobile/docs/persistent_cooldown_impleme...

4.6 KiB

Persistent Cooldown Implementation

Implementasi cooldown persisten untuk panic button yang akan tetap berlaku meskipun user keluar dan masuk kembali dari aplikasi.

Features

  1. Persistent Storage: Cooldown state disimpan menggunakan SharedPreferences
  2. Auto-restore: Cooldown akan otomatis dipulihkan saat aplikasi dibuka kembali
  3. Expiration Check: Otomatis membersihkan cooldown yang sudah expired
  4. Force Clear: Method untuk membersihkan cooldown secara paksa (untuk testing/admin)

Implementation Details

1. SharedPreferences Keys

static const String _cooldownEndTimeKey = 'panic_cooldown_end_time';
static const String _cooldownActiveKey = 'panic_cooldown_active';

2. Core Methods

Load Cooldown State

Future<void> _loadCooldownState() async {
  final prefs = await SharedPreferences.getInstance();
  final cooldownEndTime = prefs.getString(_cooldownEndTimeKey);

  if (cooldownEndTime != null) {
    final endTime = DateTime.parse(cooldownEndTime);
    final now = DateTime.now();

    if (now.isBefore(endTime)) {
      // Cooldown is still active
      isCooldownActive.value = true;
      cooldownSeconds.value = endTime.difference(now).inSeconds;
      _startCooldownTimer();
    } else {
      // Cooldown has expired, clean up
      await _clearCooldownState();
    }
  }
}

Save Cooldown State

Future<void> _saveCooldownState(DateTime endTime) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString(_cooldownEndTimeKey, endTime.toIso8601String());
  await prefs.setBool(_cooldownActiveKey, true);
}

Clear Cooldown State

Future<void> _clearCooldownState() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.remove(_cooldownEndTimeKey);
  await prefs.remove(_cooldownActiveKey);
  isCooldownActive.value = false;
  cooldownSeconds.value = 0;
}

3. Integration with Existing Code

Modified _startCooldown()

void _startCooldown() {
  int cooldownDuration = _calculateCooldownDuration();

  isCooldownActive.value = true;
  cooldownSeconds.value = cooldownDuration;
  _updateCooldownTimeString();

  // Save cooldown end time to persistent storage
  final endTime = DateTime.now().add(Duration(seconds: cooldownDuration));
  _saveCooldownState(endTime);

  _startCooldownTimer();
}

Modified _endCooldown()

void _endCooldown() {
  _cooldownTimer?.cancel();
  isCooldownActive.value = false;
  cooldownSeconds.value = 0;
  cooldownTimeString.value = '';

  // Clear persistent storage
  _clearCooldownState();
}

4. Controller Initialization

In onInit()

@override
void onInit() {
  super.onInit();

  // Load cooldown state from persistent storage
  _loadCooldownState();

  // ... other initialization code
}

Usage Scenarios

1. App Launch with Active Cooldown

  • User mengaktifkan panic button
  • Cooldown dimulai (5 menit)
  • User keluar dari aplikasi
  • User membuka aplikasi kembali setelah 2 menit
  • Cooldown akan otomatis dipulihkan dengan 3 menit tersisa

2. App Launch with Expired Cooldown

  • User mengaktifkan panic button
  • Cooldown dimulai (5 menit)
  • User keluar dari aplikasi
  • User membuka aplikasi kembali setelah 6 menit
  • Cooldown akan otomatis dibersihkan karena sudah expired

3. Force Clear Cooldown

  • Admin atau developer dapat menggunakan method forceClearCooldown()
  • Berguna untuk testing atau situasi darurat

Testing

Manual Testing Steps

  1. Aktivasi panic button hingga cooldown aktif
  2. Tutup aplikasi sepenuhnya
  3. Buka aplikasi kembali
  4. Verify cooldown masih aktif dengan waktu yang tepat
  5. Tunggu hingga cooldown habis
  6. Verify panic button dapat digunakan lagi

Edge Cases

  • Perubahan timezone
  • Perubahan waktu sistem
  • Aplikasi di-kill oleh sistem
  • Storage permission issues

Security Considerations

  1. No sensitive data: Hanya menyimpan timestamp, tidak ada data sensitif
  2. Local storage only: Menggunakan SharedPreferences yang bersifat lokal
  3. Validation: Selalu validasi timestamp sebelum menggunakan
  4. Fallback: Jika ada error, default ke state aman (no cooldown)

Performance Considerations

  1. Minimal storage: Hanya menyimpan 2 key-value pairs
  2. Efficient loading: Loading dilakukan sekali saat app start
  3. Cleanup: Otomatis membersihkan expired data
  4. Timer optimization: Reuse existing timer mechanism

Future Enhancements

  1. Server sync: Sinkronisasi dengan server untuk multi-device
  2. Usage analytics: Track cooldown patterns
  3. Dynamic duration: Cooldown duration berdasarkan usage pattern
  4. Notification: Notify user saat cooldown berakhir