mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-12-29 05:03:05 +03:00
140 lines
3.6 KiB
Dart
Executable File
140 lines
3.6 KiB
Dart
Executable File
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:yubico_authenticator/management/models.dart';
|
|
import 'package:collection/collection.dart';
|
|
|
|
import '../models.dart';
|
|
import '../state.dart';
|
|
import 'device_avatar.dart';
|
|
|
|
Function _listEquals = const ListEquality().equals;
|
|
|
|
class MainActionsDialog extends ConsumerWidget {
|
|
const MainActionsDialog({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final devices = ref.watch(attachedDevicesProvider).toList();
|
|
final currentNode = ref.watch(currentDeviceProvider);
|
|
final data = ref.watch(currentDeviceDataProvider);
|
|
final actions = ref.watch(menuActionsProvider)(context);
|
|
|
|
if (currentNode != null) {
|
|
devices.removeWhere((e) => _listEquals(e.path, currentNode.path));
|
|
}
|
|
|
|
return SimpleDialog(
|
|
children: [
|
|
if (currentNode != null)
|
|
_CurrentDeviceRow(
|
|
currentNode,
|
|
data: data,
|
|
onTap: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
...devices.map(
|
|
(e) => _DeviceRow(
|
|
e,
|
|
info: e.map(
|
|
usbYubiKey: (node) => node.info,
|
|
nfcReader: (_) => null,
|
|
),
|
|
onTap: () {
|
|
Navigator.of(context).pop();
|
|
ref.read(currentDeviceProvider.notifier).setCurrentDevice(e);
|
|
},
|
|
),
|
|
),
|
|
if (currentNode == null && devices.isEmpty)
|
|
Center(
|
|
child: Text(
|
|
'No YubiKey found',
|
|
style: Theme.of(context).textTheme.titleMedium,
|
|
)),
|
|
if (actions.isNotEmpty) const Divider(),
|
|
...actions.map((a) => ListTile(
|
|
dense: true,
|
|
leading: a.icon,
|
|
title: Text(a.text),
|
|
onTap: () {
|
|
Navigator.of(context).pop();
|
|
a.action?.call();
|
|
},
|
|
)),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class _CurrentDeviceRow extends StatelessWidget {
|
|
final DeviceNode node;
|
|
final YubiKeyData? data;
|
|
final Function() onTap;
|
|
|
|
const _CurrentDeviceRow(
|
|
this.node, {
|
|
this.data,
|
|
required this.onTap,
|
|
Key? key,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final subtitle = node.when(
|
|
usbYubiKey: (_, __, ___, info) =>
|
|
'S/N: ${info.serial} F/W: ${info.version}',
|
|
nfcReader: (_, name) {
|
|
final info = data?.info;
|
|
return info == null
|
|
? name
|
|
: '$name\nS/N: ${info.serial} F/W: ${info.version}';
|
|
});
|
|
|
|
return ListTile(
|
|
leading: data != null
|
|
? DeviceAvatar.yubiKeyData(
|
|
data!,
|
|
selected: true,
|
|
)
|
|
: DeviceAvatar.deviceNode(
|
|
node,
|
|
selected: true,
|
|
),
|
|
title: Text(data?.name ?? 'No YubiKey present'),
|
|
isThreeLine: subtitle.contains('\n'),
|
|
subtitle: Text(subtitle),
|
|
onTap: onTap,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _DeviceRow extends StatelessWidget {
|
|
final DeviceNode node;
|
|
final DeviceInfo? info;
|
|
final Function() onTap;
|
|
|
|
const _DeviceRow(
|
|
this.node, {
|
|
required this.info,
|
|
required this.onTap,
|
|
Key? key,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ListTile(
|
|
leading: DeviceAvatar.deviceNode(node),
|
|
title: Text(node.name),
|
|
subtitle: Text(
|
|
node.when(
|
|
usbYubiKey: (_, __, ___, info) =>
|
|
'S/N: ${info.serial} F/W: ${info.version}',
|
|
nfcReader: (_, __) => 'Select to scan',
|
|
),
|
|
),
|
|
onTap: onTap,
|
|
);
|
|
}
|
|
}
|