125 lines
2.6 KiB
Dart
125 lines
2.6 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
|
|
import '../models/app_error.dart';
|
|
import '../services/admin_pin_service.dart';
|
|
import '../services/pin_lock_service.dart';
|
|
|
|
class AdminPinViewModel extends ChangeNotifier {
|
|
final AdminPinService adminPinService;
|
|
|
|
AdminPinViewModel({required this.adminPinService});
|
|
|
|
bool _isPinSet = false;
|
|
bool _isUnlocked = false;
|
|
bool _isLoading = false;
|
|
bool _hasLoaded = false;
|
|
AppError? _error;
|
|
|
|
bool get isPinSet => _isPinSet;
|
|
|
|
bool get isUnlocked => _isUnlocked;
|
|
|
|
bool get isLoading => _isLoading;
|
|
|
|
bool get hasLoaded => _hasLoaded;
|
|
|
|
AppError? get error => _error;
|
|
|
|
Future<void> ensureLoaded() async {
|
|
if (_hasLoaded || _isLoading) return;
|
|
|
|
await load();
|
|
}
|
|
|
|
Future<void> load() async {
|
|
if (_isLoading) return;
|
|
|
|
_isLoading = true;
|
|
_error = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
_isPinSet = await adminPinService.hasPin();
|
|
} catch (e) {
|
|
debugPrint('AdminPinViewModel: load error: $e');
|
|
_error = AppError.checkPinStatus;
|
|
} finally {
|
|
_hasLoaded = true;
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<bool> setPin(String pin) async {
|
|
_error = null;
|
|
|
|
try {
|
|
await adminPinService.setPin(pin);
|
|
_isPinSet = true;
|
|
_isUnlocked = true;
|
|
notifyListeners();
|
|
return true;
|
|
} catch (e) {
|
|
debugPrint('AdminPinViewModel: setPin error: $e');
|
|
_error = AppError.savePin;
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> verify(String pin) async {
|
|
_error = null;
|
|
|
|
try {
|
|
final matches = await adminPinService.verifyPin(pin);
|
|
|
|
if (matches) {
|
|
_isUnlocked = true;
|
|
notifyListeners();
|
|
return true;
|
|
}
|
|
|
|
_error = AppError.incorrectPin;
|
|
notifyListeners();
|
|
return false;
|
|
} on PinLockedOutException {
|
|
_error = AppError.tooManyPinAttempts;
|
|
notifyListeners();
|
|
return false;
|
|
} catch (e) {
|
|
debugPrint('AdminPinViewModel: verify error: $e');
|
|
_error = AppError.verifyPin;
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> changePin({
|
|
required String currentPin,
|
|
required String newPin,
|
|
}) async {
|
|
if (!await _verifyCurrentPin(currentPin)) return false;
|
|
|
|
return setPin(newPin);
|
|
}
|
|
|
|
Future<bool> _verifyCurrentPin(String pin) async {
|
|
try {
|
|
if (await adminPinService.verifyPin(pin)) return true;
|
|
_error = AppError.currentPinIncorrect;
|
|
} on PinLockedOutException {
|
|
_error = AppError.tooManyPinAttempts;
|
|
}
|
|
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
|
|
void lock() {
|
|
if (!_isUnlocked) return;
|
|
|
|
_isUnlocked = false;
|
|
notifyListeners();
|
|
}
|
|
}
|