update flutter file structure

This commit is contained in:
Adam Velebil 2024-09-09 10:31:03 +02:00
parent ec4288927e
commit 937893ae37
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
15 changed files with 170 additions and 377 deletions

View File

@ -32,7 +32,7 @@ import '../../exception/no_data_exception.dart';
import '../../exception/platform_exception_decoder.dart';
import '../../fido/models.dart';
import '../../fido/state.dart';
import '../method_channel_notifier.dart';
import '../overlay/nfc/method_channel_notifier.dart';
final _log = Logger('android.fido.state');

View File

@ -40,10 +40,10 @@ import 'logger.dart';
import 'management/state.dart';
import 'oath/otp_auth_link_handler.dart';
import 'oath/state.dart';
import 'overlay/nfc/nfc_event_notifier.dart';
import 'overlay/nfc/nfc_overlay_provider.dart';
import 'qr_scanner/qr_scanner_provider.dart';
import 'state.dart';
import 'tap_request_dialog.dart';
import 'views/nfc/nfc_activity_command_listener.dart';
import 'window_state_provider.dart';
Future<Widget> initialize() async {
@ -123,7 +123,7 @@ Future<Widget> initialize() async {
ref.read(androidWindowStateProvider);
// initializes global handler for dialogs
ref.read(androidDialogProvider);
ref.read(nfcOverlayProvider);
// set context which will handle otpauth links
setupOtpAuthLinkHandler(context);

View File

@ -36,8 +36,8 @@ import '../../exception/platform_exception_decoder.dart';
import '../../oath/models.dart';
import '../../oath/state.dart';
import '../../widgets/toast.dart';
import '../method_channel_notifier.dart';
import '../tap_request_dialog.dart';
import '../overlay/nfc/method_channel_notifier.dart';
import '../overlay/nfc/nfc_overlay_provider.dart';
final _log = Logger('android.oath.state');
@ -156,7 +156,7 @@ Exception handlePlatformException(
toast(String message, {bool popStack = false}) =>
withContext((context) async {
ref.read(androidDialogProvider.notifier).closeDialog();
ref.read(nfcOverlayProvider.notifier).hideOverlay();
if (popStack) {
Navigator.of(context).popUntil((route) {
return route.isFirst;

View File

@ -17,7 +17,7 @@
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'tap_request_dialog.dart';
import 'nfc_overlay_provider.dart';
class MethodChannelNotifier extends Notifier<void> {
final MethodChannel _channel;
@ -30,7 +30,7 @@ class MethodChannelNotifier extends Notifier<void> {
Future<dynamic> invoke(String name,
[Map<String, dynamic> params = const {}]) async {
final result = await _channel.invokeMethod(name, params['callArgs']);
await ref.read(androidDialogProvider.notifier).waitForDialogClosed();
await ref.read(nfcOverlayProvider.notifier).waitForHide();
return result;
}
}

View File

@ -15,15 +15,15 @@
*/
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
class NfcIconSuccess extends StatelessWidget {
const NfcIconSuccess({super.key});
part 'models.freezed.dart';
@override
Widget build(BuildContext context) => Icon(
Symbols.check,
size: 64,
color: Theme.of(context).colorScheme.primary,
);
@freezed
class NfcOverlayWidgetProperties with _$NfcOverlayWidgetProperties {
factory NfcOverlayWidgetProperties({
required Widget child,
@Default(false) bool visible,
@Default(false) bool hasCloseButton,
}) = _NfcOverlayWidgetProperties;
}

View File

@ -15,41 +15,40 @@ final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
/// @nodoc
mixin _$NfcActivityWidgetProperties {
mixin _$NfcOverlayWidgetProperties {
Widget get child => throw _privateConstructorUsedError;
bool get visible => throw _privateConstructorUsedError;
bool get hasCloseButton => throw _privateConstructorUsedError;
/// Create a copy of NfcActivityWidgetProperties
/// Create a copy of NfcOverlayWidgetProperties
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$NfcActivityWidgetPropertiesCopyWith<NfcActivityWidgetProperties>
$NfcOverlayWidgetPropertiesCopyWith<NfcOverlayWidgetProperties>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $NfcActivityWidgetPropertiesCopyWith<$Res> {
factory $NfcActivityWidgetPropertiesCopyWith(
NfcActivityWidgetProperties value,
$Res Function(NfcActivityWidgetProperties) then) =
_$NfcActivityWidgetPropertiesCopyWithImpl<$Res,
NfcActivityWidgetProperties>;
abstract class $NfcOverlayWidgetPropertiesCopyWith<$Res> {
factory $NfcOverlayWidgetPropertiesCopyWith(NfcOverlayWidgetProperties value,
$Res Function(NfcOverlayWidgetProperties) then) =
_$NfcOverlayWidgetPropertiesCopyWithImpl<$Res,
NfcOverlayWidgetProperties>;
@useResult
$Res call({Widget child, bool visible, bool hasCloseButton});
}
/// @nodoc
class _$NfcActivityWidgetPropertiesCopyWithImpl<$Res,
$Val extends NfcActivityWidgetProperties>
implements $NfcActivityWidgetPropertiesCopyWith<$Res> {
_$NfcActivityWidgetPropertiesCopyWithImpl(this._value, this._then);
class _$NfcOverlayWidgetPropertiesCopyWithImpl<$Res,
$Val extends NfcOverlayWidgetProperties>
implements $NfcOverlayWidgetPropertiesCopyWith<$Res> {
_$NfcOverlayWidgetPropertiesCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of NfcActivityWidgetProperties
/// Create a copy of NfcOverlayWidgetProperties
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
@ -76,28 +75,28 @@ class _$NfcActivityWidgetPropertiesCopyWithImpl<$Res,
}
/// @nodoc
abstract class _$$NfcActivityWidgetPropertiesImplCopyWith<$Res>
implements $NfcActivityWidgetPropertiesCopyWith<$Res> {
factory _$$NfcActivityWidgetPropertiesImplCopyWith(
_$NfcActivityWidgetPropertiesImpl value,
$Res Function(_$NfcActivityWidgetPropertiesImpl) then) =
__$$NfcActivityWidgetPropertiesImplCopyWithImpl<$Res>;
abstract class _$$NfcOverlayWidgetPropertiesImplCopyWith<$Res>
implements $NfcOverlayWidgetPropertiesCopyWith<$Res> {
factory _$$NfcOverlayWidgetPropertiesImplCopyWith(
_$NfcOverlayWidgetPropertiesImpl value,
$Res Function(_$NfcOverlayWidgetPropertiesImpl) then) =
__$$NfcOverlayWidgetPropertiesImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({Widget child, bool visible, bool hasCloseButton});
}
/// @nodoc
class __$$NfcActivityWidgetPropertiesImplCopyWithImpl<$Res>
extends _$NfcActivityWidgetPropertiesCopyWithImpl<$Res,
_$NfcActivityWidgetPropertiesImpl>
implements _$$NfcActivityWidgetPropertiesImplCopyWith<$Res> {
__$$NfcActivityWidgetPropertiesImplCopyWithImpl(
_$NfcActivityWidgetPropertiesImpl _value,
$Res Function(_$NfcActivityWidgetPropertiesImpl) _then)
class __$$NfcOverlayWidgetPropertiesImplCopyWithImpl<$Res>
extends _$NfcOverlayWidgetPropertiesCopyWithImpl<$Res,
_$NfcOverlayWidgetPropertiesImpl>
implements _$$NfcOverlayWidgetPropertiesImplCopyWith<$Res> {
__$$NfcOverlayWidgetPropertiesImplCopyWithImpl(
_$NfcOverlayWidgetPropertiesImpl _value,
$Res Function(_$NfcOverlayWidgetPropertiesImpl) _then)
: super(_value, _then);
/// Create a copy of NfcActivityWidgetProperties
/// Create a copy of NfcOverlayWidgetProperties
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
@ -106,7 +105,7 @@ class __$$NfcActivityWidgetPropertiesImplCopyWithImpl<$Res>
Object? visible = null,
Object? hasCloseButton = null,
}) {
return _then(_$NfcActivityWidgetPropertiesImpl(
return _then(_$NfcOverlayWidgetPropertiesImpl(
child: null == child
? _value.child
: child // ignore: cast_nullable_to_non_nullable
@ -125,9 +124,8 @@ class __$$NfcActivityWidgetPropertiesImplCopyWithImpl<$Res>
/// @nodoc
class _$NfcActivityWidgetPropertiesImpl
implements _NfcActivityWidgetProperties {
_$NfcActivityWidgetPropertiesImpl(
class _$NfcOverlayWidgetPropertiesImpl implements _NfcOverlayWidgetProperties {
_$NfcOverlayWidgetPropertiesImpl(
{required this.child, this.visible = false, this.hasCloseButton = false});
@override
@ -141,14 +139,14 @@ class _$NfcActivityWidgetPropertiesImpl
@override
String toString() {
return 'NfcActivityWidgetProperties(child: $child, visible: $visible, hasCloseButton: $hasCloseButton)';
return 'NfcOverlayWidgetProperties(child: $child, visible: $visible, hasCloseButton: $hasCloseButton)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$NfcActivityWidgetPropertiesImpl &&
other is _$NfcOverlayWidgetPropertiesImpl &&
(identical(other.child, child) || other.child == child) &&
(identical(other.visible, visible) || other.visible == visible) &&
(identical(other.hasCloseButton, hasCloseButton) ||
@ -158,22 +156,22 @@ class _$NfcActivityWidgetPropertiesImpl
@override
int get hashCode => Object.hash(runtimeType, child, visible, hasCloseButton);
/// Create a copy of NfcActivityWidgetProperties
/// Create a copy of NfcOverlayWidgetProperties
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$NfcActivityWidgetPropertiesImplCopyWith<_$NfcActivityWidgetPropertiesImpl>
get copyWith => __$$NfcActivityWidgetPropertiesImplCopyWithImpl<
_$NfcActivityWidgetPropertiesImpl>(this, _$identity);
_$$NfcOverlayWidgetPropertiesImplCopyWith<_$NfcOverlayWidgetPropertiesImpl>
get copyWith => __$$NfcOverlayWidgetPropertiesImplCopyWithImpl<
_$NfcOverlayWidgetPropertiesImpl>(this, _$identity);
}
abstract class _NfcActivityWidgetProperties
implements NfcActivityWidgetProperties {
factory _NfcActivityWidgetProperties(
abstract class _NfcOverlayWidgetProperties
implements NfcOverlayWidgetProperties {
factory _NfcOverlayWidgetProperties(
{required final Widget child,
final bool visible,
final bool hasCloseButton}) = _$NfcActivityWidgetPropertiesImpl;
final bool hasCloseButton}) = _$NfcOverlayWidgetPropertiesImpl;
@override
Widget get child;
@ -182,10 +180,10 @@ abstract class _NfcActivityWidgetProperties
@override
bool get hasCloseButton;
/// Create a copy of NfcActivityWidgetProperties
/// Create a copy of NfcOverlayWidgetProperties
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$NfcActivityWidgetPropertiesImplCopyWith<_$NfcActivityWidgetPropertiesImpl>
_$$NfcOverlayWidgetPropertiesImplCopyWith<_$NfcOverlayWidgetPropertiesImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -20,11 +20,41 @@ import 'package:logging/logging.dart';
import '../../../app/logging.dart';
import '../../../app/state.dart';
import '../../tap_request_dialog.dart';
import 'models.dart';
import 'nfc_activity_overlay.dart';
import 'nfc_overlay_provider.dart';
import 'views/nfc_overlay_widget.dart';
final _log = Logger('android.nfc_activity_command_listener');
final _log = Logger('android.nfc_event_notifier');
class NfcEvent {
const NfcEvent();
}
class NfcHideViewEvent extends NfcEvent {
final Duration delay;
const NfcHideViewEvent({this.delay = Duration.zero});
}
class NfcSetViewEvent extends NfcEvent {
final Widget child;
final bool showIfHidden;
const NfcSetViewEvent({required this.child, this.showIfHidden = true});
}
final nfcEventNotifier =
NotifierProvider<_NfcEventNotifier, NfcEvent>(_NfcEventNotifier.new);
class _NfcEventNotifier extends Notifier<NfcEvent> {
@override
NfcEvent build() {
return const NfcEvent();
}
void send(NfcEvent event) {
state = event;
}
}
final nfcEventNotifierListener = Provider<_NfcEventNotifierListener>(
(ref) => _NfcEventNotifierListener(ref));
@ -45,7 +75,7 @@ class _NfcEventNotifierListener {
_show(context, a.child);
} else {
_ref
.read(nfcActivityWidgetPropertiesNotifier.notifier)
.read(nfcOverlayWidgetProperties.notifier)
.update(child: a.child);
}
break;
@ -57,18 +87,18 @@ class _NfcEventNotifierListener {
}
void _show(BuildContext context, Widget child) async {
final notifier = _ref.read(nfcActivityWidgetPropertiesNotifier.notifier);
final notifier = _ref.read(nfcOverlayWidgetProperties.notifier);
notifier.update(child: child);
if (!visible) {
visible = true;
final result = await showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return const NfcActivityWidget();
return const NfcOverlayWidget();
});
if (result == null) {
// the modal sheet was cancelled by Back button, close button or dismiss
_ref.read(androidDialogProvider.notifier).cancelDialog();
_ref.read(nfcOverlayProvider.notifier).onCancel();
}
visible = false;
}
@ -86,9 +116,8 @@ class _NfcEventNotifierListener {
}
bool get visible =>
_ref.read(nfcActivityWidgetPropertiesNotifier.select((s) => s.visible));
_ref.read(nfcOverlayWidgetProperties.select((s) => s.visible));
set visible(bool visible) => _ref
.read(nfcActivityWidgetPropertiesNotifier.notifier)
.update(visible: visible);
set visible(bool visible) =>
_ref.read(nfcOverlayWidgetProperties.notifier).update(visible: visible);
}

View File

@ -20,23 +20,21 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart';
import '../app/logging.dart';
import '../app/state.dart';
import 'state.dart';
import 'views/nfc/models.dart';
import 'views/nfc/nfc_activity_overlay.dart';
import 'views/nfc/nfc_content_widget.dart';
import 'views/nfc/nfc_failure_icon.dart';
import 'views/nfc/nfc_progress_bar.dart';
import 'views/nfc/nfc_success_icon.dart';
import '../../../app/logging.dart';
import '../../../app/state.dart';
import '../../state.dart';
import 'nfc_event_notifier.dart';
import 'views/nfc_content_widget.dart';
import 'views/nfc_overlay_icons.dart';
import 'views/nfc_overlay_widget.dart';
final _log = Logger('android.tap_request_dialog');
const _channel = MethodChannel('com.yubico.authenticator.channel.dialog');
final androidDialogProvider =
NotifierProvider<_DialogProvider, int>(_DialogProvider.new);
final nfcOverlayProvider =
NotifierProvider<_NfcOverlayProvider, int>(_NfcOverlayProvider.new);
class _DialogProvider extends Notifier<int> {
class _NfcOverlayProvider extends Notifier<int> {
Timer? processingViewTimeout;
late final l10n = ref.read(l10nProvider);
@ -81,7 +79,7 @@ class _DialogProvider extends Notifier<int> {
break;
case 'close':
closeDialog();
hideOverlay();
break;
default:
@ -95,9 +93,7 @@ class _DialogProvider extends Notifier<int> {
}
NfcEvent showTapYourYubiKey() {
ref
.read(nfcActivityWidgetPropertiesNotifier.notifier)
.update(hasCloseButton: true);
ref.read(nfcOverlayWidgetProperties.notifier).update(hasCloseButton: true);
return NfcSetViewEvent(
child: NfcContentWidget(
title: l10n.s_nfc_ready_to_scan,
@ -107,9 +103,7 @@ class _DialogProvider extends Notifier<int> {
}
NfcEvent showHoldStill() {
ref
.read(nfcActivityWidgetPropertiesNotifier.notifier)
.update(hasCloseButton: false);
ref.read(nfcOverlayWidgetProperties.notifier).update(hasCloseButton: false);
return NfcSetViewEvent(
child: NfcContentWidget(
title: l10n.s_nfc_ready_to_scan,
@ -119,9 +113,7 @@ class _DialogProvider extends Notifier<int> {
}
NfcEvent showDone() {
ref
.read(nfcActivityWidgetPropertiesNotifier.notifier)
.update(hasCloseButton: false);
ref.read(nfcOverlayWidgetProperties.notifier).update(hasCloseButton: false);
return NfcSetViewEvent(
child: NfcContentWidget(
title: l10n.s_nfc_ready_to_scan,
@ -132,9 +124,7 @@ class _DialogProvider extends Notifier<int> {
}
NfcEvent showFailed() {
ref
.read(nfcActivityWidgetPropertiesNotifier.notifier)
.update(hasCloseButton: true);
ref.read(nfcOverlayWidgetProperties.notifier).update(hasCloseButton: true);
return NfcSetViewEvent(
child: NfcContentWidget(
title: l10n.s_nfc_ready_to_scan,
@ -144,22 +134,21 @@ class _DialogProvider extends Notifier<int> {
showIfHidden: false);
}
void closeDialog() {
void hideOverlay() {
ref.read(nfcEventNotifier.notifier).send(const NfcHideViewEvent());
}
void cancelDialog() async {
void onCancel() async {
await _channel.invokeMethod('cancel');
}
Future<void> waitForDialogClosed() async {
Future<void> waitForHide() async {
final completer = Completer();
Timer.periodic(
const Duration(milliseconds: 200),
(timer) {
if (ref.read(
nfcActivityWidgetPropertiesNotifier.select((s) => !s.visible))) {
if (ref.read(nfcOverlayWidgetProperties.select((s) => !s.visible))) {
timer.cancel();
completer.complete();
}

View File

@ -1,3 +1,19 @@
/*
* Copyright (C) 2024 Yubico.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

View File

@ -55,3 +55,25 @@ class NfcIconProgressBar extends StatelessWidget {
),
);
}
class NfcIconSuccess extends StatelessWidget {
const NfcIconSuccess({super.key});
@override
Widget build(BuildContext context) => Icon(
Symbols.check,
size: 64,
color: Theme.of(context).colorScheme.primary,
);
}
class NfcIconFailure extends StatelessWidget {
const NfcIconFailure({super.key});
@override
Widget build(BuildContext context) => Icon(
Symbols.close,
size: 64,
color: Theme.of(context).colorScheme.error,
);
}

View File

@ -18,31 +18,16 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'models.dart';
import '../models.dart';
final nfcEventNotifier =
NotifierProvider<_NfcEventNotifier, NfcEvent>(_NfcEventNotifier.new);
final nfcOverlayWidgetProperties =
NotifierProvider<_NfcOverlayWidgetProperties, NfcOverlayWidgetProperties>(
_NfcOverlayWidgetProperties.new);
class _NfcEventNotifier extends Notifier<NfcEvent> {
class _NfcOverlayWidgetProperties extends Notifier<NfcOverlayWidgetProperties> {
@override
NfcEvent build() {
return const NfcEvent();
}
void send(NfcEvent event) {
state = event;
}
}
final nfcActivityWidgetPropertiesNotifier = NotifierProvider<
_NfcActivityWidgetPropertiesNotifier,
NfcActivityWidgetProperties>(_NfcActivityWidgetPropertiesNotifier.new);
class _NfcActivityWidgetPropertiesNotifier
extends Notifier<NfcActivityWidgetProperties> {
@override
NfcActivityWidgetProperties build() {
return NfcActivityWidgetProperties(child: const SizedBox());
NfcOverlayWidgetProperties build() {
return NfcOverlayWidgetProperties(child: const SizedBox());
}
void update({
@ -57,15 +42,14 @@ class _NfcActivityWidgetPropertiesNotifier
}
}
class NfcActivityWidget extends ConsumerWidget {
const NfcActivityWidget({super.key});
class NfcOverlayWidget extends ConsumerWidget {
const NfcOverlayWidget({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final widget =
ref.watch(nfcActivityWidgetPropertiesNotifier.select((s) => s.child));
final showCloseButton = ref.watch(
nfcActivityWidgetPropertiesNotifier.select((s) => s.hasCloseButton));
final widget = ref.watch(nfcOverlayWidgetProperties.select((s) => s.child));
final showCloseButton =
ref.watch(nfcOverlayWidgetProperties.select((s) => s.hasCloseButton));
return Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) 2024 Yubico.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'models.freezed.dart';
class NfcEvent {
const NfcEvent();
}
class NfcHideViewEvent extends NfcEvent {
final Duration delay;
const NfcHideViewEvent({this.delay = Duration.zero});
}
class NfcSetViewEvent extends NfcEvent {
final Widget child;
final bool showIfHidden;
const NfcSetViewEvent({required this.child, this.showIfHidden = true});
}
@freezed
class NfcActivityWidgetProperties with _$NfcActivityWidgetProperties {
factory NfcActivityWidgetProperties({
required Widget child,
@Default(false) bool visible,
@Default(false) bool hasCloseButton,
}) = _NfcActivityWidgetProperties;
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 2024 Yubico.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../state.dart';
import 'models.dart';
import 'nfc_activity_overlay.dart';
import 'nfc_content_widget.dart';
NfcEvent autoClose(
{required String title,
required String subtitle,
required Widget icon,
bool showIfHidden = true}) =>
NfcSetViewEvent(
child: _NfcAutoCloseWidget(
child: NfcContentWidget(
title: title,
subtitle: subtitle,
icon: icon,
),
),
showIfHidden: showIfHidden);
class _NfcAutoCloseWidget extends ConsumerWidget {
final Widget child;
const _NfcAutoCloseWidget({required this.child});
@override
Widget build(BuildContext context, WidgetRef ref) {
ref.listen(androidNfcActivityProvider, (previous, current) {
if (current == NfcActivity.ready) {
ref.read(nfcEventNotifier.notifier).send(const NfcHideViewEvent());
}
});
return child;
}
}

View File

@ -1,115 +0,0 @@
/*
* Copyright (C) 2024 Yubico.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../state.dart';
import 'models.dart';
import 'nfc_activity_overlay.dart';
import 'nfc_content_widget.dart';
NfcEvent countDownClose({
required String title,
required String subtitle,
required Widget icon,
int closeInSec = 3,
}) =>
NfcSetViewEvent(
child: _CountDownCloseWidget(
closeInSec: closeInSec,
child: NfcContentWidget(
title: title,
subtitle: subtitle,
icon: icon,
),
));
class _CountDownCloseWidget extends ConsumerStatefulWidget {
final int closeInSec;
final Widget child;
const _CountDownCloseWidget({required this.child, required this.closeInSec});
@override
ConsumerState<_CountDownCloseWidget> createState() =>
_CountDownCloseWidgetState();
}
class _CountDownCloseWidgetState extends ConsumerState<_CountDownCloseWidget> {
late int counter;
late Timer? timer;
bool shouldHide = false;
@override
Widget build(BuildContext context) {
ref.listen(androidNfcActivityProvider, (previous, current) {
if (current == NfcActivity.ready) {
timer?.cancel();
hideNow();
}
});
return Stack(
fit: StackFit.loose,
children: [
Center(child: widget.child),
Positioned(
bottom: 0,
right: 0,
child: counter > 0
? Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Closing in $counter'),
)
: const SizedBox(),
)
],
);
}
@override
void initState() {
super.initState();
counter = widget.closeInSec;
timer = Timer(const Duration(seconds: 0), onTimer);
}
@override
void dispose() {
timer?.cancel();
super.dispose();
}
void onTimer() async {
timer?.cancel();
setState(() {
counter--;
});
if (counter > 0) {
timer = Timer(const Duration(seconds: 1), onTimer);
} else {
hideNow();
}
}
void hideNow() {
ref.read(nfcEventNotifier.notifier).send(const NfcHideViewEvent());
}
}

View File

@ -1,29 +0,0 @@
/*
* Copyright (C) 2024 Yubico.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
class NfcIconFailure extends StatelessWidget {
const NfcIconFailure({super.key});
@override
Widget build(BuildContext context) => Icon(
Symbols.close,
size: 64,
color: Theme.of(context).colorScheme.error,
);
}