diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index de39d7e..a5c5290 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -1680,6 +1680,12 @@ class MeshCoreConnector extends ChangeNotifier { _isLoadingContacts = true; notifyListeners(); break; + case pushCodeNewAdvert: + debugPrint('Got NEW_ADVERT'); + _handleContact(frame); + notifyListeners(); + unawaited(_persistContacts()); + break; case respCodeContact: debugPrint('Got CONTACT'); _handleContact(frame); @@ -1737,6 +1743,7 @@ class MeshCoreConnector extends ChangeNotifier { break; case respCodeCustomVars: _handleCustomVars(frame); + break; default: debugPrint('Unknown frame code: $code'); } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 7c8a0a7..3a9383a 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1309,8 +1309,23 @@ "listFilter_roomServers": "Room servers", "listFilter_unreadOnly": "Unread only", "listFilter_newGroup": "New group", + + "contacts_pathTrace": "Path Trace", + "contacts_ping": "Ping", + "contacts_repeaterPathTrace": "Path trace to repeater", + "contacts_repeaterPing": "Ping repeater", + "contacts_roomPathTrace": "Path trace to room server", + "contacts_roomPing": "Ping room server", + "contacts_chatTraceRoute": "Path trace route", + "contacts_pathTraceTo": "Trace route to {name}", + "@contacts_pathTraceTo": { + "placeholders": { + "name": {"type": "String"} + } + }, "contacts_clipboardEmpty": "Clipboard Is Empty.", "contacts_invalidAdvertFormat": "Invalid Contact Data", - "contacts_contactAdded": "Contact has been added." + "contacts_contactImported": "Contact has been Imported.", + "contacts_contactImportFailed": "Contact Failed to Imported." } diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index 89a07e0..64c2924 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -54,6 +54,7 @@ class _ContactsScreenState extends State List _groups = []; Timer? _searchDebounce; + bool _imported = false; StreamSubscription? _frameSubscription; @override @@ -96,6 +97,23 @@ class _ContactsScreenState extends State final hexString = pubKeyToHex(advertPacket); Clipboard.setData(ClipboardData(text: "meshcore://$hexString")); } + + if(code == respCodeOk && _imported) { + // Show a snackbar indicating success + _imported = false; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(context.l10n.contacts_contactImported)), + ); + } + + if(code == respCodeErr && _imported) { + // Show a snackbar indicating success + _imported = false; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(context.l10n.contacts_contactImportFailed)), + ); + } + }); } @@ -126,9 +144,7 @@ class _ContactsScreenState extends State final connector = Provider.of(context, listen: false); final importContactFrame = buildImportContactFrame(hexString); await connector.sendFrame(importContactFrame); - // ScaffoldMessenger.of(context).showSnackBar( - // SnackBar(content: Text(context.l10n.contacts_contactAdded)), - // ); + _imported = true; } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(context.l10n.contacts_invalidAdvertFormat)), @@ -923,6 +939,7 @@ class _ContactsScreenState extends State _openChat(context, contact); }, ), + ], ListTile( leading: const Icon(Icons.delete, color: Colors.red), title: Text( @@ -997,7 +1014,7 @@ class _ContactTile extends StatelessWidget { ), title: Text(contact.name), subtitle: Text( - '${contact.typeLabel} • ${contact.pathLabel} $shotPublicKey', + '${contact.typeLabel}\n${contact.shortPubKeyHex}', ), // Clamp text scaling in trailing section to prevent overflow while // maintaining accessibility. Primary content (title/subtitle) scales normally. @@ -1019,13 +1036,24 @@ class _ContactTile extends StatelessWidget { _formatLastSeen(context, lastSeen), style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), - if (contact.hasLocation) - Icon(Icons.location_on, size: 14, color: Colors.grey[400]), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(contact.pathLabel, + style: TextStyle(fontSize: 12, color: Colors.grey[600])), + if (contact.hasLocation) + Icon(Icons.location_on, size: 14, color: Colors.grey[400]), + ], + ), + Text( + _formatLastSeen(context, lastSeen), + style: TextStyle(fontSize: 12, color: Colors.grey[600]), + ), + if (contact.hasLocation) + Icon(Icons.location_on, size: 14, color: Colors.grey[400]), ], ), ), - onTap: onTap, - onLongPress: onLongPress, ); }