mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-20 07:41:03 +10:00
Added zero-hop contact sharing functionality and related UI updates
This commit is contained in:
@@ -755,4 +755,13 @@ Uint8List buildImportContactFrame(String contactFrame) {
|
|||||||
writer.writeByte(cmdImportContact);
|
writer.writeByte(cmdImportContact);
|
||||||
writer.writeHex(contactFrame);
|
writer.writeHex(contactFrame);
|
||||||
return writer.toBytes();
|
return writer.toBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a export contact frame
|
||||||
|
// [cmd][pub_key x32]
|
||||||
|
Uint8List buildZeroHopContact(Uint8List pubKey) {
|
||||||
|
final writer = BufferWriter();
|
||||||
|
writer.writeByte(cmdShareContact);
|
||||||
|
writer.writeBytes(pubKey);
|
||||||
|
return writer.toBytes();
|
||||||
}
|
}
|
||||||
+7
-1
@@ -1338,5 +1338,11 @@
|
|||||||
"contacts_zeroHopAdvert":"Zero Hop Advert",
|
"contacts_zeroHopAdvert":"Zero Hop Advert",
|
||||||
"contacts_floodAdvert":"Flood Advert",
|
"contacts_floodAdvert":"Flood Advert",
|
||||||
"contacts_copyAdvertToClipboard":"Copy Advert to Clipboard",
|
"contacts_copyAdvertToClipboard":"Copy Advert to Clipboard",
|
||||||
"contacts_addContactFromClipboard":"Add Contact from Clipboard"
|
"contacts_addContactFromClipboard":"Add Contact from Clipboard",
|
||||||
|
"contacts_ShareContact": "Copy contact to Clipboard",
|
||||||
|
"contacts_ShareContactZeroHop": "Share contact by advert",
|
||||||
|
"contacts_zeroHopContactAdvertSent": "Sent contact by advert.",
|
||||||
|
"contacts_zeroHopContactAdvertFailed": "Failed to send contact.",
|
||||||
|
"contacts_contactAdvertCopied": "Advert copied to Clipboard.",
|
||||||
|
"contacts_contactAdvertCopyFailed": "Copying advert to Clipboard failed."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
Timer? _searchDebounce;
|
Timer? _searchDebounce;
|
||||||
|
|
||||||
bool _imported = false;
|
bool _imported = false;
|
||||||
|
bool _zeroHopContact = false;
|
||||||
|
bool _copyedContact = false;
|
||||||
|
|
||||||
StreamSubscription<Uint8List>? _frameSubscription;
|
StreamSubscription<Uint8List>? _frameSubscription;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -98,20 +101,53 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
Clipboard.setData(ClipboardData(text: "meshcore://$hexString"));
|
Clipboard.setData(ClipboardData(text: "meshcore://$hexString"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(code == respCodeOk && _imported) {
|
if(code == respCodeOk) {
|
||||||
// Show a snackbar indicating success
|
// Show a snackbar indicating success
|
||||||
|
if(_imported && mounted){
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_contactImported)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_zeroHopContact && mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_zeroHopContactAdvertSent)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_copyedContact && mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_contactAdvertCopied)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_copyedContact = false;
|
||||||
|
_zeroHopContact = false;
|
||||||
_imported = false;
|
_imported = false;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(content: Text(context.l10n.contacts_contactImported)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(code == respCodeErr && _imported) {
|
if(code == respCodeErr) {
|
||||||
// Show a snackbar indicating success
|
// Show a snackbar indicating failure
|
||||||
|
if(_imported && mounted){
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_contactImportFailed)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_zeroHopContact && mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_zeroHopContactAdvertFailed)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if(_copyedContact && mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_contactAdvertCopyFailed)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_copyedContact = false;
|
||||||
_imported = false;
|
_imported = false;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
_zeroHopContact = false;
|
||||||
SnackBar(content: Text(context.l10n.contacts_contactImportFailed)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -120,35 +156,49 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
Future<void> _contactExport(Uint8List pubKey) async {
|
Future<void> _contactExport(Uint8List pubKey) async {
|
||||||
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
|
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
|
||||||
final exportContactFrame = buildExportContactFrame(pubKey);
|
final exportContactFrame = buildExportContactFrame(pubKey);
|
||||||
|
_copyedContact = true;
|
||||||
await connector.sendFrame(exportContactFrame);
|
await connector.sendFrame(exportContactFrame);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _contactZeroHop(Uint8List pubKey) async {
|
||||||
|
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
|
||||||
|
final exportContactZeroHopFrame = buildZeroHopContact(pubKey);
|
||||||
|
_zeroHopContact = true;
|
||||||
|
await connector.sendFrame(exportContactZeroHopFrame);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _contactImport() async {
|
Future<void> _contactImport() async {
|
||||||
|
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
|
||||||
final clipboardData = await Clipboard.getData('text/plain');
|
final clipboardData = await Clipboard.getData('text/plain');
|
||||||
if (clipboardData == null || clipboardData.text == null) {
|
if (clipboardData == null || clipboardData.text == null) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
if(mounted) {
|
||||||
SnackBar(content: Text(context.l10n.contacts_clipboardEmpty)),
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
);
|
SnackBar(content: Text(context.l10n.contacts_clipboardEmpty)),
|
||||||
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final text = clipboardData.text!.trim();
|
final text = clipboardData.text!.trim();
|
||||||
if (!text.startsWith('meshcore://')) {
|
if (!text.startsWith('meshcore://')) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
if(mounted) {
|
||||||
SnackBar(content: Text(context.l10n.contacts_invalidAdvertFormat)),
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
);
|
SnackBar(content: Text(context.l10n.contacts_invalidAdvertFormat)),
|
||||||
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final hexString = text.substring('meshcore://'.length);
|
final hexString = text.substring('meshcore://'.length);
|
||||||
try {
|
try {
|
||||||
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
|
|
||||||
final importContactFrame = buildImportContactFrame(hexString);
|
final importContactFrame = buildImportContactFrame(hexString);
|
||||||
await connector.sendFrame(importContactFrame);
|
await connector.sendFrame(importContactFrame);
|
||||||
_imported = true;
|
_imported = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
if(mounted) {
|
||||||
SnackBar(content: Text(context.l10n.contacts_invalidAdvertFormat)),
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
);
|
SnackBar(content: Text(context.l10n.contacts_invalidAdvertFormat)),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -977,6 +1027,22 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.copy),
|
||||||
|
title: Text(context.l10n.contacts_ShareContact),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(sheetContext);
|
||||||
|
_contactExport(contact.publicKey);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.connect_without_contact),
|
||||||
|
title: Text(context.l10n.contacts_ShareContactZeroHop),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(sheetContext);
|
||||||
|
_contactZeroHop(contact.publicKey);
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.delete, color: Colors.red),
|
leading: const Icon(Icons.delete, color: Colors.red),
|
||||||
title: Text(
|
title: Text(
|
||||||
@@ -988,7 +1054,6 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
_confirmDelete(context, connector, contact);
|
_confirmDelete(context, connector, contact);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user