mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 08:22:16 +03:00
Merge PR #1630
This commit is contained in:
commit
7b6c32fe3d
@ -29,7 +29,6 @@ import '../../app/views/app_page.dart';
|
||||
import '../../core/models.dart';
|
||||
import '../../core/state.dart';
|
||||
import '../../management/models.dart';
|
||||
import '../../widgets/choice_filter_chip.dart';
|
||||
import '../../widgets/product_image.dart';
|
||||
import 'key_actions.dart';
|
||||
import 'manage_label_dialog.dart';
|
||||
@ -97,16 +96,9 @@ class _HomeScreenState extends ConsumerState<HomeScreen> {
|
||||
),
|
||||
if (widget.deviceData.info.fipsCapable != 0)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
padding: const EdgeInsets.only(top: 38),
|
||||
child: _FipsLegend(),
|
||||
),
|
||||
if (serial != null) ...[
|
||||
const SizedBox(height: 32.0),
|
||||
_DeviceColor(
|
||||
deviceData: widget.deviceData,
|
||||
initialCustomization: keyCustomization ??
|
||||
KeyCustomization(serial: serial))
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -208,6 +200,9 @@ class _DeviceContent extends ConsumerWidget {
|
||||
final label = initialCustomization?.name;
|
||||
String displayName = label != null ? '$label ($name)' : name;
|
||||
|
||||
final defaultColor = ref.watch(defaultColorProvider);
|
||||
final customColor = initialCustomization?.color;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -219,22 +214,114 @@ class _DeviceContent extends ConsumerWidget {
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
),
|
||||
if (serial != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: IconButton(
|
||||
icon: const Icon(Symbols.edit),
|
||||
onPressed: () async {
|
||||
await ref.read(withContextProvider)((context) async {
|
||||
await _showManageLabelDialog(
|
||||
initialCustomization ??
|
||||
KeyCustomization(serial: serial),
|
||||
context,
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
if (serial != null) ...[
|
||||
const SizedBox(width: 8),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Symbols.edit),
|
||||
tooltip: l10n.s_set_label,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
onPressed: () async {
|
||||
await ref.read(withContextProvider)((context) async {
|
||||
await _showManageLabelDialog(
|
||||
initialCustomization ??
|
||||
KeyCustomization(serial: serial),
|
||||
context,
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
PopupMenuButton(
|
||||
popUpAnimationStyle:
|
||||
AnimationStyle(duration: Duration.zero),
|
||||
menuPadding: EdgeInsets.zero,
|
||||
tooltip: l10n.s_set_color,
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
PopupMenuItem(
|
||||
child: Center(
|
||||
child: Wrap(
|
||||
runSpacing: 8,
|
||||
spacing: 16,
|
||||
children: [
|
||||
...[
|
||||
Colors.teal,
|
||||
Colors.cyan,
|
||||
Colors.blueAccent,
|
||||
Colors.deepPurple,
|
||||
Colors.red,
|
||||
Colors.orange,
|
||||
Colors.yellow,
|
||||
// add nice color to devices with dynamic color
|
||||
if (isAndroid &&
|
||||
ref.read(androidSdkVersionProvider) >=
|
||||
31)
|
||||
Colors.lightGreen
|
||||
].map((e) => _ColorButton(
|
||||
color: e,
|
||||
isSelected:
|
||||
customColor?.value == e.value,
|
||||
onPressed: () {
|
||||
_updateColor(e, ref, serial);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)),
|
||||
|
||||
// "use default color" button
|
||||
RawMaterialButton(
|
||||
onPressed: () {
|
||||
_updateColor(null, ref, serial);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 26.0, minHeight: 26.0),
|
||||
fillColor: defaultColor,
|
||||
hoverColor: Colors.black12,
|
||||
shape: const CircleBorder(),
|
||||
child: Icon(
|
||||
customColor == null
|
||||
? Symbols.circle
|
||||
: Symbols.clear,
|
||||
fill: 1,
|
||||
size: 16,
|
||||
weight: 700,
|
||||
opticalSize: 20,
|
||||
color: defaultColor
|
||||
.computeLuminance() >
|
||||
0.7
|
||||
? Colors.grey // for bright colors
|
||||
: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
];
|
||||
},
|
||||
icon: Icon(
|
||||
Symbols.palette,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 3.0,
|
||||
width: 24.0,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
.withOpacity(0.9)),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
@ -283,6 +370,15 @@ class _DeviceContent extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _updateColor(Color? color, WidgetRef ref, int serial) async {
|
||||
final manager = ref.read(keyCustomizationManagerProvider.notifier);
|
||||
await manager.set(
|
||||
serial: serial,
|
||||
name: initialCustomization?.name,
|
||||
color: color,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showManageLabelDialog(
|
||||
KeyCustomization keyCustomization, BuildContext context) async {
|
||||
await showBlurDialog(
|
||||
@ -294,97 +390,6 @@ class _DeviceContent extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _DeviceColor extends ConsumerWidget {
|
||||
final YubiKeyData deviceData;
|
||||
final KeyCustomization initialCustomization;
|
||||
const _DeviceColor(
|
||||
{required this.deviceData, required this.initialCustomization});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final defaultColor = ref.watch(defaultColorProvider);
|
||||
final customColor = initialCustomization.color;
|
||||
|
||||
return ChoiceFilterChip<Color?>(
|
||||
disableHover: true,
|
||||
value: customColor,
|
||||
items: const [null],
|
||||
selected: customColor != null && customColor.value != defaultColor.value,
|
||||
itemBuilder: (e) => Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
runSpacing: 8,
|
||||
spacing: 16,
|
||||
children: [
|
||||
...[
|
||||
Colors.teal,
|
||||
Colors.cyan,
|
||||
Colors.blueAccent,
|
||||
Colors.deepPurple,
|
||||
Colors.red,
|
||||
Colors.orange,
|
||||
Colors.yellow,
|
||||
// add nice color to devices with dynamic color
|
||||
if (isAndroid && ref.read(androidSdkVersionProvider) >= 31)
|
||||
Colors.lightGreen
|
||||
].map((e) => _ColorButton(
|
||||
color: e,
|
||||
isSelected: customColor?.value == e.value,
|
||||
onPressed: () {
|
||||
_updateColor(e, ref);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
)),
|
||||
|
||||
// "use default color" button
|
||||
RawMaterialButton(
|
||||
onPressed: () {
|
||||
_updateColor(null, ref);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
constraints: const BoxConstraints(minWidth: 26.0, minHeight: 26.0),
|
||||
fillColor: defaultColor,
|
||||
hoverColor: Colors.black12,
|
||||
shape: const CircleBorder(),
|
||||
child: Icon(customColor == null ? Symbols.circle : Symbols.clear,
|
||||
fill: 1,
|
||||
size: 16,
|
||||
weight: 700,
|
||||
opticalSize: 20,
|
||||
color: defaultColor.computeLuminance() > 0.7
|
||||
? Colors.grey // for bright colors
|
||||
: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
labelBuilder: (e) => Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
constraints: const BoxConstraints(minWidth: 22.0, minHeight: 22.0),
|
||||
decoration: BoxDecoration(
|
||||
color: customColor ?? defaultColor, shape: BoxShape.circle),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Flexible(child: Text(l10n.s_color))
|
||||
],
|
||||
),
|
||||
onChanged: (e) {},
|
||||
);
|
||||
}
|
||||
|
||||
void _updateColor(Color? color, WidgetRef ref) async {
|
||||
final manager = ref.read(keyCustomizationManagerProvider.notifier);
|
||||
await manager.set(
|
||||
serial: initialCustomization.serial,
|
||||
name: initialCustomization.name,
|
||||
color: color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ColorButton extends StatefulWidget {
|
||||
final Color? color;
|
||||
final bool isSelected;
|
||||
|
@ -906,6 +906,7 @@
|
||||
|
||||
"@_key_customization": {},
|
||||
"s_set_label": null,
|
||||
"s_set_color": null,
|
||||
"s_change_label": null,
|
||||
"s_color": null,
|
||||
"p_set_will_add_custom_name": null,
|
||||
|
@ -906,6 +906,7 @@
|
||||
|
||||
"@_key_customization": {},
|
||||
"s_set_label": "Set label",
|
||||
"s_set_color": "Set color",
|
||||
"s_change_label": "Change label",
|
||||
"s_color": "Color",
|
||||
"p_set_will_add_custom_name": "This will give your YubiKey a custom name.",
|
||||
|
@ -906,6 +906,7 @@
|
||||
|
||||
"@_key_customization": {},
|
||||
"s_set_label": "Définir l'étiquette",
|
||||
"s_set_color": null,
|
||||
"s_change_label": "Modifier l'étiquette",
|
||||
"s_color": "Couleur",
|
||||
"p_set_will_add_custom_name": "Cela donnera un nom personnalisé à votre YubiKey.",
|
||||
|
@ -906,6 +906,7 @@
|
||||
|
||||
"@_key_customization": {},
|
||||
"s_set_label": "ラベルを設定",
|
||||
"s_set_color": null,
|
||||
"s_change_label": "ラベルを変更",
|
||||
"s_color": "色",
|
||||
"p_set_will_add_custom_name": "これにより、YubiKey にカスタム名を付けることができます。",
|
||||
|
@ -906,6 +906,7 @@
|
||||
|
||||
"@_key_customization": {},
|
||||
"s_set_label": null,
|
||||
"s_set_color": null,
|
||||
"s_change_label": null,
|
||||
"s_color": null,
|
||||
"p_set_will_add_custom_name": null,
|
||||
|
Loading…
Reference in New Issue
Block a user