diff --git a/lib/android/oath/state.dart b/lib/android/oath/state.dart index de1fe79d..d19450dd 100755 --- a/lib/android/oath/state.dart +++ b/lib/android/oath/state.dart @@ -360,6 +360,7 @@ class _OathMethodChannelNotifier extends MethodChannelNotifier { 'callArgs': {'password': password, 'remember': remember}, 'operationSuccess': l10n.s_nfc_unlock_success, 'operationFailure': l10n.s_nfc_unlock_failure, + 'showSuccess': false, }); Future setPassword(String? current, String password) async => diff --git a/lib/android/tap_request_dialog.dart b/lib/android/tap_request_dialog.dart index 8f646018..94949564 100755 --- a/lib/android/tap_request_dialog.dart +++ b/lib/android/tap_request_dialog.dart @@ -39,9 +39,11 @@ final androidDialogProvider = NotifierProvider<_DialogProvider, int>(_DialogProvider.new); class _DialogProvider extends Notifier { - Timer? processingTimer; + Timer? processingViewTimeout; bool explicitAction = false; + late final l10n = ref.read(l10nProvider); + @override int build() { final l10n = ref.read(l10nProvider); @@ -53,6 +55,7 @@ class _DialogProvider extends Notifier { if (!explicitAction) { // setup properties for ad-hoc action viewNotifier.setDialogProperties( + operationSuccess: l10n.s_nfc_scan_success, operationFailure: l10n.l_nfc_read_key_failure, showSuccess: true, showCloseButton: false); @@ -62,45 +65,37 @@ class _DialogProvider extends Notifier { switch (current) { case NfcActivity.processingStarted: - viewNotifier.setDialogProperties(showCloseButton: false); - processingTimer?.cancel(); - final timeout = explicitAction ? 300 : 200; - - processingTimer = Timer(Duration(milliseconds: timeout), () { - if (!explicitAction) { - // show the widget - notifier.sendCommand(showNfcView(NfcContentWidget( - title: l10n.s_nfc_accessing_yubikey, - icon: const NfcIconProgressBar(true), - ))); - } else { - // the processing view will only be shown if the timer is still active - notifier.sendCommand(updateNfcView(NfcContentWidget( - title: l10n.s_nfc_accessing_yubikey, - icon: const NfcIconProgressBar(true), - ))); - } + final timeout = explicitAction ? 300 : 500; + processingViewTimeout?.cancel(); + processingViewTimeout = Timer(Duration(milliseconds: timeout), () { + notifier.sendCommand(showAccessingKeyView()); }); break; case NfcActivity.processingFinished: - processingTimer?.cancel(); + processingViewTimeout?.cancel(); final showSuccess = properties.showSuccess ?? false; allowMessages = !showSuccess; if (showSuccess) { notifier.sendCommand(autoClose( - title: properties.operationSuccess, - subtitle: l10n.s_nfc_remove_key, - icon: const NfcIconSuccess(), - )); + title: properties.operationSuccess, + subtitle: explicitAction ? l10n.s_nfc_remove_key : null, + icon: const NfcIconSuccess(), + showIfHidden: false)); + // hide } - // hide - notifier.sendCommand(hideNfcView(explicitAction ? 5000 : 400)); + notifier.sendCommand(hideNfcView(Duration( + milliseconds: !showSuccess + ? 0 + : explicitAction + ? 5000 + : 400))); + explicitAction = false; // next action might not be explicit break; case NfcActivity.processingInterrupted: - processingTimer?.cancel(); + processingViewTimeout?.cancel(); viewNotifier.setDialogProperties(showCloseButton: true); - notifier.sendCommand(updateNfcView(NfcContentWidget( + notifier.sendCommand(setNfcView(NfcContentWidget( title: properties.operationFailure, subtitle: l10n.s_nfc_scan_again, icon: const NfcIconFailure(), @@ -119,14 +114,7 @@ class _DialogProvider extends Notifier { switch (call.method) { case 'show': explicitAction = true; - - // we want to show the close button - viewNotifier.setDialogProperties(showCloseButton: true); - - notifier.sendCommand(showNfcView(NfcContentWidget( - subtitle: l10n.s_nfc_scan_yubikey, - icon: const NfcIconProgressBar(false), - ))); + notifier.sendCommand(showScanKeyView()); break; case 'close': @@ -143,6 +131,26 @@ class _DialogProvider extends Notifier { return 0; } + NfcEventCommand showScanKeyView() { + ref + .read(nfcViewNotifier.notifier) + .setDialogProperties(showCloseButton: true); + return setNfcView(NfcContentWidget( + subtitle: l10n.s_nfc_scan_yubikey, + icon: const NfcIconProgressBar(false), + )); + } + + NfcEventCommand showAccessingKeyView() { + ref + .read(nfcViewNotifier.notifier) + .setDialogProperties(showCloseButton: false); + return setNfcView(NfcContentWidget( + title: l10n.s_nfc_accessing_yubikey, + icon: const NfcIconProgressBar(true), + )); + } + void closeDialog() { ref.read(nfcEventCommandNotifier.notifier).sendCommand(hideNfcView()); } @@ -168,28 +176,3 @@ class _DialogProvider extends Notifier { await completer.future; } } - -class MethodChannelHelper { - final ProviderRef _ref; - final MethodChannel _channel; - - const MethodChannelHelper(this._ref, this._channel); - - Future invoke(String method, - {String? operationSuccess, - String? operationFailure, - bool? showSuccess, - bool? showCloseButton, - Map arguments = const {}}) async { - final notifier = _ref.read(nfcViewNotifier.notifier); - notifier.setDialogProperties( - operationSuccess: operationSuccess, - operationFailure: operationFailure, - showSuccess: showSuccess, - showCloseButton: showCloseButton); - - final result = await _channel.invokeMethod(method, arguments); - await _ref.read(androidDialogProvider.notifier).waitForDialogClosed(); - return result; - } -} diff --git a/lib/android/views/nfc/models.dart b/lib/android/views/nfc/models.dart index 057b98bc..d6594304 100644 --- a/lib/android/views/nfc/models.dart +++ b/lib/android/views/nfc/models.dart @@ -23,26 +23,21 @@ class NfcEvent { const NfcEvent(); } -class NfcShowViewEvent extends NfcEvent { - final Widget child; - - const NfcShowViewEvent({required this.child}); -} - class NfcHideViewEvent extends NfcEvent { - final int timeoutMs; + final Duration hideAfter; - const NfcHideViewEvent({required this.timeoutMs}); + const NfcHideViewEvent({required this.hideAfter}); } class NfcCancelEvent extends NfcEvent { const NfcCancelEvent(); } -class NfcUpdateViewEvent extends NfcEvent { +class NfcSetViewEvent extends NfcEvent { final Widget child; + final bool showIfHidden; - const NfcUpdateViewEvent({required this.child}); + const NfcSetViewEvent({required this.child, this.showIfHidden = true}); } @freezed @@ -63,11 +58,9 @@ class NfcEventCommand with _$NfcEventCommand { }) = _NfcEventCommand; } -NfcEventCommand hideNfcView([int timeoutMs = 0]) => - NfcEventCommand(event: NfcHideViewEvent(timeoutMs: timeoutMs)); +NfcEventCommand hideNfcView([Duration hideAfter = Duration.zero]) => + NfcEventCommand(event: NfcHideViewEvent(hideAfter: hideAfter)); -NfcEventCommand updateNfcView(Widget child) => - NfcEventCommand(event: NfcUpdateViewEvent(child: child)); - -NfcEventCommand showNfcView(Widget child) => - NfcEventCommand(event: NfcShowViewEvent(child: child)); +NfcEventCommand setNfcView(Widget child, {bool showIfHidden = true}) => + NfcEventCommand( + event: NfcSetViewEvent(child: child, showIfHidden: showIfHidden)); diff --git a/lib/android/views/nfc/nfc_activity_command_listener.dart b/lib/android/views/nfc/nfc_activity_command_listener.dart index b5e1a628..d821750b 100644 --- a/lib/android/views/nfc/nfc_activity_command_listener.dart +++ b/lib/android/views/nfc/nfc_activity_command_listener.dart @@ -41,14 +41,15 @@ class _NfcEventCommandListener { (previous, action) { _log.debug('Change in command for Overlay: $previous -> $action'); switch (action) { - case (NfcShowViewEvent a): - _show(context, a.child); - break; - case (NfcUpdateViewEvent a): - _ref.read(nfcViewNotifier.notifier).update(a.child); + case (NfcSetViewEvent a): + if (!visible && a.showIfHidden) { + _show(context, a.child); + } else { + _ref.read(nfcViewNotifier.notifier).update(a.child); + } break; case (NfcHideViewEvent e): - _hide(context, Duration(milliseconds: e.timeoutMs)); + _hide(context, e.hideAfter); break; case (NfcCancelEvent _): _ref.read(androidDialogProvider.notifier).cancelDialog(); @@ -61,8 +62,8 @@ class _NfcEventCommandListener { void _show(BuildContext context, Widget child) async { final notifier = _ref.read(nfcViewNotifier.notifier); notifier.update(child); - if (!_ref.read(nfcViewNotifier.select((s) => s.isShowing))) { - notifier.setShowing(true); + if (!visible) { + visible = true; final result = await showModalBottomSheet( context: context, builder: (BuildContext context) { @@ -72,18 +73,22 @@ class _NfcEventCommandListener { // the modal sheet was cancelled by Back button, close button or dismiss _ref.read(androidDialogProvider.notifier).cancelDialog(); } - notifier.setShowing(false); + visible = false; } } void _hide(BuildContext context, Duration timeout) { Future.delayed(timeout, () { _ref.read(withContextProvider)((context) async { - if (_ref.read(nfcViewNotifier.select((s) => s.isShowing))) { + if (visible) { Navigator.of(context).pop('HIDDEN'); - _ref.read(nfcViewNotifier.notifier).setShowing(false); + visible = false; } }); }); } + + bool get visible => _ref.read(nfcViewNotifier.select((s) => s.isShowing)); + set visible(bool showing) => + _ref.read(nfcViewNotifier.notifier).setShowing(showing); } diff --git a/lib/android/views/nfc/nfc_auto_close_widget.dart b/lib/android/views/nfc/nfc_auto_close_widget.dart index 5006bf7a..d0abe3e6 100644 --- a/lib/android/views/nfc/nfc_auto_close_widget.dart +++ b/lib/android/views/nfc/nfc_auto_close_widget.dart @@ -22,18 +22,20 @@ import 'models.dart'; import 'nfc_activity_overlay.dart'; import 'nfc_content_widget.dart'; -NfcEventCommand autoClose({ - String? title, - String? subtitle, - Widget? icon, -}) => - updateNfcView(_NfcAutoCloseWidget( - child: NfcContentWidget( - title: title, - subtitle: subtitle, - icon: icon, - ), - )); +NfcEventCommand autoClose( + {String? title, + String? subtitle, + Widget? icon, + bool showIfHidden = true}) => + setNfcView( + _NfcAutoCloseWidget( + child: NfcContentWidget( + title: title, + subtitle: subtitle, + icon: icon, + ), + ), + showIfHidden: showIfHidden); class _NfcAutoCloseWidget extends ConsumerWidget { final Widget child; @@ -44,7 +46,7 @@ class _NfcAutoCloseWidget extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { ref.listen(androidNfcActivityProvider, (previous, current) { if (current == NfcActivity.ready) { - ref.read(nfcEventCommandNotifier.notifier).sendCommand(hideNfcView(0)); + ref.read(nfcEventCommandNotifier.notifier).sendCommand(hideNfcView()); } }); diff --git a/lib/android/views/nfc/nfc_count_down_close_widget.dart b/lib/android/views/nfc/nfc_count_down_close_widget.dart index f6cf39ca..6620d893 100644 --- a/lib/android/views/nfc/nfc_count_down_close_widget.dart +++ b/lib/android/views/nfc/nfc_count_down_close_widget.dart @@ -30,7 +30,7 @@ NfcEventCommand countDownClose({ String? subtitle, Widget? icon, }) => - updateNfcView(_CountDownCloseWidget( + setNfcView(_CountDownCloseWidget( closeInSec: closeInSec, child: NfcContentWidget( title: title, @@ -109,6 +109,6 @@ class _CountDownCloseWidgetState extends ConsumerState<_CountDownCloseWidget> { } void hideNow() { - ref.read(nfcEventCommandNotifier.notifier).sendCommand(hideNfcView(0)); + ref.read(nfcEventCommandNotifier.notifier).sendCommand(hideNfcView()); } } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index b2a60a02..d65a02b2 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -949,6 +949,7 @@ "s_nfc_accessing_yubikey": null, "s_nfc_scan_yubikey": null, "s_nfc_scan_again": null, + "s_nfc_scan_success": null, "c_nfc_unlock": null, "s_nfc_unlock_processing": null, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ec8d55db..9f9f3191 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -949,6 +949,7 @@ "s_nfc_accessing_yubikey": "Accessing YubiKey", "s_nfc_scan_yubikey": "Scan your YubiKey", "s_nfc_scan_again": "Scan again", + "s_nfc_scan_success": "Scanned your Yubikey", "c_nfc_unlock": "unlock", "s_nfc_unlock_processing": "Unlocking", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index d717bc95..fe3b8c42 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -949,6 +949,7 @@ "s_nfc_accessing_yubikey": null, "s_nfc_scan_yubikey": null, "s_nfc_scan_again": null, + "s_nfc_scan_success": null, "c_nfc_unlock": null, "s_nfc_unlock_processing": null, diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index 19fd6718..484c385b 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -949,6 +949,7 @@ "s_nfc_accessing_yubikey": null, "s_nfc_scan_yubikey": null, "s_nfc_scan_again": null, + "s_nfc_scan_success": null, "c_nfc_unlock": null, "s_nfc_unlock_processing": null, diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 65b8d183..352c4c20 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -949,6 +949,7 @@ "s_nfc_accessing_yubikey": null, "s_nfc_scan_yubikey": null, "s_nfc_scan_again": null, + "s_nfc_scan_success": null, "c_nfc_unlock": null, "s_nfc_unlock_processing": null, diff --git a/lib/l10n/app_vi.arb b/lib/l10n/app_vi.arb index a3036aaa..15247254 100644 --- a/lib/l10n/app_vi.arb +++ b/lib/l10n/app_vi.arb @@ -949,6 +949,7 @@ "s_nfc_accessing_yubikey": null, "s_nfc_scan_yubikey": null, "s_nfc_scan_again": null, + "s_nfc_scan_success": null, "c_nfc_unlock": null, "s_nfc_unlock_processing": null,