Skip to content

Commit 8889b62

Browse files
committed
UI enchancements for key customization
1 parent ee6a7d8 commit 8889b62

File tree

9 files changed

+82
-21
lines changed

9 files changed

+82
-21
lines changed

lib/app/state.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@ class CurrentAppNotifier extends StateNotifier<Application> {
235235
// Try switching to saved app
236236
state = Application.values.firstWhere((app) => app.name == lastAppName);
237237
}
238+
if (state == Application.passkeys &&
239+
state.getAvailability(data) != Availability.enabled) {
240+
state = Application.webauthn;
241+
}
242+
if (state == Application.webauthn &&
243+
state.getAvailability(data) != Availability.enabled) {
244+
state = Application.passkeys;
245+
}
238246
if (state.getAvailability(data) != Availability.unsupported) {
239247
// Keep current app
240248
return;

lib/home/views/home_screen.dart

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,8 @@ class HomeScreen extends ConsumerWidget {
4444
final enabledCapabilities =
4545
deviceData.info.config.enabledCapabilities[deviceData.node.transport] ??
4646
0;
47-
final image = ProductImage(
48-
name: deviceData.name,
49-
formFactor: deviceData.info.formFactor,
50-
isNfc:
51-
deviceData.info.supportedCapabilities.containsKey(Transport.nfc));
47+
final primaryColor = ref.watch(defaultColorProvider);
48+
5249
return AppPage(
5350
title: l10n.s_home,
5451
keyActionsBuilder: (context) =>
@@ -60,7 +57,6 @@ class HomeScreen extends ConsumerWidget {
6057
crossAxisAlignment: CrossAxisAlignment.start,
6158
children: [
6259
_DeviceName(deviceData, keyCustomization),
63-
const SizedBox(height: 16.0),
6460
_DeviceInfoContent(deviceData.info),
6561
const SizedBox(height: 16.0),
6662
Row(
@@ -94,7 +90,15 @@ class HomeScreen extends ConsumerWidget {
9490
flex: 6,
9591
child: ConstrainedBox(
9692
constraints: const BoxConstraints(maxWidth: 200),
97-
child: image,
93+
child: _HeroAvatar(
94+
color: keyCustomization?.color ?? primaryColor,
95+
child: ProductImage(
96+
name: deviceData.name,
97+
formFactor: deviceData.info.formFactor,
98+
isNfc: deviceData.info.supportedCapabilities
99+
.containsKey(Transport.nfc),
100+
),
101+
),
98102
),
99103
)
100104
],
@@ -121,6 +125,7 @@ class _DeviceName extends ConsumerWidget {
121125
String displayName = label != null ? '$label ($name)' : name;
122126

123127
return Row(
128+
crossAxisAlignment: CrossAxisAlignment.start,
124129
children: [
125130
Flexible(
126131
child: Text(
@@ -172,20 +177,20 @@ class _DeviceInfoContent extends StatelessWidget {
172177
crossAxisAlignment: CrossAxisAlignment.start,
173178
children: [
174179
if (serial != null)
175-
Opacity(
176-
opacity: 0.6,
177-
child: Text(
178-
l10n.l_serial_number(serial),
179-
style: Theme.of(context).textTheme.bodySmall,
180-
),
181-
),
182-
Opacity(
183-
opacity: 0.6,
184-
child: Text(
185-
l10n.l_firmware_version(version),
186-
style: Theme.of(context).textTheme.bodySmall,
180+
Text(
181+
l10n.l_serial_number(serial),
182+
style: Theme.of(context)
183+
.textTheme
184+
.titleSmall
185+
?.apply(color: Theme.of(context).colorScheme.onSurfaceVariant),
187186
),
188-
)
187+
Text(
188+
l10n.l_firmware_version(version),
189+
style: Theme.of(context)
190+
.textTheme
191+
.titleSmall
192+
?.apply(color: Theme.of(context).colorScheme.onSurfaceVariant),
193+
),
189194
],
190195
);
191196
}
@@ -199,6 +204,7 @@ class _DeviceColor extends ConsumerWidget {
199204

200205
@override
201206
Widget build(BuildContext context, WidgetRef ref) {
207+
final l10n = AppLocalizations.of(context)!;
202208
final theme = Theme.of(context);
203209
final primaryColor = ref.watch(defaultColorProvider);
204210
final defaultColor =
@@ -208,6 +214,7 @@ class _DeviceColor extends ConsumerWidget {
208214
final customColor = initialCustomization.color;
209215

210216
return ChoiceFilterChip<Color?>(
217+
disableHover: true,
211218
value: customColor,
212219
items: const [null],
213220
selected: customColor != null && customColor != defaultColor,
@@ -246,6 +253,7 @@ class _DeviceColor extends ConsumerWidget {
246253
fillColor: (isAndroid && ref.read(androidSdkVersionProvider) >= 31)
247254
? theme.colorScheme.onSurface
248255
: primaryColor,
256+
hoverColor: Colors.black12,
249257
shape: const CircleBorder(),
250258
child: Icon(
251259
Icons.cancel_rounded,
@@ -268,7 +276,7 @@ class _DeviceColor extends ConsumerWidget {
268276
const SizedBox(
269277
width: 12,
270278
),
271-
const Flexible(child: Text('Key color'))
279+
Flexible(child: Text(l10n.s_color))
272280
],
273281
),
274282
onChanged: (e) {},
@@ -307,6 +315,7 @@ class _ColorButtonState extends State<_ColorButton> {
307315
onPressed: widget.onPressed,
308316
constraints: const BoxConstraints(minWidth: 26.0, minHeight: 26.0),
309317
fillColor: widget.color,
318+
hoverColor: Colors.black12,
310319
shape: const CircleBorder(),
311320
child: Icon(
312321
Icons.circle,
@@ -316,3 +325,37 @@ class _ColorButtonState extends State<_ColorButton> {
316325
);
317326
}
318327
}
328+
329+
class _HeroAvatar extends StatelessWidget {
330+
final Widget child;
331+
final Color color;
332+
333+
const _HeroAvatar({required this.color, required this.child});
334+
335+
@override
336+
Widget build(BuildContext context) {
337+
final theme = Theme.of(context);
338+
return Container(
339+
decoration: BoxDecoration(
340+
shape: BoxShape.circle,
341+
gradient: RadialGradient(
342+
colors: [
343+
color.withOpacity(0.6),
344+
color.withOpacity(0.25),
345+
(DialogTheme.of(context).backgroundColor ??
346+
theme.dialogBackgroundColor)
347+
.withOpacity(0),
348+
],
349+
),
350+
),
351+
padding: const EdgeInsets.all(12),
352+
child: Theme(
353+
// Give the avatar a transparent background
354+
data: theme.copyWith(
355+
colorScheme:
356+
theme.colorScheme.copyWith(surfaceVariant: Colors.transparent)),
357+
child: child,
358+
),
359+
);
360+
}
361+
}

lib/home/views/manage_label_dialog.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class _ManageLabelDialogState extends ConsumerState<ManageLabelDialog> {
6767
? l10n.p_set_will_add_custom_name
6868
: l10n.p_rename_will_change_custom_name),
6969
AppTextFormField(
70+
autofocus: true,
7071
initialValue: _label,
7172
maxLength: 20,
7273
decoration: AppInputDecoration(

lib/l10n/app_de.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@
767767
"s_set_label": null,
768768
"s_change_label": null,
769769
"s_theme_color": null,
770+
"s_color": null,
770771
"p_set_will_add_custom_name": null,
771772
"p_rename_will_change_custom_name": null,
772773

lib/l10n/app_en.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@
767767
"s_set_label": "Set label",
768768
"s_change_label": "Change label",
769769
"s_theme_color": "Theme color",
770+
"s_color": "Color",
770771
"p_set_will_add_custom_name": "This will give your YubiKey a custom name.",
771772
"p_rename_will_change_custom_name": "This will change the label of your YubiKey.",
772773

lib/l10n/app_fr.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@
767767
"s_set_label": null,
768768
"s_change_label": null,
769769
"s_theme_color": null,
770+
"s_color": null,
770771
"p_set_will_add_custom_name": null,
771772
"p_rename_will_change_custom_name": null,
772773

lib/l10n/app_ja.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@
767767
"s_set_label": null,
768768
"s_change_label": null,
769769
"s_theme_color": null,
770+
"s_color": null,
770771
"p_set_will_add_custom_name": null,
771772
"p_rename_will_change_custom_name": null,
772773

lib/l10n/app_pl.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@
767767
"s_set_label": null,
768768
"s_change_label": null,
769769
"s_theme_color": "Kolor motywu",
770+
"s_color": null,
770771
"p_set_will_add_custom_name": null,
771772
"p_rename_will_change_custom_name": null,
772773

lib/widgets/choice_filter_chip.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ChoiceFilterChip<T> extends StatefulWidget {
2828
final void Function(T value)? onChanged;
2929
final Widget? avatar;
3030
final bool selected;
31+
final bool? disableHover;
3132
const ChoiceFilterChip({
3233
super.key,
3334
required this.value,
@@ -37,6 +38,7 @@ class ChoiceFilterChip<T> extends StatefulWidget {
3738
this.tooltip,
3839
this.avatar,
3940
this.selected = false,
41+
this.disableHover,
4042
this.labelBuilder,
4143
});
4244

@@ -69,6 +71,8 @@ class _ChoiceFilterChipState<T> extends State<ChoiceFilterChip<T>> {
6971
color: Theme.of(context).colorScheme.background,
7072
items: widget.items
7173
.map((e) => PopupMenuItem<T>(
74+
enabled:
75+
widget.disableHover != null ? !widget.disableHover! : true,
7276
value: e,
7377
height: chipBox.size.height,
7478
textStyle: ChipTheme.of(context).labelStyle,

0 commit comments

Comments
 (0)