mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-03 23:40:57 +10:00
Implement contact import functionality from clipboard and add relevant UI options
This commit is contained in:
@@ -98,6 +98,14 @@ class BufferWriter {
|
|||||||
}
|
}
|
||||||
writeBytes(bytes);
|
writeBytes(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void writeHex(String hex) {
|
||||||
|
List<int> result = [];
|
||||||
|
for (int i = 0; i < hex.length ~/ 2; i++) {
|
||||||
|
result.add(int.parse(hex.substring(i * 2, i * 2 + 2), radix: 16));
|
||||||
|
}
|
||||||
|
writeBytes(Uint8List.fromList(result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command codes (to device)
|
// Command codes (to device)
|
||||||
@@ -720,10 +728,10 @@ Uint8List buildExportContactFrame(Uint8List pubKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build a import contact frame
|
// Build a import contact frame
|
||||||
// [cmd][contact_frame x148]
|
// [cmd][contact_frame x98+]
|
||||||
Uint8List buildImportContactFrame(Uint8List contactFrame) {
|
Uint8List buildImportContactFrame(String contactFrame) {
|
||||||
final writer = BufferWriter();
|
final writer = BufferWriter();
|
||||||
writer.writeByte(cmdImportContact);
|
writer.writeByte(cmdImportContact);
|
||||||
writer.writeBytes(contactFrame);
|
writer.writeHex(contactFrame);
|
||||||
return writer.toBytes();
|
return writer.toBytes();
|
||||||
}
|
}
|
||||||
+5
-1
@@ -1308,5 +1308,9 @@
|
|||||||
"listFilter_repeaters": "Repeaters",
|
"listFilter_repeaters": "Repeaters",
|
||||||
"listFilter_roomServers": "Room servers",
|
"listFilter_roomServers": "Room servers",
|
||||||
"listFilter_unreadOnly": "Unread only",
|
"listFilter_unreadOnly": "Unread only",
|
||||||
"listFilter_newGroup": "New group"
|
"listFilter_newGroup": "New group",
|
||||||
|
|
||||||
|
"contacts_clipboardEmpty": "Clipboard Is Empty.",
|
||||||
|
"contacts_invalidAdvertFormat": "Invalid Contact Data",
|
||||||
|
"contacts_contactAdded": "Contact has been added."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,36 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _contactImport() async {
|
||||||
|
final clipboardData = await Clipboard.getData('text/plain');
|
||||||
|
if (clipboardData == null || clipboardData.text == null) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_clipboardEmpty)),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final text = clipboardData.text!.trim();
|
||||||
|
if (!text.startsWith('meshcore://')) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_invalidAdvertFormat)),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final hexString = text.substring('meshcore://'.length);
|
||||||
|
try {
|
||||||
|
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
|
||||||
|
final importContactFrame = buildImportContactFrame(hexString);
|
||||||
|
await connector.sendFrame(importContactFrame);
|
||||||
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
// SnackBar(content: Text(context.l10n.contacts_contactAdded)),
|
||||||
|
// );
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(context.l10n.contacts_invalidAdvertFormat)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final connector = context.watch<MeshCoreConnector>();
|
final connector = context.watch<MeshCoreConnector>();
|
||||||
@@ -166,21 +196,21 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
),
|
),
|
||||||
onTap: () => _contactExport(Uint8List.fromList([])),
|
onTap: () => _contactExport(Uint8List.fromList([])),
|
||||||
),
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.paste),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text("Add Contact from Clipboard"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () => _contactImport(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
icon: const Icon(Icons.connect_without_contact),
|
icon: const Icon(Icons.connect_without_contact),
|
||||||
),
|
),
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
itemBuilder: (context) => [
|
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(
|
PopupMenuItem(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -194,6 +224,16 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||||||
MaterialPageRoute(builder: (context) => const SettingsScreen()),
|
MaterialPageRoute(builder: (context) => const SettingsScreen()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.logout, color: Colors.red),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
const Text('Disconnect'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () => _disconnect(context, connector),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
icon: const Icon(Icons.more_vert),
|
icon: const Icon(Icons.more_vert),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user