update feature file structure

This commit is contained in:
Adam Velebil 2024-01-22 17:57:46 +01:00
parent f21a41c4d4
commit 68238f6742
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
7 changed files with 91 additions and 52 deletions

View File

@ -18,22 +18,14 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'logging.dart'; import '../logging.dart';
import 'models.dart'; import 'models.dart';
final _log = Logger('key_customization'); final _log = Logger('key_customization_manager');
final keyCustomizationManagerProvider =
Provider<KeyCustomizationManager>((ref) {
final retval = KeyCustomizationManager();
retval.read();
return retval;
});
class KeyCustomizationManager { class KeyCustomizationManager {
var _customizations = <String, dynamic>{}; var _customizations = <String, dynamic>{};

View File

@ -0,0 +1,29 @@
/*
* 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:convert';
class KeyCustomization {
final String serialNumber;
final Map<String, dynamic> properties;
const KeyCustomization(this.serialNumber, this.properties);
factory KeyCustomization.fromString(String serialNumber, String encodedJson) {
final data = json.decode(String.fromCharCodes(base64Decode(encodedJson)));
return KeyCustomization(serialNumber, data);
}
}

View File

@ -0,0 +1,26 @@
/*
* 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_riverpod/flutter_riverpod.dart';
import 'key_customization.dart';
final keyCustomizationManagerProvider =
Provider<KeyCustomizationManager>((ref) {
final retval = KeyCustomizationManager();
retval.read();
return retval;
});

View File

@ -19,20 +19,21 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import '../../core/state.dart'; import '../../../core/state.dart';
import '../../management/models.dart'; import '../../../management/models.dart';
import '../../widgets/app_input_decoration.dart'; import '../../../widgets/app_input_decoration.dart';
import '../../widgets/app_text_form_field.dart'; import '../../../widgets/app_text_form_field.dart';
import '../../widgets/focus_utils.dart'; import '../../../widgets/focus_utils.dart';
import '../../widgets/responsive_dialog.dart'; import '../../../widgets/responsive_dialog.dart';
import '../key_customization.dart'; import '../../logging.dart';
import '../logging.dart'; import '../../models.dart';
import '../../state.dart';
import '../../views/device_avatar.dart';
import '../../views/keys.dart';
import '../models.dart'; import '../models.dart';
import '../state.dart'; import '../state.dart';
import 'device_avatar.dart';
import 'keys.dart';
final _log = Logger('KeyCustomizationDialog'); final _log = Logger('key_customization_dialog');
class KeyCustomizationDialog extends ConsumerStatefulWidget { class KeyCustomizationDialog extends ConsumerStatefulWidget {
final KeyCustomization? initialCustomization; final KeyCustomization? initialCustomization;
@ -62,7 +63,6 @@ class _KeyCustomizationDialogState
_displayName = widget.initialCustomization != null _displayName = widget.initialCustomization != null
? widget.initialCustomization?.properties['display_name'] ? widget.initialCustomization?.properties['display_name']
: null; : null;
_previewColor = _displayColor != null _previewColor = _displayColor != null
? Color(int.parse(_displayColor!, radix: 16)) ? Color(int.parse(_displayColor!, radix: 16))
: null; : null;
@ -71,7 +71,7 @@ class _KeyCustomizationDialogState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!; final l10n = AppLocalizations.of(context)!;
final currentNode = widget.node; //ref.watch(currentDeviceProvider); final currentNode = widget.node;
final theme = Theme.of(context); final theme = Theme.of(context);
final Widget hero; final Widget hero;
@ -231,18 +231,22 @@ String _getDeviceInfoString(BuildContext context, DeviceInfo info) {
].join(' '); ].join(' ');
} }
List<String> _getDeviceStrings(BuildContext context, DeviceNode node) { List<String> _getDeviceStrings(
final messages = (node is UsbYubiKeyNode) BuildContext context, WidgetRef ref, DeviceNode node) {
final data = ref.watch(currentDeviceDataProvider);
final messages = node is UsbYubiKeyNode
? node.info != null ? node.info != null
? [node.name, _getDeviceInfoString(context, node.info!)] ? [node.name, _getDeviceInfoString(context, node.info!)]
: <String>[] : <String>[]
: data.hasValue
? data.value?.node.path == node.path
? [
data.value!.name,
_getDeviceInfoString(context, data.value!.info)
]
: <String>[]
: <String>[]; : <String>[];
// Add the NFC reader name, unless it's already included (as device name, like on Android)
if (node is NfcReaderNode && !messages.contains(node.name)) {
messages.add(node.name);
}
return messages; return messages;
} }
@ -282,8 +286,6 @@ class _HeroAvatar extends StatelessWidget {
class _CurrentDeviceAvatar extends ConsumerWidget { class _CurrentDeviceAvatar extends ConsumerWidget {
final DeviceNode node; final DeviceNode node;
//final AsyncValue<YubiKeyData> data;
final Color color; final Color color;
const _CurrentDeviceAvatar(this.node, this.color); const _CurrentDeviceAvatar(this.node, this.color);
@ -291,7 +293,7 @@ class _CurrentDeviceAvatar extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final hero = DeviceAvatar.deviceNode(node, radius: 64); final hero = DeviceAvatar.deviceNode(node, radius: 64);
final messages = _getDeviceStrings(context, node); final messages = _getDeviceStrings(context, ref, node);
return Column( return Column(
children: [ children: [

View File

@ -14,8 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
import 'dart:convert';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -111,9 +109,11 @@ class DevicePath {
@freezed @freezed
class DeviceNode with _$DeviceNode { class DeviceNode with _$DeviceNode {
const DeviceNode._(); const DeviceNode._();
factory DeviceNode.usbYubiKey( factory DeviceNode.usbYubiKey(
DevicePath path, String name, UsbPid pid, DeviceInfo? info) = DevicePath path, String name, UsbPid pid, DeviceInfo? info) =
UsbYubiKeyNode; UsbYubiKeyNode;
factory DeviceNode.nfcReader(DevicePath path, String name) = NfcReaderNode; factory DeviceNode.nfcReader(DevicePath path, String name) = NfcReaderNode;
Transport get transport => Transport get transport =>
@ -146,15 +146,3 @@ class WindowState with _$WindowState {
@Default(false) bool hidden, @Default(false) bool hidden,
}) = _WindowState; }) = _WindowState;
} }
class KeyCustomization {
final String serialNumber;
final Map<String, dynamic> properties;
const KeyCustomization(this.serialNumber, this.properties);
factory KeyCustomization.fromString(String serialNumber, String encodedJson) {
final data = json.decode(String.fromCharCodes(base64Decode(encodedJson)));
return KeyCustomization(serialNumber, data);
}
}

View File

@ -27,7 +27,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../core/state.dart'; import '../core/state.dart';
import '../theme.dart'; import '../theme.dart';
import 'features.dart' as features; import 'features.dart' as features;
import 'key_customization.dart'; import 'key_customization/state.dart';
import 'logging.dart'; import 'logging.dart';
import 'models.dart'; import 'models.dart';

View File

@ -23,12 +23,14 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../android/state.dart'; import '../../android/state.dart';
import '../../core/state.dart'; import '../../core/state.dart';
import '../../management/models.dart'; import '../../management/models.dart';
import '../key_customization.dart'; import '../key_customization/key_customization.dart';
import '../key_customization/models.dart';
import '../key_customization/state.dart';
import '../key_customization/views/key_customization_dialog.dart';
import '../message.dart'; import '../message.dart';
import '../models.dart'; import '../models.dart';
import '../state.dart'; import '../state.dart';
import 'device_avatar.dart'; import 'device_avatar.dart';
import 'key_customization_dialog.dart';
import 'keys.dart' as keys; import 'keys.dart' as keys;
final _hiddenDevicesProvider = final _hiddenDevicesProvider =