From c37abb63e37b26ba25893f71fa97bcfd90047059 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Mon, 26 Jan 2026 11:56:42 -0800 Subject: [PATCH] add export and import contact frame builders in meshcore_protocol.dart and implement contact export functionality in contacts_screen.dart --- lib/connector/meshcore_protocol.dart | 18 ++++++ lib/screens/contacts_screen.dart | 89 ++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 11 deletions(-) diff --git a/lib/connector/meshcore_protocol.dart b/lib/connector/meshcore_protocol.dart index f9241e8..0e43e46 100644 --- a/lib/connector/meshcore_protocol.dart +++ b/lib/connector/meshcore_protocol.dart @@ -708,3 +708,21 @@ Uint8List buildSendBinaryReq(Uint8List repeaterPubKey, {Uint8List? payload}) { } return writer.toBytes(); } + +// Build a export contact frame +// [cmd][pub_key x32 / if empty exports your contact info] +Uint8List buildExportContactFrame(Uint8List pubKey) { + final writer = BufferWriter(); + writer.writeByte(cmdExportContact); + writer.writeBytes(pubKey); + return writer.toBytes(); +} + +// Build a import contact frame +// [cmd][contact_frame x148] +Uint8List buildImportContactFrame(Uint8List contactFrame) { + final writer = BufferWriter(); + writer.writeByte(cmdImportContact); + writer.writeBytes(contactFrame); + return writer.toBytes(); +} \ No newline at end of file diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index 54f819c..4c8e396 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -77,6 +78,13 @@ class _ContactsScreenState extends State await _groupStore.saveGroups(_groups); } + Future _contactExport(Uint8List pubKey) async { + final connector = Provider.of(context, listen: false); + final exportContactFrame = buildExportContactFrame(pubKey); + await connector.sendFrame(exportContactFrame); + return; + } + @override Widget build(BuildContext context) { final connector = context.watch(); @@ -96,18 +104,77 @@ class _ContactsScreenState extends State centerTitle: true, automaticallyImplyLeading: false, actions: [ - IconButton( - icon: const Icon(Icons.bluetooth_disabled), - tooltip: context.l10n.common_disconnect, - onPressed: () => _disconnect(context, connector), - ), - IconButton( - icon: const Icon(Icons.tune), - tooltip: context.l10n.common_settings, - onPressed: () => Navigator.push( - context, - MaterialPageRoute(builder: (context) => const SettingsScreen()), + PopupMenuButton(itemBuilder: (context) => [ + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.connect_without_contact), + const SizedBox(width: 8), + Text("Zero Hop Advert"), + ], + ), + onTap: () => { + connector.sendSelfAdvert(flood: false), + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(context.l10n.settings_advertisementSent))), + }, ), + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.cell_tower), + const SizedBox(width: 8), + Text("Flood Advert"), + ], + ), + onTap: () => { + connector.sendSelfAdvert(flood: true), + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(context.l10n.settings_advertisementSent))), + }, + ), + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.copy), + const SizedBox(width: 8), + Text("Copy Advert to Clipboard"), + ], + ), + onTap: () => _contactExport(Uint8List.fromList([])), + ), + ], + icon: const Icon(Icons.connect_without_contact), + ), + PopupMenuButton( + itemBuilder: (context) => [ + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.logout, color: Colors.red), + const SizedBox(width: 8), + const Text('Disconnect'), + ], + ), + onTap: () => _disconnect(context, connector), + ), + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.settings), + const SizedBox(width: 8), + const Text('Settings'), + ], + ), + onTap: () => Navigator.push( + context, + MaterialPageRoute(builder: (context) => const SettingsScreen()), + ), + ), + ], + icon: const Icon(Icons.more_vert), ), ], ),