Address review comments.

This commit is contained in:
Dain Nilsson 2022-01-18 15:46:42 +01:00
parent 01a9628b81
commit d7c04f5103
No known key found for this signature in database
GPG Key ID: F04367096FBA95E8
8 changed files with 37 additions and 39 deletions

View File

@ -3,7 +3,6 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import '../../management/models.dart'; import '../../management/models.dart';
part 'models.freezed.dart'; part 'models.freezed.dart';
//part 'models.g.dart';
enum SubPage { authenticator, yubikey } enum SubPage { authenticator, yubikey }
@ -21,19 +20,6 @@ class DeviceNode with _$DeviceNode {
factory DeviceNode.nfcReader(List<String> path, String name) = NfcReaderNode; factory DeviceNode.nfcReader(List<String> path, String name) = NfcReaderNode;
} }
/*
@freezed
class DeviceNode with _$DeviceNode {
factory DeviceNode(
List<String> path,
int pid,
Transport transport,
String name,
DeviceInfo info,
) = _DeviceNode;
}
*/
@freezed @freezed
class MenuAction with _$MenuAction { class MenuAction with _$MenuAction {
factory MenuAction( factory MenuAction(

View File

@ -14,6 +14,12 @@ import '../core/rpc.dart';
import '../oath/menu_actions.dart'; import '../oath/menu_actions.dart';
import 'models.dart'; import 'models.dart';
const _usbPollDelay = Duration(milliseconds: 500);
const _nfcPollDelay = Duration(milliseconds: 2500);
const _nfcAttachPollDelay = Duration(seconds: 1);
const _nfcDetachPollDelay = Duration(seconds: 5);
final log = Logger('app.state'); final log = Logger('app.state');
final windowStateProvider = final windowStateProvider =
@ -184,7 +190,7 @@ class UsbDeviceNotifier extends StateNotifier<List<UsbYubiKeyNode>> {
} }
if (mounted) { if (mounted) {
_pollTimer = Timer(const Duration(milliseconds: 500), _pollDevices); _pollTimer = Timer(_usbPollDelay, _pollDevices);
} }
} }
} }
@ -241,7 +247,7 @@ class NfcDeviceNotifier extends StateNotifier<List<NfcReaderNode>> {
} }
if (mounted) { if (mounted) {
_pollTimer = Timer(const Duration(milliseconds: 2500), _pollReaders); _pollTimer = Timer(_nfcPollDelay, _pollReaders);
} }
} }
} }
@ -361,7 +367,9 @@ class CurrentDeviceDataNotifier extends StateNotifier<YubiKeyData?> {
log.severe('Error polling NFC', jsonEncode(e)); log.severe('Error polling NFC', jsonEncode(e));
} }
if (mounted) { if (mounted) {
_pollTimer = Timer(Duration(seconds: state == null ? 1 : 5), _pollReader); _pollTimer = Timer(
state == null ? _nfcAttachPollDelay : _nfcDetachPollDelay,
_pollReader);
} }
} }
} }

View File

@ -4,6 +4,10 @@ import 'package:yubico_authenticator/management/models.dart';
import '../models.dart'; import '../models.dart';
import 'device_images.dart'; import 'device_images.dart';
/*
TODO: This class should be refactored once we settle more on the final design.
We may want to have two separate implementations depending on if it's an NFC reader or a USB YubiKey.
*/
class DeviceAvatar extends StatelessWidget { class DeviceAvatar extends StatelessWidget {
final DeviceNode node; final DeviceNode node;
final String name; final String name;

View File

@ -18,9 +18,7 @@ class MainActionsDialog extends ConsumerWidget {
final currentNode = ref.watch(currentDeviceProvider); final currentNode = ref.watch(currentDeviceProvider);
final data = ref.watch(currentDeviceDataProvider); final data = ref.watch(currentDeviceDataProvider);
final actions = ref.watch(menuActionsProvider)(context); final actions = ref.watch(menuActionsProvider)(context);
//final nfcReaders = ref.watch(nfcDevicesProvider);
//final allDevices = devices + nfcReaders;
if (currentNode != null) { if (currentNode != null) {
devices.removeWhere((e) => _listEquals(e.path, currentNode.path)); devices.removeWhere((e) => _listEquals(e.path, currentNode.path));
} }

View File

@ -28,7 +28,7 @@ class MainPage extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final currentDevice = ref.watch(currentDeviceDataProvider); final deviceData = ref.watch(currentDeviceDataProvider);
final subPage = ref.watch(subPageProvider); final subPage = ref.watch(subPageProvider);
return Scaffold( return Scaffold(
@ -59,7 +59,7 @@ class MainPage extends ConsumerWidget {
InkWell( InkWell(
child: Padding( child: Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: currentDevice == null child: deviceData == null
? SizedBox.square( ? SizedBox.square(
dimension: 44, dimension: 44,
child: Icon( child: Icon(
@ -68,9 +68,9 @@ class MainPage extends ConsumerWidget {
), ),
) )
: DeviceAvatar( : DeviceAvatar(
currentDevice.node, deviceData.node,
currentDevice.name, deviceData.name,
currentDevice.info, deviceData.info,
selected: true, selected: true,
), ),
), ),
@ -84,7 +84,7 @@ class MainPage extends ConsumerWidget {
], ],
), ),
drawer: const MainPageDrawer(), drawer: const MainPageDrawer(),
body: _buildSubPage(subPage, currentDevice), body: _buildSubPage(subPage, deviceData),
); );
} }
} }

