feat: reformat some pages
This commit is contained in:
@@ -6,23 +6,29 @@ import '../l10n/app_localizations_helpers.dart';
|
||||
import '../models/app_error.dart';
|
||||
import '../viewmodels/pin_lock_view_model.dart';
|
||||
|
||||
enum PinEntryMode { unlock, create }
|
||||
enum PinEntryMode { unlock, create, change }
|
||||
|
||||
const _pinLength = 4;
|
||||
|
||||
/// Full-screen PIN entry. In [PinEntryMode.unlock] it verifies a PIN
|
||||
/// against the one already saved. In [PinEntryMode.create] it walks the
|
||||
/// person through entering a new PIN twice before saving it.
|
||||
/// [PinEntryMode.change] first checks the current PIN, then does the same.
|
||||
class PinEntryView extends StatefulWidget {
|
||||
final PinEntryMode mode;
|
||||
final VoidCallback? onSuccess;
|
||||
final bool isAdmin;
|
||||
final Future<bool> Function(String)? onVerify;
|
||||
final Future<bool> Function(String)? onSet;
|
||||
final Future<bool> Function(String currentPin, String newPin)? onChange;
|
||||
final AppError? Function()? error;
|
||||
|
||||
/// Shows a close button that leaves the screen without entering a PIN.
|
||||
final VoidCallback? onClose;
|
||||
|
||||
/// Replaces the title of the step that checks an existing PIN.
|
||||
final String? title;
|
||||
|
||||
const PinEntryView({
|
||||
super.key,
|
||||
required this.mode,
|
||||
@@ -30,8 +36,10 @@ class PinEntryView extends StatefulWidget {
|
||||
this.isAdmin = false,
|
||||
this.onVerify,
|
||||
this.onSet,
|
||||
this.onChange,
|
||||
this.error,
|
||||
this.onClose,
|
||||
this.title,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -41,21 +49,33 @@ class PinEntryView extends StatefulWidget {
|
||||
class _PinEntryViewState extends State<PinEntryView> {
|
||||
String _digits = '';
|
||||
String? _firstEntry;
|
||||
String? _currentPin;
|
||||
bool _isConfirmStep = false;
|
||||
bool _isSubmitting = false;
|
||||
String? _localError;
|
||||
bool _shake = false;
|
||||
|
||||
bool get _isCreateFlow => widget.mode == PinEntryMode.create;
|
||||
bool get _isChangeFlow => widget.mode == PinEntryMode.change;
|
||||
|
||||
bool get _isCreateFlow =>
|
||||
widget.mode == PinEntryMode.create ||
|
||||
(_isChangeFlow && _currentPin != null);
|
||||
|
||||
String _title(AppLocalizations l10n) {
|
||||
if (widget.isAdmin) {
|
||||
if (!_isCreateFlow) return l10n.enterAdminPin;
|
||||
return _isConfirmStep ? l10n.confirmAdminPin : l10n.createAdminPin;
|
||||
if (_isChangeFlow && _currentPin == null) {
|
||||
return widget.title ??
|
||||
(widget.isAdmin ? l10n.enterCurrentAdminPin : l10n.enterCurrentPin);
|
||||
}
|
||||
|
||||
if (!_isCreateFlow) return l10n.enterPin;
|
||||
return _isConfirmStep ? l10n.confirmPin : l10n.createPin;
|
||||
if (widget.isAdmin) {
|
||||
if (!_isCreateFlow) return widget.title ?? l10n.enterAdminPin;
|
||||
if (_isConfirmStep) return l10n.confirmAdminPin;
|
||||
return _isChangeFlow ? l10n.enterNewAdminPin : l10n.createAdminPin;
|
||||
}
|
||||
|
||||
if (!_isCreateFlow) return widget.title ?? l10n.enterPin;
|
||||
if (_isConfirmStep) return l10n.confirmPin;
|
||||
return _isChangeFlow ? l10n.enterNewPin : l10n.createPin;
|
||||
}
|
||||
|
||||
String? _subtitle(AppLocalizations l10n) {
|
||||
@@ -114,7 +134,9 @@ class _PinEntryViewState extends State<PinEntryView> {
|
||||
}
|
||||
|
||||
setState(() => _isSubmitting = true);
|
||||
final ok = await _setPin(_digits);
|
||||
final ok = _isChangeFlow
|
||||
? await _changePin(_currentPin!, _digits)
|
||||
: await _setPin(_digits);
|
||||
if (!mounted) return;
|
||||
setState(() => _isSubmitting = false);
|
||||
|
||||
@@ -135,10 +157,15 @@ class _PinEntryViewState extends State<PinEntryView> {
|
||||
if (!mounted) return;
|
||||
setState(() => _isSubmitting = false);
|
||||
|
||||
if (ok) {
|
||||
widget.onSuccess?.call();
|
||||
} else {
|
||||
if (!ok) {
|
||||
_fail(l10n.errorText(_error()));
|
||||
} else if (_isChangeFlow) {
|
||||
setState(() {
|
||||
_currentPin = _digits;
|
||||
_digits = '';
|
||||
});
|
||||
} else {
|
||||
widget.onSuccess?.call();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +176,16 @@ class _PinEntryViewState extends State<PinEntryView> {
|
||||
return context.read<PinLockViewModel>().setPin(pin);
|
||||
}
|
||||
|
||||
Future<bool> _changePin(String currentPin, String newPin) {
|
||||
final callback = widget.onChange;
|
||||
if (callback != null) return callback(currentPin, newPin);
|
||||
|
||||
return context.read<PinLockViewModel>().changePin(
|
||||
currentPin: currentPin,
|
||||
newPin: newPin,
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> _verify(String pin) {
|
||||
final callback = widget.onVerify;
|
||||
if (callback != null) return callback(pin);
|
||||
|
||||
Reference in New Issue
Block a user