split currentDeviceProvider to desktop and android

This commit is contained in:
Adam Velebil 2022-03-21 09:34:45 +01:00
parent 972fad795e
commit eff800181c
No known key found for this signature in database
GPG Key ID: AC6D6B9D715FC084
5 changed files with 81 additions and 43 deletions

View File

@ -43,5 +43,6 @@ Future<List<Override>> initializeAndGetOverrides() async {
credentialListProvider.overrideWithProvider(androidCredentialListProvider),
currentAppProvider.overrideWithProvider(androidSubPageProvider),
managementStateProvider.overrideWithProvider(androidManagementState),
currentDeviceProvider.overrideWithProvider(androidCurrentDeviceProvider)
];
}

View File

@ -48,3 +48,28 @@ class _AndroidAttachedDevicesNotifier extends AttachedDevicesNotifier {
final androidDeviceDataProvider =
Provider<YubiKeyData?>((ref) => ref.watch(androidYubikeyProvider));
final androidCurrentDeviceProvider =
StateNotifierProvider<CurrentDeviceNotifier, DeviceNode?>((ref) {
final provider = _AndroidCurrentDeviceNotifier();
ref.listen(attachedDevicesProvider, provider._updateAttachedDevices);
return provider;
});
class _AndroidCurrentDeviceNotifier extends CurrentDeviceNotifier {
_AndroidCurrentDeviceNotifier() : super(null);
_updateAttachedDevices(
List<DeviceNode>? previous, List<DeviceNode?> devices) {
if (devices.isNotEmpty) {
state = devices.first;
} else {
state = null;
}
}
@override
setCurrentDevice(DeviceNode device) {
state = device;
}
}

View File

@ -73,51 +73,14 @@ final currentDeviceDataProvider = Provider<YubiKeyData?>(
(ref) => throw UnimplementedError(),
);
// Override with platform implementation
final currentDeviceProvider =
StateNotifierProvider<CurrentDeviceNotifier, DeviceNode?>((ref) {
final provider = CurrentDeviceNotifier(ref.watch(prefProvider));
ref.listen(attachedDevicesProvider, provider._updateAttachedDevices);
return provider;
});
StateNotifierProvider<CurrentDeviceNotifier, DeviceNode?>(
(ref) => throw UnimplementedError());
class CurrentDeviceNotifier extends StateNotifier<DeviceNode?> {
static const String _lastDevice = 'APP_STATE_LAST_DEVICE';
final SharedPreferences _prefs;
CurrentDeviceNotifier(this._prefs) : super(null);
_updateAttachedDevices(List<DeviceNode>? previous, List<DeviceNode> devices) {
if (!devices.contains(state)) {
final lastDevice = _prefs.getString(_lastDevice) ?? '';
try {
state = devices.firstWhere(
(dev) => dev.when(
usbYubiKey: (path, name, pid, info) =>
lastDevice == 'serial:${info?.serial}',
nfcReader: (path, name) => lastDevice == 'name:$name',
), orElse: () {
var usbDevices = devices.whereType<UsbYubiKeyNode>();
return usbDevices.isNotEmpty ? usbDevices.first : devices.first;
});
} on StateError {
state = null;
}
}
}
setCurrentDevice(DeviceNode device) {
state = device;
device.when(
usbYubiKey: (path, name, pid, info) {
final serial = info?.serial;
if (serial != null) {
_prefs.setString(_lastDevice, 'serial:$serial');
}
},
nfcReader: (path, name) {
_prefs.setString(_lastDevice, 'name:$name');
},
);
}
abstract class CurrentDeviceNotifier extends StateNotifier<DeviceNode?> {
CurrentDeviceNotifier(DeviceNode? state) : super(state);
setCurrentDevice(DeviceNode device);
}
final currentAppProvider =

View File

@ -100,5 +100,6 @@ Future<List<Override>> initializeAndGetOverrides(
qrScannerProvider.overrideWithProvider(desktopQrScannerProvider),
managementStateProvider.overrideWithProvider(desktopManagementState),
fidoStateProvider.overrideWithProvider(desktopFidoState),
currentDeviceProvider.overrideWithProvider(desktopCurrentDeviceProvider)
];
}

View File

@ -3,8 +3,10 @@ import 'dart:io';
import 'package:logging/logging.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:window_manager/window_manager.dart';
import '../app/state.dart';
import '../core/state.dart';
import '../app/models.dart';
import 'models.dart';
@ -113,3 +115,49 @@ class _WindowStateNotifier extends StateNotifier<WindowState>
}
}
}
final desktopCurrentDeviceProvider =
StateNotifierProvider<CurrentDeviceNotifier, DeviceNode?>((ref) {
final provider = _DesktopCurrentDeviceNotifier(ref.watch(prefProvider));
ref.listen(attachedDevicesProvider, provider._updateAttachedDevices);
return provider;
});
class _DesktopCurrentDeviceNotifier extends CurrentDeviceNotifier {
static const String _lastDevice = 'APP_STATE_LAST_DEVICE';
final SharedPreferences _prefs;
_DesktopCurrentDeviceNotifier(this._prefs) : super(null);
_updateAttachedDevices(List<DeviceNode>? previous, List<DeviceNode> devices) {
if (!devices.contains(state)) {
final lastDevice = _prefs.getString(_lastDevice) ?? '';
try {
state = devices.firstWhere(
(dev) => dev.when(
usbYubiKey: (path, name, pid, info) =>
lastDevice == 'serial:${info?.serial}',
nfcReader: (path, name) => lastDevice == 'name:$name',
),
orElse: () => devices.whereType<UsbYubiKeyNode>().first);
} on StateError {
state = null;
}
}
}
@override
setCurrentDevice(DeviceNode device) {
state = device;
device.when(
usbYubiKey: (path, name, pid, info) {
final serial = info?.serial;
if (serial != null) {
_prefs.setString(_lastDevice, 'serial:$serial');
}
},
nfcReader: (path, name) {
_prefs.setString(_lastDevice, 'name:$name');
},
);
}
}