diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 87c05849..4d4ab31a 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -622,6 +622,7 @@ "s_no_export": null, "s_export": null, "l_export_configuration_file": null, + "l_export_can_be_added_to": null, "@_otp_slot_actions": {}, "s_delete_slot": null, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d4626477..10e6e560 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -622,6 +622,7 @@ "s_no_export": "No export", "s_export": "Export", "l_export_configuration_file": "Export configuration to file", + "l_export_can_be_added_to": "Exported credential can be added to", "@_otp_slot_actions": {}, "s_delete_slot": "Delete credential", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index d6d1574f..58c0eb57 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -622,6 +622,7 @@ "s_no_export": null, "s_export": null, "l_export_configuration_file": null, + "l_export_can_be_added_to": null, "@_otp_slot_actions": {}, "s_delete_slot": null, diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index bba1c714..da7eaa4e 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -622,6 +622,7 @@ "s_no_export": null, "s_export": null, "l_export_configuration_file": null, + "l_export_can_be_added_to": null, "@_otp_slot_actions": {}, "s_delete_slot": null, diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 622bc4b5..4fe79971 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -622,6 +622,7 @@ "s_no_export": "Brak eksportu", "s_export": "Eksportuj", "l_export_configuration_file": "Eksportuj konfigurację do pliku", + "l_export_can_be_added_to": null, "@_otp_slot_actions": {}, "s_delete_slot": "Usuń poświadczenie", diff --git a/lib/otp/views/configure_yubiotp_dialog.dart b/lib/otp/views/configure_yubiotp_dialog.dart index 81643834..e01de8cf 100644 --- a/lib/otp/views/configure_yubiotp_dialog.dart +++ b/lib/otp/views/configure_yubiotp_dialog.dart @@ -18,11 +18,13 @@ import 'dart:io'; import 'dart:math'; import 'package:file_picker/file_picker.dart'; +import 'package:flutter/gestures.dart'; 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 'package:material_symbols_icons/symbols.dart'; +import 'package:url_launcher/url_launcher.dart'; import '../../app/logging.dart'; import '../../app/message.dart'; @@ -365,6 +367,17 @@ class _ConfigureYubiOtpDialogState }, ), ], + ), + RichText( + text: TextSpan( + text: l10n.l_export_can_be_added_to, + style: Theme.of(context).textTheme.labelSmall?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant), + children: [ + const TextSpan(text: ' '), + _createUploadOtpLink(context) + ], + ), ) ] .map((e) => Padding( @@ -376,4 +389,21 @@ class _ConfigureYubiOtpDialogState ), ); } + + TextSpan _createUploadOtpLink(BuildContext context) { + final theme = Theme.of(context); + final uploadOtpUri = Uri.parse('https://upload.yubico.com'); + return TextSpan( + text: uploadOtpUri.host, + style: theme.textTheme.labelSmall + ?.copyWith(color: theme.colorScheme.primary), + recognizer: TapGestureRecognizer() + ..onTap = () async { + await launchUrl(uploadOtpUri, mode: LaunchMode.externalApplication); + }, + children: const [ + TextSpan(text: ' ') // without this the recognizer takes over whole row + ], + ); + } }