View File

@ -5,10 +5,11 @@ import '../models.dart';
import 'account_view.dart'; import 'account_view.dart';
class AccountList extends StatelessWidget { class AccountList extends StatelessWidget {
final YubiKeyData device; final YubiKeyData deviceData;
final List<OathPair> credentials; final List<OathPair> credentials;
final List<String> favorites; final List<String> favorites;
const AccountList(this.device, this.credentials, this.favorites, {Key? key}) const AccountList(this.deviceData, this.credentials, this.favorites,
{Key? key})
: super(key: key); : super(key: key);
@override @override
@ -34,7 +35,7 @@ class AccountList extends StatelessWidget {
), ),
), ),
...favCreds.map( ...favCreds.map(
(entry) => AccountView(device, entry.credential, entry.code), (entry) => AccountView(deviceData, entry.credential, entry.code),
), ),
if (creds.isNotEmpty) if (creds.isNotEmpty)
ListTile( ListTile(
@ -44,7 +45,7 @@ class AccountList extends StatelessWidget {
), ),
), ),
...creds.map( ...creds.map(
(entry) => AccountView(device, entry.credential, entry.code), (entry) => AccountView(deviceData, entry.credential, entry.code),
), ),
], ],
); );

View File

@ -35,10 +35,10 @@ class _ExpireNotifier extends StateNotifier<bool> {
} }
class AccountView extends ConsumerWidget { class AccountView extends ConsumerWidget {
final YubiKeyData device; final YubiKeyData deviceData;
final OathCredential credential; final OathCredential credential;
final OathCode? code; final OathCode? code;
const AccountView(this.device, this.credential, this.code, {Key? key}) const AccountView(this.deviceData, this.credential, this.code, {Key? key})
: super(key: key); : super(key: key);
String formatCode() { String formatCode() {
@ -73,7 +73,8 @@ class AccountView extends ConsumerWidget {
ref.read(favoritesProvider.notifier).toggleFavorite(credential.id); ref.read(favoritesProvider.notifier).toggleFavorite(credential.id);
}, },
), ),
if (device.info.version.major >= 5 && device.info.version.minor >= 3) if (deviceData.info.version.major >= 5 &&
deviceData.info.version.minor >= 3)
PopupMenuItem( PopupMenuItem(
child: const ListTile( child: const ListTile(
leading: Icon(Icons.edit), leading: Icon(Icons.edit),
@ -117,7 +118,7 @@ class AccountView extends ConsumerWidget {
} }
try { try {
await ref await ref
.read(credentialListProvider(device.node.path).notifier) .read(credentialListProvider(deviceData.node.path).notifier)
.calculate(credential); .calculate(credential);
} finally { } finally {
close?.call(); close?.call();

View File

@ -6,12 +6,12 @@ import '../state.dart';
import 'account_list.dart'; import 'account_list.dart';
class OathScreen extends ConsumerWidget { class OathScreen extends ConsumerWidget {
final YubiKeyData device; final YubiKeyData deviceData;
const OathScreen(this.device, {Key? key}) : super(key: key); const OathScreen(this.deviceData, {Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final state = ref.watch(oathStateProvider(device.node.path)); final state = ref.watch(oathStateProvider(deviceData.node.path));
if (state == null) { if (state == null) {
return Column( return Column(
@ -35,7 +35,7 @@ class OathScreen extends ConsumerWidget {
decoration: const InputDecoration(labelText: 'Password'), decoration: const InputDecoration(labelText: 'Password'),
onSubmitted: (value) async { onSubmitted: (value) async {
final result = await ref final result = await ref
.read(oathStateProvider(device.node.path).notifier) .read(oathStateProvider(deviceData.node.path).notifier)
.unlock(value); .unlock(value);
if (!result) { if (!result) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
@ -51,7 +51,7 @@ class OathScreen extends ConsumerWidget {
), ),
); );
} else { } else {
final accounts = ref.watch(credentialListProvider(device.node.path)); final accounts = ref.watch(credentialListProvider(deviceData.node.path));
if (accounts == null) { if (accounts == null) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -61,7 +61,7 @@ class OathScreen extends ConsumerWidget {
); );
} }
return AccountList( return AccountList(
device, deviceData,
ref.watch(filteredCredentialsProvider(accounts)), ref.watch(filteredCredentialsProvider(accounts)),
ref.watch(favoritesProvider), ref.watch(favoritesProvider),
); );