mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 16:32:01 +03:00
simplify working with KeyCustomization
This commit is contained in:
parent
56e20520a2
commit
20f8d6fd25
@ -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 {
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user