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

180 lines
4.6 KiB
Markdown

# 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
```dart
static const String _cooldownEndTimeKey = 'panic_cooldown_end_time';
static const String _cooldownActiveKey = 'panic_cooldown_active';
```
### 2. Core Methods
#### Load Cooldown State
```dart
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
```dart
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
```dart
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()
```dart
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()
```dart
void _endCooldown() {
_cooldownTimer?.cancel();
isCooldownActive.value = false;
cooldownSeconds.value = 0;
cooldownTimeString.value = '';
// Clear persistent storage
_clearCooldownState();
}
```
### 4. Controller Initialization
#### In onInit()
```dart
@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