feat(#234): make own device pubkey full, selectable, and one-tap copyable

Settings showed the self public key truncated to 16 hex chars + "..." as
plain Text (settings_screen:262/:410), so it couldn't be shared. Show the
full key, make it selectable, and add a copy button beside it.

- _buildInfoRow gains an optional copyValue: renders the value as
  SelectableText + a copy IconButton that copies the full key and shows a
  "Public key copied" snackbar. Both self-pubkey rows pass the full key.
- New l10n string settings_publicKeyCopied (regenerated localizations +
  untranslated.json).

Part of #234.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull/243/head
Strycher 1 week ago
parent ad29ea3f0e
commit cd9b8e88eb

@ -238,6 +238,7 @@
"settings_infoModel": "Model", "settings_infoModel": "Model",
"settings_infoBattery": "Battery", "settings_infoBattery": "Battery",
"settings_infoPublicKey": "Public Key", "settings_infoPublicKey": "Public Key",
"settings_publicKeyCopied": "Public key copied",
"settings_infoContactsCount": "Contacts Count", "settings_infoContactsCount": "Contacts Count",
"settings_infoChannelCount": "Channel Count", "settings_infoChannelCount": "Channel Count",
"settings_presets": "Presets", "settings_presets": "Presets",

@ -1186,6 +1186,12 @@ abstract class AppLocalizations {
/// **'Public Key'** /// **'Public Key'**
String get settings_infoPublicKey; String get settings_infoPublicKey;
/// No description provided for @settings_publicKeyCopied.
///
/// In en, this message translates to:
/// **'Public key copied'**
String get settings_publicKeyCopied;
/// No description provided for @settings_infoContactsCount. /// No description provided for @settings_infoContactsCount.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

@ -596,6 +596,9 @@ class AppLocalizationsBg extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Общ публичен ключ'; String get settings_infoPublicKey => 'Общ публичен ключ';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Брой контакти'; String get settings_infoContactsCount => 'Брой контакти';

@ -591,6 +591,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Öffentlicher Schlüssel'; String get settings_infoPublicKey => 'Öffentlicher Schlüssel';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Anzahl Kontakte'; String get settings_infoContactsCount => 'Anzahl Kontakte';

@ -581,6 +581,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Public Key'; String get settings_infoPublicKey => 'Public Key';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Contacts Count'; String get settings_infoContactsCount => 'Contacts Count';

@ -592,6 +592,9 @@ class AppLocalizationsEs extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Clave Pública'; String get settings_infoPublicKey => 'Clave Pública';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Número de contactos'; String get settings_infoContactsCount => 'Número de contactos';

@ -596,6 +596,9 @@ class AppLocalizationsFr extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Clé Publique'; String get settings_infoPublicKey => 'Clé Publique';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Nombre de contacts'; String get settings_infoContactsCount => 'Nombre de contacts';

@ -594,6 +594,9 @@ class AppLocalizationsHu extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Nyelvkönyv'; String get settings_infoPublicKey => 'Nyelvkönyv';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Kapcsolatok száma'; String get settings_infoContactsCount => 'Kapcsolatok száma';

@ -594,6 +594,9 @@ class AppLocalizationsIt extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Chiave Pubblica'; String get settings_infoPublicKey => 'Chiave Pubblica';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Numero contatti'; String get settings_infoContactsCount => 'Numero contatti';

@ -567,6 +567,9 @@ class AppLocalizationsJa extends AppLocalizations {
@override @override
String get settings_infoPublicKey => '公開鍵'; String get settings_infoPublicKey => '公開鍵';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => '連絡先数'; String get settings_infoContactsCount => '連絡先数';

@ -567,6 +567,9 @@ class AppLocalizationsKo extends AppLocalizations {
@override @override
String get settings_infoPublicKey => '공개 키'; String get settings_infoPublicKey => '공개 키';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => '연락처 수'; String get settings_infoContactsCount => '연락처 수';

@ -588,6 +588,9 @@ class AppLocalizationsNl extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Openbare Sleutel'; String get settings_infoPublicKey => 'Openbare Sleutel';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Aantal Contacten'; String get settings_infoContactsCount => 'Aantal Contacten';

@ -596,6 +596,9 @@ class AppLocalizationsPl extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Klucz Publiczny'; String get settings_infoPublicKey => 'Klucz Publiczny';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Liczba kontaktów'; String get settings_infoContactsCount => 'Liczba kontaktów';

@ -594,6 +594,9 @@ class AppLocalizationsPt extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Chave Pública'; String get settings_infoPublicKey => 'Chave Pública';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Número de Contatos'; String get settings_infoContactsCount => 'Número de Contatos';

@ -593,6 +593,9 @@ class AppLocalizationsRu extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Публичный ключ'; String get settings_infoPublicKey => 'Публичный ключ';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Количество контактов'; String get settings_infoContactsCount => 'Количество контактов';

@ -588,6 +588,9 @@ class AppLocalizationsSk extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Verejný kľúč'; String get settings_infoPublicKey => 'Verejný kľúč';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Počet kontaktov'; String get settings_infoContactsCount => 'Počet kontaktov';

@ -585,6 +585,9 @@ class AppLocalizationsSl extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Javni ključ'; String get settings_infoPublicKey => 'Javni ključ';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Število stikov'; String get settings_infoContactsCount => 'Število stikov';

@ -583,6 +583,9 @@ class AppLocalizationsSv extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Allmänt nyckel'; String get settings_infoPublicKey => 'Allmänt nyckel';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Kontakterantal'; String get settings_infoContactsCount => 'Kontakterantal';

@ -591,6 +591,9 @@ class AppLocalizationsUk extends AppLocalizations {
@override @override
String get settings_infoPublicKey => 'Відкритий ключ'; String get settings_infoPublicKey => 'Відкритий ключ';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => 'Кількість контактів'; String get settings_infoContactsCount => 'Кількість контактів';

@ -559,6 +559,9 @@ class AppLocalizationsZh extends AppLocalizations {
@override @override
String get settings_infoPublicKey => '公钥'; String get settings_infoPublicKey => '公钥';
@override
String get settings_publicKeyCopied => 'Public key copied';
@override @override
String get settings_infoContactsCount => '联系人数量'; String get settings_infoContactsCount => '联系人数量';

@ -1,5 +1,6 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:meshcore_open/utils/gpx_export.dart'; import 'package:meshcore_open/utils/gpx_export.dart';
import 'package:meshcore_open/widgets/elements_ui.dart'; import 'package:meshcore_open/widgets/elements_ui.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -259,7 +260,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
padding: const EdgeInsets.fromLTRB(16, 8, 16, 12), padding: const EdgeInsets.fromLTRB(16, 8, 16, 12),
child: _buildInfoRow( child: _buildInfoRow(
l10n.settings_infoPublicKey, l10n.settings_infoPublicKey,
'${pubKeyToHex(connector.selfPublicKey!).substring(0, 16)}...', pubKeyToHex(connector.selfPublicKey!),
copyValue: pubKeyToHex(connector.selfPublicKey!),
), ),
), ),
], ],
@ -407,7 +409,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
if (connector.selfPublicKey != null) if (connector.selfPublicKey != null)
_buildInfoRow( _buildInfoRow(
l10n.settings_infoPublicKey, l10n.settings_infoPublicKey,
'${pubKeyToHex(connector.selfPublicKey!).substring(0, 16)}...', pubKeyToHex(connector.selfPublicKey!),
copyValue: pubKeyToHex(connector.selfPublicKey!),
), ),
_buildInfoRow( _buildInfoRow(
l10n.settings_infoContactsCount, l10n.settings_infoContactsCount,
@ -643,6 +646,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
Widget? leading, Widget? leading,
Color? valueColor, Color? valueColor,
VoidCallback? onTap, VoidCallback? onTap,
String? copyValue,
}) { }) {
final theme = Theme.of(context); final theme = Theme.of(context);
@ -666,13 +670,43 @@ class _SettingsScreenState extends State<SettingsScreen> {
], ],
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( if (copyValue == null)
value, Text(
style: theme.textTheme.bodyLarge?.copyWith( value,
color: valueColor, style: theme.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500, color: valueColor,
fontWeight: FontWeight.w500,
),
)
else
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: SelectableText(
value,
style: theme.textTheme.bodyLarge?.copyWith(
color: valueColor,
fontWeight: FontWeight.w500,
),
),
),
IconButton(
icon: const Icon(Icons.copy, size: 18),
tooltip: context.l10n.common_copy,
visualDensity: VisualDensity.compact,
onPressed: () async {
await Clipboard.setData(ClipboardData(text: copyValue));
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(context.l10n.settings_publicKeyCopied),
),
);
},
),
],
), ),
),
], ],
), ),
); );

@ -14,6 +14,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -66,6 +67,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -118,6 +120,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -170,6 +173,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -222,6 +226,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -274,6 +279,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -326,6 +332,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -378,6 +385,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -430,6 +438,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -482,6 +491,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -534,6 +544,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -586,6 +597,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -638,6 +650,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -690,6 +703,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -742,6 +756,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -794,6 +809,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",
@ -846,6 +862,7 @@
"settings_gpsStatusNoResponse", "settings_gpsStatusNoResponse",
"settings_infoFirmware", "settings_infoFirmware",
"settings_infoModel", "settings_infoModel",
"settings_publicKeyCopied",
"appSettings_clock", "appSettings_clock",
"appSettings_clockSystem", "appSettings_clockSystem",
"appSettings_clock12h", "appSettings_clock12h",

Loading…
Cancel
Save

Powered by TurnKey Linux.