simplify working with KeyCustomization

This commit is contained in:
Adam Velebil 2024-01-23 12:36:13 +01:00
parent 56e20520a2
commit 20f8d6fd25
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
5 changed files with 81 additions and 90 deletions

View File

@ -16,6 +16,7 @@
import 'dart:convert';
import 'dart:io';
import 'dart:ui';
import 'package:crypto/crypto.dart';
import 'package:logging/logging.dart';
@ -48,7 +49,7 @@ class KeyCustomizationManager {
}
KeyCustomization? get(String? serialNumber) {
_log.debug('Getting customization for: $serialNumber');
_log.debug('Getting key customization for $serialNumber');
if (serialNumber == null || serialNumber.isEmpty) {
return null;
@ -63,11 +64,14 @@ class KeyCustomizationManager {
return null;
}
void set(KeyCustomization customization) {
_log.debug(
'Added: ${customization.serialNumber}: ${customization.properties}');
final sha = getSerialSha(customization.serialNumber);
_customizations[sha] = customization.properties;
void set({required String serial, String? customName, Color? customColor}) {
final properties = <String, String?>{
'display_color': customColor?.value.toRadixString(16),
'display_name': customName?.isNotEmpty == true ? customName : null
};
_log.debug('Setting key customization for $serial: $properties');
final sha = getSerialSha(serial);
_customizations[sha] = properties;
}
Future<void> write() async {

View File

@ -15,12 +15,29 @@
*/
import 'dart:convert';
import 'dart:ui';
class KeyCustomization {
final String serialNumber;
final Map<String, dynamic> properties;
final Map<String, dynamic> _properties;
const KeyCustomization(this.serialNumber, this.properties);
const KeyCustomization(this.serialNumber, this._properties);
String? getName() => _properties['display_name'] as String?;
Color? getColor() {
var customColor = _properties['display_color'] as String?;
if (customColor == null) {
return null;
}
var intValue = int.tryParse(customColor, radix: 16);
if (intValue == null) {
return null;
}
return Color(intValue);
}
factory KeyCustomization.fromString(String serialNumber, String encodedJson) {
final data = json.decode(String.fromCharCodes(base64Decode(encodedJson)));

View File

@ -17,7 +17,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart';
import '../../../core/state.dart';
import '../../../management/models.dart';
@ -25,7 +24,6 @@ import '../../../widgets/app_input_decoration.dart';
import '../../../widgets/app_text_form_field.dart';
import '../../../widgets/focus_utils.dart';
import '../../../widgets/responsive_dialog.dart';
import '../../logging.dart';
import '../../models.dart';
import '../../state.dart';
import '../../views/device_avatar.dart';
@ -33,7 +31,21 @@ import '../../views/keys.dart';
import '../models.dart';
import '../state.dart';
final _log = Logger('key_customization_dialog');
extension _ColorHelper on String? {
Color? asColor() {
final hexValue = this;
if (hexValue == null) {
return null;
}
final intValue = int.tryParse(hexValue, radix: 16);
if (intValue == null) {
return null;
}
return Color(intValue);
}
}
class KeyCustomizationDialog extends ConsumerStatefulWidget {
final KeyCustomization? initialCustomization;
@ -49,23 +61,14 @@ class KeyCustomizationDialog extends ConsumerStatefulWidget {
class _KeyCustomizationDialogState
extends ConsumerState<KeyCustomizationDialog> {
String? _displayName;
String? _displayColor;
Color? _previewColor;
String? _customName;
Color? _customColor;
@override
void initState() {
super.initState();
_displayColor = widget.initialCustomization != null
? widget.initialCustomization?.properties['display_color']
: null;
_displayName = widget.initialCustomization != null
? widget.initialCustomization?.properties['display_name']
: null;
_previewColor = _displayColor != null
? Color(int.parse(_displayColor!, radix: 16))
: null;
_customName = widget.initialCustomization?.getName();
_customColor = widget.initialCustomization?.getColor();
}
@override
@ -76,12 +79,12 @@ class _KeyCustomizationDialogState
final Widget hero;
if (currentNode != null) {
hero = _CurrentDeviceAvatar(currentNode, _previewColor ?? Colors.white);
hero = _CurrentDeviceAvatar(currentNode, _customColor ?? Colors.white);
} else {
hero = Column(
children: [
_HeroAvatar(
color: _previewColor ?? Colors.white,
color: _customColor ?? Colors.white,
child: DeviceAvatar(
radius: 64,
child: Icon(isAndroid ? Icons.no_cell : Icons.usb),
@ -103,24 +106,17 @@ class _KeyCustomizationDialogState
colorScheme: ColorScheme.fromSeed(
brightness: theme.brightness,
seedColor:
_previewColor ?? primaryColor ?? theme.colorScheme.primary),
_customColor ?? primaryColor ?? theme.colorScheme.primary),
),
child: ResponsiveDialog(
actions: [
TextButton(
onPressed: () async {
KeyCustomization newValue = KeyCustomization(
widget.initialCustomization!.serialNumber, <String, dynamic>{
'display_color': _displayColor,
'display_name': _displayName
});
_log.debug('Saving customization for '
'${widget.initialCustomization!.serialNumber}: '
'$_displayName/$_displayColor');
final manager = ref.read(keyCustomizationManagerProvider);
manager.set(newValue);
manager.set(
serial: widget.initialCustomization!.serialNumber,
customName: _customName,
customColor: _customColor);
await manager.write();
ref.invalidate(lightThemeProvider);
@ -146,7 +142,7 @@ class _KeyCustomizationDialogState
children: [
AppTextFormField(
//controller: displayNameController,
initialValue: _displayName,
initialValue: _customName,
maxLength: 20,
decoration: AppInputDecoration(
border: const OutlineInputBorder(),
@ -157,7 +153,7 @@ class _KeyCustomizationDialogState
textInputAction: TextInputAction.done,
onChanged: (value) {
setState(() {
_displayName = value.trim();
_customName = value.trim();
});
},
onFieldSubmitted: (_) {},
@ -167,18 +163,19 @@ class _KeyCustomizationDialogState
alignment: WrapAlignment.center,
children: [
...[
[Colors.yellow, 'FFFFEB3B'],
[Colors.orange, 'FFFF9800'],
[Colors.red, 'FFF44336'],
[Colors.deepPurple, 'FF673AB7'],
[Colors.green, 'FF4CAF50'],
[Colors.teal, 'FF009688'],
[Colors.cyan, 'FF00BCD4']
Colors.yellow.withOpacity(1.0),
Colors.orange.withOpacity(1.0),
Colors.red.withOpacity(1.0),
Colors.deepPurple.withOpacity(1.0),
Colors.green.withOpacity(1.0),
Colors.teal.withOpacity(1.0),
Colors.cyan.withOpacity(1.0),
'FF88FFBB'.asColor() // example
].map((e) => _ColorButton(
color: e[0] as MaterialColor,
isSelected: _displayColor == e[1],
color: e,
isSelected: _customColor == e,
onPressed: () {
_updateColor(e[1] as String?);
_updateColor(e);
},
)),
@ -187,14 +184,14 @@ class _KeyCustomizationDialogState
onPressed: () => _updateColor(null),
constraints: const BoxConstraints(
minWidth: 32.0, minHeight: 32.0),
fillColor: _displayColor == null
fillColor: _customColor == null
? theme.colorScheme.surface
: theme.colorScheme.onSurface,
shape: const CircleBorder(),
child: Icon(
Icons.cancel_rounded,
size: 16,
color: _displayColor == null
color: _customColor == null
? theme.colorScheme.onSurface
: theme.colorScheme.surface,
),
@ -210,11 +207,9 @@ class _KeyCustomizationDialogState
);
}
void _updateColor(String? colorString) {
void _updateColor(Color? color) {
setState(() {
_displayColor = colorString;
_previewColor =
colorString != null ? Color(int.parse(colorString, radix: 16)) : null;
_customColor = color;
});
}
}
@ -310,7 +305,7 @@ class _CurrentDeviceAvatar extends ConsumerWidget {
}
class _ColorButton extends StatefulWidget {
final MaterialColor color;
final Color? color;
final bool isSelected;
final Function()? onPressed;

View File

@ -176,14 +176,8 @@ class ThemeNotifier extends Notifier<ThemeData> {
Color? primaryColor = color;
if (yubiKeyData != null) {
final manager = ref.read(keyCustomizationManagerProvider);
final customization = manager.get(yubiKeyData.info.serial?.toString());
String? displayColorCustomization =
customization?.properties['display_color'];
if (displayColorCustomization != null) {
primaryColor = Color(int.parse(displayColorCustomization, radix: 16));
}
primaryColor = customization?.getColor() ?? color;
}
primaryColor ??= ref.read(primaryColorProvider);

View File

@ -420,17 +420,9 @@ _DeviceRow _buildDeviceRow(
nfcReader: (_, __) => l10n.s_select_to_scan,
);
String displayName = node.name;
if (info?.serial != null) {
final properties = ref
.read(keyCustomizationManagerProvider)
.get(info?.serial?.toString())
?.properties;
var customName = properties?['display_name'];
if (customName != null && customName != '') {
displayName = customName;
}
}
final keyCustomization =
ref.read(keyCustomizationManagerProvider).get(info?.serial?.toString());
String displayName = keyCustomization?.getName() ?? node.name;
return _DeviceRow(
key: ValueKey(node.path.key),
@ -461,24 +453,13 @@ _DeviceRow _buildCurrentDeviceRow(
final title = messages.removeAt(0);
final subtitle = messages.join('\n');
String displayName = title;
final serialNumber =
data.hasValue ? data.value?.info.serial?.toString() : null;
Color? displayColor;
if (serialNumber != null) {
final properties =
ref.read(keyCustomizationManagerProvider).get(serialNumber)?.properties;
var customName = properties?['display_name'];
if (customName != null && customName != '') {
displayName = customName;
}
var customColor = properties?['display_color'];
if (customColor != null) {
displayColor = Color(int.parse(customColor, radix: 16));
}
}
final keyCustomization =
ref.read(keyCustomizationManagerProvider).get(serialNumber);
String displayName = keyCustomization?.getName() ?? title;
Color? displayColor = keyCustomization?.getColor();
return _DeviceRow(
key: keys.deviceInfoListTile,