|
|
|
@ -54,50 +54,50 @@ class GpxExport {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void addRepeaters() {
|
|
|
|
void addRepeaters() {
|
|
|
|
final contacts = _connector.contacts;
|
|
|
|
final contacts = _connector.contacts
|
|
|
|
final repeaters = contacts
|
|
|
|
|
|
|
|
.where((c) => c.type == advTypeRepeater || c.type == advTypeRoom)
|
|
|
|
.where((c) => c.type == advTypeRepeater || c.type == advTypeRoom)
|
|
|
|
.toList();
|
|
|
|
.toList();
|
|
|
|
for (var repeater in repeaters) {
|
|
|
|
for (var contact in contacts) {
|
|
|
|
if (repeater.latitude == null || repeater.longitude == null) {
|
|
|
|
if (contact.latitude == null || contact.longitude == null) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_addContact(
|
|
|
|
_addContact(
|
|
|
|
repeater.name,
|
|
|
|
contact.name,
|
|
|
|
repeater.latitude ?? 0.0,
|
|
|
|
contact.latitude!,
|
|
|
|
repeater.longitude ?? 0.0,
|
|
|
|
contact.longitude!,
|
|
|
|
"Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}",
|
|
|
|
"Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}",
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void addContacts() {
|
|
|
|
void addContacts() {
|
|
|
|
final contacts = _connector.contacts;
|
|
|
|
final contacts = _connector.contacts
|
|
|
|
final repeaters = contacts.where((c) => c.type == advTypeChat).toList();
|
|
|
|
.where((c) => c.type == advTypeChat)
|
|
|
|
for (var repeater in repeaters) {
|
|
|
|
.toList();
|
|
|
|
if (repeater.latitude == null || repeater.longitude == null) {
|
|
|
|
for (var contact in contacts) {
|
|
|
|
|
|
|
|
if (contact.latitude == null || contact.longitude == null) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_addContact(
|
|
|
|
_addContact(
|
|
|
|
repeater.name,
|
|
|
|
contact.name,
|
|
|
|
repeater.latitude ?? 0.0,
|
|
|
|
contact.latitude!,
|
|
|
|
repeater.longitude ?? 0.0,
|
|
|
|
contact.longitude!,
|
|
|
|
"Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}",
|
|
|
|
"Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}",
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void addAll() {
|
|
|
|
void addAll() {
|
|
|
|
final contacts = _connector.contacts;
|
|
|
|
final contacts = _connector.contacts;
|
|
|
|
for (var repeater in contacts.toList()) {
|
|
|
|
for (var contact in contacts.toList()) {
|
|
|
|
if (repeater.latitude == null || repeater.longitude == null) {
|
|
|
|
if (contact.latitude == null || contact.longitude == null) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_addContact(
|
|
|
|
_addContact(
|
|
|
|
repeater.name,
|
|
|
|
contact.name,
|
|
|
|
repeater.latitude ?? 0.0,
|
|
|
|
contact.latitude ?? 0.0,
|
|
|
|
repeater.longitude ?? 0.0,
|
|
|
|
contact.longitude ?? 0.0,
|
|
|
|
"Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}",
|
|
|
|
"Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}",
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -149,23 +149,17 @@ class GpxExport {
|
|
|
|
.split('T')
|
|
|
|
.split('T')
|
|
|
|
.join('_');
|
|
|
|
.join('_');
|
|
|
|
|
|
|
|
|
|
|
|
// ignore: unnecessary_string_escapes
|
|
|
|
|
|
|
|
final path = '${dir.path}/$filename$timestamp.gpx';
|
|
|
|
final path = '${dir.path}/$filename$timestamp.gpx';
|
|
|
|
|
|
|
|
|
|
|
|
final file = File(path);
|
|
|
|
final file = File(path);
|
|
|
|
await file.writeAsString(xml);
|
|
|
|
await file.writeAsString(xml);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Modern share call (2025+ style)
|
|
|
|
|
|
|
|
final result = await SharePlus.instance.share(
|
|
|
|
final result = await SharePlus.instance.share(
|
|
|
|
ShareParams(
|
|
|
|
ShareParams(text: shareText, subject: subject, files: [XFile(path)]),
|
|
|
|
text: shareText,
|
|
|
|
|
|
|
|
subject: subject,
|
|
|
|
|
|
|
|
files: [XFile(path)],
|
|
|
|
|
|
|
|
// Optional: sharePositionOrigin: ... (if you want iPad popover positioning)
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// 4. Handle result
|
|
|
|
await file.delete();
|
|
|
|
|
|
|
|
|
|
|
|
switch (result.status) {
|
|
|
|
switch (result.status) {
|
|
|
|
case ShareResultStatus.success:
|
|
|
|
case ShareResultStatus.success:
|
|
|
|
debugPrint('Share successful – user completed the action.');
|
|
|
|
debugPrint('Share successful – user completed the action.');
|
|
|
|
@ -177,12 +171,8 @@ class GpxExport {
|
|
|
|
debugPrint('Sharing is not available on this platform / context.');
|
|
|
|
debugPrint('Sharing is not available on this platform / context.');
|
|
|
|
return gpxExportNotAvailable;
|
|
|
|
return gpxExportNotAvailable;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Optional cleanup (uncomment if you don't want to keep the file)
|
|
|
|
|
|
|
|
// await file.delete();
|
|
|
|
|
|
|
|
} catch (e, stack) {
|
|
|
|
} catch (e, stack) {
|
|
|
|
debugPrint('Export or share failed: $e\n$stack');
|
|
|
|
debugPrint('Export or share failed: $e\n$stack');
|
|
|
|
// → here you could show a SnackBar / AlertDialog in real UI code
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return gpxExportFailed;
|
|
|
|
return gpxExportFailed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|