Change FIDO bio enrollment UI.

This commit is contained in:
Elias Bonnici 2023-12-19 16:09:55 +01:00
parent 1d9c7b4f49
commit 36f0877881
No known key found for this signature in database
GPG Key ID: 5EAC28EA3F980CCF
6 changed files with 73 additions and 41 deletions

View File

@ -65,10 +65,15 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
super.dispose();
}
Animation<Color?> _animateColor(Color color,
Animation<Color?> _animateColor(bool success,
{Function? atPeak, bool reverse = true}) {
final theme = Theme.of(context);
final darkMode = theme.brightness == Brightness.dark;
final beginColor = darkMode ? Colors.white : Colors.black;
final endColor =
success ? theme.colorScheme.primary : theme.colorScheme.error;
final animation =
ColorTween(begin: Colors.black, end: color).animate(_animator);
ColorTween(begin: beginColor, end: endColor).animate(_animator);
_animator.forward().then((_) {
if (reverse) {
atPeak?.call();
@ -85,8 +90,7 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
_nameFocus = FocusNode();
_animator = AnimationController(
vsync: this, duration: const Duration(milliseconds: 250));
_color =
ColorTween(begin: Colors.black, end: Colors.black).animate(_animator);
_color = ColorTween().animate(_animator);
_subscription = ref
.read(fingerprintProvider(widget.devicePath).notifier)
@ -94,7 +98,7 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
.listen((event) {
setState(() {
event.when(capture: (remaining) {
_color = _animateColor(Colors.lightGreenAccent, atPeak: () {
_color = _animateColor(true, atPeak: () {
setState(() {
_samples += 1;
_remaining = remaining;
@ -107,7 +111,7 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
Timer(const Duration(milliseconds: 100), _nameFocus.requestFocus);
}, error: (code) {
_log.debug('Fingerprint capture error (code: $code)');
_color = _animateColor(Colors.redAccent);
_color = _animateColor(false);
});
});
}, onError: (error, stacktrace) {
@ -176,19 +180,26 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final progress = _samples == 0 ? 0.0 : _samples / (_samples + _remaining);
return ResponsiveDialog(
title: Text(l10n.s_add_fingerprint),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 18.0),
padding: const EdgeInsets.only(top: 38, bottom: 0, right: 18, left: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(l10n.l_fp_step_1_capture),
Column(
children: [
Padding(
padding: const EdgeInsets.all(36.0),
padding: const EdgeInsets.all(8.0),
child: Text(
_getMessage(),
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 16, fontWeight: FontWeight.normal),
),
),
Padding(
padding: const EdgeInsets.all(28),
child: AnimatedBuilder(
animation: _color,
builder: (context, _) {
@ -200,35 +211,49 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
},
),
),
LinearProgressIndicator(value: progress),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(_getMessage()),
),
if (_fingerprint == null) ...[
Container(
constraints: const BoxConstraints(maxWidth: 360),
child: LinearProgressIndicator(
value: progress,
),
)
]
],
),
Text(l10n.l_fp_step_2_name),
AppTextFormField(
focusNode: _nameFocus,
maxLength: 15,
inputFormatters: [limitBytesLength(15)],
buildCounter: buildByteCounterFor(_label),
autofocus: true,
decoration: AppInputDecoration(
enabled: _fingerprint != null,
border: const OutlineInputBorder(),
labelText: l10n.s_name,
prefixIcon: const Icon(Icons.fingerprint_outlined),
if (_fingerprint != null) ...[
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
l10n.l_name_fingerprint,
style: const TextStyle(
fontSize: 16, fontWeight: FontWeight.normal),
),
),
onChanged: (value) {
setState(() {
_label = value.trim();
});
},
onFieldSubmitted: (_) {
_submit();
},
),
Container(
constraints: const BoxConstraints(maxWidth: 360),
child: AppTextFormField(
focusNode: _nameFocus,
maxLength: 15,
inputFormatters: [limitBytesLength(15)],
buildCounter: buildByteCounterFor(_label),
autofocus: true,
decoration: AppInputDecoration(
border: const OutlineInputBorder(),
labelText: l10n.s_name,
prefixIcon: const Icon(Icons.fingerprint_outlined),
),
onChanged: (value) {
setState(() {
_label = value.trim();
});
},
onFieldSubmitted: (_) {
_submit();
},
),
)
],
]
.map((e) => Padding(
child: e,
@ -241,10 +266,12 @@ class _AddFingerprintDialogState extends ConsumerState<AddFingerprintDialog>
_subscription.cancel();
},
actions: [
TextButton(
onPressed: _fingerprint != null && _label.isNotEmpty ? _submit : null,
child: Text(l10n.s_save),
),
if (_fingerprint != null) ...[
TextButton(
onPressed: _label.isNotEmpty ? _submit : null,
child: Text(l10n.s_save),
),
]
],
);
}

View File

@ -444,6 +444,7 @@
},
"p_press_fingerprint_begin": "Drücken Sie Ihren Finger gegen den YubiKey um zu beginnen.",
"p_will_change_label_fp": "Das ändert die Beschriftung des Fingerabdrucks.",
"l_name_fingerprint": null,
"@_fido_errors": {},
"l_user_action_timeout_error": null,

View File

@ -444,6 +444,7 @@
},
"p_press_fingerprint_begin": "Press your finger against the YubiKey to begin.",
"p_will_change_label_fp": "This will change the label of the fingerprint.",
"l_name_fingerprint": "Name this fingerprint",
"@_fido_errors": {},
"l_user_action_timeout_error": "Failed due to user inactivity",

View File

@ -444,6 +444,7 @@
},
"p_press_fingerprint_begin": "Posez votre doigt sur votre YubiKey pour commencer.",
"p_will_change_label_fp": "Cette action changera la description de votre empreinte.",
"l_name_fingerprint": null,
"@_fido_errors": {},
"l_user_action_timeout_error": null,

View File

@ -444,6 +444,7 @@
},
"p_press_fingerprint_begin": "YubiKeyに指を押し当てて開始します",
"p_will_change_label_fp": "これにより指紋のラベルが変更されます",
"l_name_fingerprint": null,
"@_fido_errors": {},
"l_user_action_timeout_error": null,

View File

@ -444,6 +444,7 @@
},
"p_press_fingerprint_begin": "Przytrzymaj palec na kluczu YubiKey, aby rozpocząć.",
"p_will_change_label_fp": "Spowoduje to zmianę etykiety odcisku palca.",
"l_name_fingerprint": null,
"@_fido_errors": {},
"l_user_action_timeout_error": null,