From 8b1228bf8d8d05f558f897769f9cee830e5d4995 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Thu, 5 Feb 2026 13:38:49 -0800 Subject: [PATCH 1/6] Add GPX export functionality and related UI components --- lib/l10n/app_en.arb | 13 ++- lib/screens/settings_screen.dart | 70 +++++++++++++ lib/utils/gpx_export.dart | 165 +++++++++++++++++++++++++++++++ pubspec.yaml | 3 + 4 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 lib/utils/gpx_export.dart diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ee5cf7d..8f501e0 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1343,5 +1343,16 @@ "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." + "contacts_contactAdvertCopyFailed": "Copying advert to Clipboard failed.", + + "settings_gpxExportRepeaters": "Export repeaters to GPX", + "settings_gpxExportRepeatersSubtitle": "Exports repeaters with a location to GPX file.", + "settings_gpxExportContacts": "Export contacts to GPX", + "settings_gpxExportContactsSubtitle": "Exports chat contacts with a location to GPX file.", + "settings_gpxExportAll": "Export all to GPX", + "settings_gpxExportAllSubtitle": "Exports all contacts with a location to GPX file.", + "settings_gpxExportSuccess": "Successfully exported GPX file.", + "settings_gpxExportNoContacts": "No contacts to export.", + "settings_gpxExportNotAvailable": "Not supported on your device/OS", + "settings_gpxExportError": "There was an error when exporting." } diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 415d508..cbcbc0d 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:meshcore_open/utils/gpx_export.dart'; import 'package:meshcore_open/widgets/elements_ui.dart'; import 'package:provider/provider.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -57,6 +58,8 @@ class _SettingsScreenState extends State { const SizedBox(height: 16), _buildDebugCard(context), const SizedBox(height: 16), + _buildExportCard(connector), + const SizedBox(height: 16), _buildAboutCard(context), ], ); @@ -684,6 +687,73 @@ class _SettingsScreenState extends State { ], ); } + + _gpxExport(GpxExport exporter) async { + final l10n = context.l10n; + final result = await exporter.exportGPX(); + // Implement GPX export functionality here + switch (result) { + case GpxExportSuccess: + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportSuccess))); + case GpxExportNoContacts: + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportNoContacts))); + case GpxExportNotAvailable: + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportNotAvailable))); + case GpxExportFailed: + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportError))); + } + } + + _buildExportCard(MeshCoreConnector connector) { + final l10n = context.l10n; + return Card( + child: Column( + children: [ + ListTile( + leading: const Icon(Icons.download_outlined), + title: Text(l10n.settings_gpxExportRepeaters), + subtitle: Text(l10n.settings_gpxExportRepeatersSubtitle), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + final exporter = GpxExport(connector); + exporter.addRepeaters(); + _gpxExport(exporter); + }, + ), + ListTile( + leading: const Icon(Icons.download_outlined), + title: Text(l10n.settings_gpxExportContacts), + subtitle: Text(l10n.settings_gpxExportContactsSubtitle), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + final exporter = GpxExport(connector); + exporter.addContacts(); + _gpxExport(exporter); + }, + ), + ListTile( + leading: const Icon(Icons.download_outlined), + title: Text(l10n.settings_gpxExportAll), + subtitle: Text(l10n.settings_gpxExportAllSubtitle), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + final exporter = GpxExport(connector); + exporter.addAll(); + _gpxExport(exporter); + }, + ), + ], + ), + ); + } } class _RadioSettingsDialog extends StatefulWidget { diff --git a/lib/utils/gpx_export.dart b/lib/utils/gpx_export.dart new file mode 100644 index 0000000..ae1c128 --- /dev/null +++ b/lib/utils/gpx_export.dart @@ -0,0 +1,165 @@ +import 'package:flutter/foundation.dart'; +import 'package:gpx/gpx.dart'; +import 'package:meshcore_open/connector/meshcore_connector.dart'; +import 'package:meshcore_open/connector/meshcore_protocol.dart'; +import 'package:path_provider/path_provider.dart'; +import 'dart:io'; + +import 'package:share_plus/share_plus.dart'; + +class ContactExport { + final String name; + final double lat; + final double lon; + final String desc; + final double? ele; + + ContactExport({ + required this.name, + required this.lat, + required this.lon, + required this.desc, + this.ele, + }); +} + +const int GpxExportFailed = -1; +const int GpxExportSuccess = 1; +const int GpxExportNoContacts = 2; +const int GpxExportCancelled = 3; +const int GpxExportNotAvailable = 4; + +class GpxExport { + MeshCoreConnector _connector; + List _contacts = []; + + GpxExport(this._connector); + + void _addContact(String name, double lat, double lon, String desc, [double? ele]) { + _contacts.add(ContactExport( + name: name.trim(), + lat: lat, + lon: lon, + desc: desc.trim(), + ele: ele, + )); + } + + void addRepeaters() { + final contacts = _connector.contacts; + final repeaters = contacts.where((c) => c.type == advTypeRepeater || c.type == advTypeRoom).toList(); + for (var repeater in repeaters) { + if (repeater.latitude == null || repeater.longitude == null) { + continue; + } + _addContact( + repeater.name, + repeater.latitude ?? 0.0, + repeater.longitude ?? 0.0, + "Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}", + ); + } + } + + void addContacts() { + final contacts = _connector.contacts; + final repeaters = contacts.where((c) => c.type == advTypeChat).toList(); + for (var repeater in repeaters) { + if (repeater.latitude == null || repeater.longitude == null) { + continue; + } + _addContact( + repeater.name, + repeater.latitude ?? 0.0, + repeater.longitude ?? 0.0, + "Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}", + ); + } + } + + void addAll() { + final contacts = _connector.contacts; + for (var repeater in contacts.toList()) { + if (repeater.latitude == null || repeater.longitude == null) { + continue; + } + _addContact( + repeater.name, + repeater.latitude ?? 0.0, + repeater.longitude ?? 0.0, + "Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}", + ); + } + } + + Future exportGPX() async { + if (_contacts.isEmpty) { + debugPrint("No repeaters to export – nothing to share."); + return GpxExportNoContacts; + } + + try { + // 1. Build GPX content (your existing logic – unchanged here) + final gpx = Gpx() + ..version = '1.1' + ..creator = 'meshcore-open Repeater Exporter' + ..metadata = Metadata( + name: 'Meshcore Repeaters', + desc: 'Repeater & room locations exported from meshcore-open', + time: DateTime.now().toUtc(), + ); + + gpx.wpts = _contacts.map((c) => Wpt( + lat: c.lat, + lon: c.lon, + ele: c.ele, + name: c.name, + desc: c.desc, + )).toList(); + + final xml = GpxWriter().asString(gpx, pretty: true); + + // 2. Save to file + final dir = await getApplicationDocumentsDirectory(); + final timestamp = DateTime.now().toUtc().toIso8601String() + .replaceAll(':', '-') + .replaceAll('.', '-') + .split('T') + .join('_'); + final path = '${dir.path}/meshcore_repeaters_$timestamp.gpx'; + + final file = File(path); + await file.writeAsString(xml); + + // 3. Modern share call (2025+ style) + final result = await SharePlus.instance.share( + ShareParams( + text: 'Repeater locations exported from meshcore-open app as GPX file.', + subject: 'Meshcore Repeaters GPX Export', + files: [XFile(path)], + // Optional: sharePositionOrigin: ... (if you want iPad popover positioning) + ), + ); + + // 4. Handle result + switch (result.status) { + case ShareResultStatus.success: + debugPrint('Share successful – user completed the action.'); + return GpxExportSuccess; + case ShareResultStatus.dismissed: + debugPrint('Share sheet was dismissed / cancelled by user.'); + return GpxExportCancelled; + case ShareResultStatus.unavailable: + debugPrint('Sharing is not available on this platform / context.'); + return GpxExportNotAvailable; + } + + // Optional cleanup (uncomment if you don't want to keep the file) + // await file.delete(); + } catch (e, stack) { + debugPrint('Export or share failed: $e\n$stack'); + // → here you could show a SnackBar / AlertDialog in real UI code + } + return GpxExportFailed; + } +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 8b1415f..6312ee3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -57,6 +57,9 @@ dependencies: qr_flutter: ^4.1.0 # QR code generation url_launcher: ^6.3.0 # Launch URLs in system browser flutter_linkify: ^6.0.0 # Auto-detect and linkify URLs in text + gpx: ^2.3.0 + path_provider: ^2.1.5 + share_plus: ^12.0.1 dev_dependencies: flutter_test: From 978ea4790da8dccb323d9dd5b6a2677ee15ea197 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Thu, 5 Feb 2026 13:46:05 -0800 Subject: [PATCH 2/6] Refactor GPX export constants to use lowercase naming convention and improve export function error handling --- lib/screens/settings_screen.dart | 10 +++++----- lib/utils/gpx_export.dart | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index cbcbc0d..c5a307f 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -691,21 +691,21 @@ class _SettingsScreenState extends State { _gpxExport(GpxExport exporter) async { final l10n = context.l10n; final result = await exporter.exportGPX(); - // Implement GPX export functionality here + if(!mounted) return; switch (result) { - case GpxExportSuccess: + case gpxExportSuccess: ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportSuccess))); - case GpxExportNoContacts: + case gpxExportNoContacts: ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportNoContacts))); - case GpxExportNotAvailable: + case gpxExportNotAvailable: ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportNotAvailable))); - case GpxExportFailed: + case gpxExportFailed: ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportError))); diff --git a/lib/utils/gpx_export.dart b/lib/utils/gpx_export.dart index ae1c128..12c6e27 100644 --- a/lib/utils/gpx_export.dart +++ b/lib/utils/gpx_export.dart @@ -23,15 +23,15 @@ class ContactExport { }); } -const int GpxExportFailed = -1; -const int GpxExportSuccess = 1; -const int GpxExportNoContacts = 2; -const int GpxExportCancelled = 3; -const int GpxExportNotAvailable = 4; +const int gpxExportFailed = -1; +const int gpxExportSuccess = 1; +const int gpxExportNoContacts = 2; +const int gpxExportCancelled = 3; +const int gpxExportNotAvailable = 4; class GpxExport { - MeshCoreConnector _connector; - List _contacts = []; + final MeshCoreConnector _connector; + final List _contacts = []; GpxExport(this._connector); @@ -95,7 +95,7 @@ class GpxExport { Future exportGPX() async { if (_contacts.isEmpty) { debugPrint("No repeaters to export – nothing to share."); - return GpxExportNoContacts; + return gpxExportNoContacts; } try { @@ -145,13 +145,13 @@ class GpxExport { switch (result.status) { case ShareResultStatus.success: debugPrint('Share successful – user completed the action.'); - return GpxExportSuccess; + return gpxExportSuccess; case ShareResultStatus.dismissed: debugPrint('Share sheet was dismissed / cancelled by user.'); - return GpxExportCancelled; + return gpxExportCancelled; case ShareResultStatus.unavailable: 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) @@ -160,6 +160,6 @@ class GpxExport { debugPrint('Export or share failed: $e\n$stack'); // → here you could show a SnackBar / AlertDialog in real UI code } - return GpxExportFailed; + return gpxExportFailed; } } \ No newline at end of file From d1009d3c20c79a500675511a38b4ed0725f8bbff Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sat, 7 Feb 2026 11:07:57 -0800 Subject: [PATCH 3/6] ran formating --- lib/screens/settings_screen.dart | 18 ++++----- lib/utils/gpx_export.dart | 65 ++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index c5a307f..6dfbc0a 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -687,24 +687,24 @@ class _SettingsScreenState extends State { ], ); } - + _gpxExport(GpxExport exporter) async { final l10n = context.l10n; final result = await exporter.exportGPX(); - if(!mounted) return; + if (!mounted) return; switch (result) { case gpxExportSuccess: ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportSuccess))); case gpxExportNoContacts: - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportNoContacts))); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(l10n.settings_gpxExportNoContacts)), + ); case gpxExportNotAvailable: - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportNotAvailable))); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(l10n.settings_gpxExportNotAvailable)), + ); case gpxExportFailed: ScaffoldMessenger.of( context, @@ -728,7 +728,7 @@ class _SettingsScreenState extends State { _gpxExport(exporter); }, ), - ListTile( + ListTile( leading: const Icon(Icons.download_outlined), title: Text(l10n.settings_gpxExportContacts), subtitle: Text(l10n.settings_gpxExportContactsSubtitle), diff --git a/lib/utils/gpx_export.dart b/lib/utils/gpx_export.dart index 12c6e27..995f34c 100644 --- a/lib/utils/gpx_export.dart +++ b/lib/utils/gpx_export.dart @@ -35,19 +35,29 @@ class GpxExport { GpxExport(this._connector); - void _addContact(String name, double lat, double lon, String desc, [double? ele]) { - _contacts.add(ContactExport( - name: name.trim(), - lat: lat, - lon: lon, - desc: desc.trim(), - ele: ele, - )); + void _addContact( + String name, + double lat, + double lon, + String desc, [ + double? ele, + ]) { + _contacts.add( + ContactExport( + name: name.trim(), + lat: lat, + lon: lon, + desc: desc.trim(), + ele: ele, + ), + ); } void addRepeaters() { final contacts = _connector.contacts; - final repeaters = contacts.where((c) => c.type == advTypeRepeater || c.type == advTypeRoom).toList(); + final repeaters = contacts + .where((c) => c.type == advTypeRepeater || c.type == advTypeRoom) + .toList(); for (var repeater in repeaters) { if (repeater.latitude == null || repeater.longitude == null) { continue; @@ -79,7 +89,7 @@ class GpxExport { void addAll() { final contacts = _connector.contacts; - for (var repeater in contacts.toList()) { + for (var repeater in contacts.toList()) { if (repeater.latitude == null || repeater.longitude == null) { continue; } @@ -104,24 +114,30 @@ class GpxExport { ..version = '1.1' ..creator = 'meshcore-open Repeater Exporter' ..metadata = Metadata( - name: 'Meshcore Repeaters', - desc: 'Repeater & room locations exported from meshcore-open', - time: DateTime.now().toUtc(), - ); + name: 'Meshcore Repeaters', + desc: 'Repeater & room locations exported from meshcore-open', + time: DateTime.now().toUtc(), + ); - gpx.wpts = _contacts.map((c) => Wpt( - lat: c.lat, - lon: c.lon, - ele: c.ele, - name: c.name, - desc: c.desc, - )).toList(); + gpx.wpts = _contacts + .map( + (c) => Wpt( + lat: c.lat, + lon: c.lon, + ele: c.ele, + name: c.name, + desc: c.desc, + ), + ) + .toList(); final xml = GpxWriter().asString(gpx, pretty: true); // 2. Save to file final dir = await getApplicationDocumentsDirectory(); - final timestamp = DateTime.now().toUtc().toIso8601String() + final timestamp = DateTime.now() + .toUtc() + .toIso8601String() .replaceAll(':', '-') .replaceAll('.', '-') .split('T') @@ -134,7 +150,8 @@ class GpxExport { // 3. Modern share call (2025+ style) final result = await SharePlus.instance.share( ShareParams( - text: 'Repeater locations exported from meshcore-open app as GPX file.', + text: + 'Repeater locations exported from meshcore-open app as GPX file.', subject: 'Meshcore Repeaters GPX Export', files: [XFile(path)], // Optional: sharePositionOrigin: ... (if you want iPad popover positioning) @@ -162,4 +179,4 @@ class GpxExport { } return gpxExportFailed; } -} \ No newline at end of file +} From 2a909e60813ee2427c8bd7e0892bcae1010ee157 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sat, 7 Feb 2026 19:45:02 -0800 Subject: [PATCH 4/6] Enhance GPX export functionality with customizable parameters and improved metadata --- lib/l10n/app_en.arb | 17 ++++++++---- lib/screens/settings_screen.dart | 47 ++++++++++++++++++++++++++++---- lib/utils/gpx_export.dart | 23 ++++++++++------ 3 files changed, 68 insertions(+), 19 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8f501e0..18b5c6c 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1345,14 +1345,19 @@ "contacts_contactAdvertCopied": "Advert copied to Clipboard.", "contacts_contactAdvertCopyFailed": "Copying advert to Clipboard failed.", - "settings_gpxExportRepeaters": "Export repeaters to GPX", - "settings_gpxExportRepeatersSubtitle": "Exports repeaters with a location to GPX file.", - "settings_gpxExportContacts": "Export contacts to GPX", - "settings_gpxExportContactsSubtitle": "Exports chat contacts with a location to GPX file.", - "settings_gpxExportAll": "Export all to GPX", + "settings_gpxExportRepeaters": "Export repeaters / room server to GPX", + "settings_gpxExportRepeatersSubtitle": "Exports repeaters / roomserver with a location to GPX file.", + "settings_gpxExportContacts": "Export companions to GPX", + "settings_gpxExportContactsSubtitle": "Exports companions with a location to GPX file.", + "settings_gpxExportAll": "Export all contacts to GPX", "settings_gpxExportAllSubtitle": "Exports all contacts with a location to GPX file.", "settings_gpxExportSuccess": "Successfully exported GPX file.", "settings_gpxExportNoContacts": "No contacts to export.", "settings_gpxExportNotAvailable": "Not supported on your device/OS", - "settings_gpxExportError": "There was an error when exporting." + "settings_gpxExportError": "There was an error when exporting.", + "settings_gpxExportRepeatersRoom": "Repeater & room server locations", + "settings_gpxExportChat": "Companion locations", + "settings_gpxExportAllContacts": "All contacts locations", + "settings_gpxExportShareText": "Map data exported from meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open GPX map data export" } diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 6dfbc0a..2212b8d 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -688,9 +688,22 @@ class _SettingsScreenState extends State { ); } - _gpxExport(GpxExport exporter) async { + _gpxExport( + GpxExport exporter, + String name, + String description, + String filename, + String shareText, + String subject, + ) async { final l10n = context.l10n; - final result = await exporter.exportGPX(); + final result = await exporter.exportGPX( + name, + description, + filename, + shareText, + subject, + ); if (!mounted) return; switch (result) { case gpxExportSuccess: @@ -701,14 +714,17 @@ class _SettingsScreenState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(l10n.settings_gpxExportNoContacts)), ); + break; case gpxExportNotAvailable: ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(l10n.settings_gpxExportNotAvailable)), ); + break; case gpxExportFailed: ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.settings_gpxExportError))); + break; } } @@ -725,7 +741,14 @@ class _SettingsScreenState extends State { onTap: () async { final exporter = GpxExport(connector); exporter.addRepeaters(); - _gpxExport(exporter); + _gpxExport( + exporter, + l10n.map_repeater, + l10n.settings_gpxExportRepeatersRoom, + "meshcore_repeaters_", + l10n.settings_gpxExportShareText, + l10n.settings_gpxExportShareSubject, + ); }, ), ListTile( @@ -736,7 +759,14 @@ class _SettingsScreenState extends State { onTap: () async { final exporter = GpxExport(connector); exporter.addContacts(); - _gpxExport(exporter); + _gpxExport( + exporter, + l10n.map_repeater, + l10n.settings_gpxExportChat, + "meshcore_contacts_", + l10n.settings_gpxExportShareText, + l10n.settings_gpxExportShareSubject, + ); }, ), ListTile( @@ -747,7 +777,14 @@ class _SettingsScreenState extends State { onTap: () async { final exporter = GpxExport(connector); exporter.addAll(); - _gpxExport(exporter); + _gpxExport( + exporter, + l10n.map_repeater, + l10n.settings_gpxExportAllContacts, + "meshcore_all_", + l10n.settings_gpxExportShareText, + l10n.settings_gpxExportShareSubject, + ); }, ), ], diff --git a/lib/utils/gpx_export.dart b/lib/utils/gpx_export.dart index 995f34c..92494c9 100644 --- a/lib/utils/gpx_export.dart +++ b/lib/utils/gpx_export.dart @@ -102,7 +102,13 @@ class GpxExport { } } - Future exportGPX() async { + Future exportGPX( + String name, + String description, + String filename, + String shareText, + String subject, + ) async { if (_contacts.isEmpty) { debugPrint("No repeaters to export – nothing to share."); return gpxExportNoContacts; @@ -112,10 +118,10 @@ class GpxExport { // 1. Build GPX content (your existing logic – unchanged here) final gpx = Gpx() ..version = '1.1' - ..creator = 'meshcore-open Repeater Exporter' + ..creator = 'meshcore-open exporter' ..metadata = Metadata( - name: 'Meshcore Repeaters', - desc: 'Repeater & room locations exported from meshcore-open', + name: name, + desc: description, time: DateTime.now().toUtc(), ); @@ -142,7 +148,9 @@ class GpxExport { .replaceAll('.', '-') .split('T') .join('_'); - final path = '${dir.path}/meshcore_repeaters_$timestamp.gpx'; + + // ignore: unnecessary_string_escapes + final path = '${dir.path}/$filename$timestamp.gpx'; final file = File(path); await file.writeAsString(xml); @@ -150,9 +158,8 @@ class GpxExport { // 3. Modern share call (2025+ style) final result = await SharePlus.instance.share( ShareParams( - text: - 'Repeater locations exported from meshcore-open app as GPX file.', - subject: 'Meshcore Repeaters GPX Export', + text: shareText, + subject: subject, files: [XFile(path)], // Optional: sharePositionOrigin: ... (if you want iPad popover positioning) ), From bcae6ac19f73da9447cbfc89311ed33ddcf148ba Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 8 Feb 2026 12:14:03 -0800 Subject: [PATCH 5/6] Updated GPX export functionality for contacts and repeaters in multiple languages. --- lib/l10n/app_bg.arb | 17 +++++- lib/l10n/app_de.arb | 17 +++++- lib/l10n/app_es.arb | 17 +++++- lib/l10n/app_fr.arb | 17 +++++- lib/l10n/app_it.arb | 17 +++++- lib/l10n/app_localizations.dart | 90 ++++++++++++++++++++++++++++++ lib/l10n/app_localizations_bg.dart | 54 ++++++++++++++++++ lib/l10n/app_localizations_de.dart | 54 ++++++++++++++++++ lib/l10n/app_localizations_en.dart | 53 ++++++++++++++++++ lib/l10n/app_localizations_es.dart | 54 ++++++++++++++++++ lib/l10n/app_localizations_fr.dart | 57 +++++++++++++++++++ lib/l10n/app_localizations_it.dart | 55 ++++++++++++++++++ lib/l10n/app_localizations_nl.dart | 53 ++++++++++++++++++ lib/l10n/app_localizations_pl.dart | 54 ++++++++++++++++++ lib/l10n/app_localizations_pt.dart | 53 ++++++++++++++++++ lib/l10n/app_localizations_ru.dart | 53 ++++++++++++++++++ lib/l10n/app_localizations_sk.dart | 53 ++++++++++++++++++ lib/l10n/app_localizations_sl.dart | 53 ++++++++++++++++++ lib/l10n/app_localizations_sv.dart | 54 ++++++++++++++++++ lib/l10n/app_localizations_uk.dart | 53 ++++++++++++++++++ lib/l10n/app_localizations_zh.dart | 45 +++++++++++++++ lib/l10n/app_nl.arb | 17 +++++- lib/l10n/app_pl.arb | 17 +++++- lib/l10n/app_pt.arb | 17 +++++- lib/l10n/app_ru.arb | 17 +++++- lib/l10n/app_sk.arb | 17 +++++- lib/l10n/app_sl.arb | 17 +++++- lib/l10n/app_sv.arb | 17 +++++- lib/l10n/app_uk.arb | 17 +++++- lib/l10n/app_zh.arb | 17 +++++- 30 files changed, 1112 insertions(+), 14 deletions(-) diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index 460bc9d..7a9d522 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopied": "Рекламата е копирана в клипборда.", "contacts_zeroHopContactAdvertFailed": "Неуспешно изпращане на контакт.", "contacts_zeroHopContactAdvertSent": "Изпратен контакт по обява.", - "contacts_contactAdvertCopyFailed": "Копирането на обявата в клипборда не успя." + "contacts_contactAdvertCopyFailed": "Копирането на обявата в клипборда не успя.", + "settings_gpxExportContactsSubtitle": "Експортира спътници с местоположение в GPX файл.", + "settings_gpxExportRepeatersSubtitle": "Изпраща повторители / roomserver с местоположение в GPX файл.", + "settings_gpxExportAll": "Експортирай всички контакти в GPX", + "settings_gpxExportAllSubtitle": "Експортира всички контакти с местоположение в файл GPX.", + "settings_gpxExportRepeaters": "Експортиране на повтарящи се устройства / сървър на стаята до GPX", + "settings_gpxExportContacts": "Експортирай спътници към GPX", + "settings_gpxExportSuccess": "Успешно изlexport на файл GPX.", + "settings_gpxExportNoContacts": "Няма контакти за изlexport.", + "settings_gpxExportChat": "Местоположения на спътници", + "settings_gpxExportError": "Възникна грешка при изнасяне.", + "settings_gpxExportRepeatersRoom": "Местоположения на повторител и сървър на стаята", + "settings_gpxExportNotAvailable": "Не е поддържан на вашето устройство/ОС", + "settings_gpxExportAllContacts": "Местоположения на всички контакти", + "settings_gpxExportShareText": "Картинни данни изнесени от meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open износ на данни за карта в формат GPX" } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 0a72559..add286c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1568,5 +1568,20 @@ "contacts_zeroHopContactAdvertFailed": "Kontakt konnte nicht gesendet werden.", "contacts_zeroHopContactAdvertSent": "Kontakt über Anzeige gesendet", "contacts_contactAdvertCopied": "Anzeige in die Zwischenablage kopiert.", - "contacts_contactAdvertCopyFailed": "Kopieren des Werbeinhalts in die Zwischenablage fehlgeschlagen." + "contacts_contactAdvertCopyFailed": "Kopieren des Werbeinhalts in die Zwischenablage fehlgeschlagen.", + "settings_gpxExportAll": "Alle Kontakte nach GPX exportieren", + "settings_gpxExportAllSubtitle": "Exportiert alle Kontakte mit einem Standort in eine GPX-Datei.", + "settings_gpxExportRepeaters": "Repeater und Raumserver nach GPX exportieren", + "settings_gpxExportContacts": "Begleiter nach GPX exportieren", + "settings_gpxExportRepeatersSubtitle": "Exportiert Repeater und Raumserver mit einem Standort in eine GPX-Datei.", + "settings_gpxExportContactsSubtitle": "Exportiert Begleiter mit einem Ort in eine GPX-Datei.", + "settings_gpxExportRepeatersRoom": "Repeater- und Raumserver-Standorte", + "settings_gpxExportChat": "Begleiterstandorte", + "settings_gpxExportNoContacts": "Keine Kontakte zum Exportieren.", + "settings_gpxExportError": "Beim Export ist ein Fehler aufgetreten.", + "settings_gpxExportNotAvailable": "Nicht auf Ihrem Gerät/Betriebssystem unterstützt", + "settings_gpxExportSuccess": "Erfolgreich GPX-Datei exportiert.", + "settings_gpxExportAllContacts": "Alle Kontaktstandorte", + "settings_gpxExportShareSubject": "meshcore-open GPX-Kartendaten exportieren", + "settings_gpxExportShareText": "Kartendaten aus meshcore-open exportiert" } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index c6dad1f..f808409 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1568,5 +1568,20 @@ "contacts_zeroHopContactAdvertFailed": "No se pudo enviar el contacto.", "contacts_zeroHopContactAdvertSent": "Envió contacto por anuncio.", "contacts_contactAdvertCopied": "Anuncio copiado al Portapapeles.", - "contacts_contactAdvertCopyFailed": "Copiar anuncio al Portapapeles ha fallado." + "contacts_contactAdvertCopyFailed": "Copiar anuncio al Portapapeles ha fallado.", + "settings_gpxExportContactsSubtitle": "Exporta compañeros con una ubicación a archivo GPX.", + "settings_gpxExportRepeaters": "Exportar repetidores / servidor de sala a GPX", + "settings_gpxExportSuccess": "Archivo GPX exportado con éxito.", + "settings_gpxExportNoContacts": "No hay contactos para exportar.", + "settings_gpxExportNotAvailable": "No compatible con tu dispositivo/SO", + "settings_gpxExportError": "Hubo un error al exportar.", + "settings_gpxExportRepeatersSubtitle": "Exporta repetidores o roomserver con una ubicación a un archivo GPX.", + "settings_gpxExportAllSubtitle": "Exporta todos los contactos con una ubicación a un archivo GPX.", + "settings_gpxExportAll": "Exportar todos los contactos a GPX", + "settings_gpxExportContacts": "Exportar compañeros a GPX", + "settings_gpxExportChat": "Ubicaciones de compañero", + "settings_gpxExportRepeatersRoom": "Ubicaciones del servidor de repetidor y sala", + "settings_gpxExportAllContacts": "Todas las ubicaciones de contactos", + "settings_gpxExportShareText": "Datos del mapa exportados desde meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open exportación de datos de mapa GPX" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index c1157ed..532f791 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopied": "Annonce copiée dans le presse-papiers.", "contacts_contactAdvertCopyFailed": "La copie de l'annonce vers le presse-papiers a échoué.", "contacts_zeroHopContactAdvertSent": "Envoyer un contact par annonce.", - "contacts_zeroHopContactAdvertFailed": "Échec de l'envoi du contact." + "contacts_zeroHopContactAdvertFailed": "Échec de l'envoi du contact.", + "settings_gpxExportRepeaters": "Exporter les répéteurs / serveur de salle au format GPX", + "settings_gpxExportRepeatersSubtitle": "Exporte les répéteurs / roomserver avec une localisation vers un fichier GPX.", + "settings_gpxExportNoContacts": "Aucun contact à exporter.", + "settings_gpxExportNotAvailable": "Non pris en charge sur votre appareil/Système d'exploitation", + "settings_gpxExportError": "Une erreur s'est produite lors de l'exportation.", + "settings_gpxExportRepeatersRoom": "Emplacements des serveurs de répéteur et de salle", + "settings_gpxExportContacts": "Exporter les compagnons au format GPX", + "settings_gpxExportAll": "Exporter tous les contacts au format GPX", + "settings_gpxExportAllSubtitle": "Exporte tous les contacts avec une localisation vers un fichier GPX.", + "settings_gpxExportContactsSubtitle": "Exporte les compagnons avec un emplacement vers un fichier GPX.", + "settings_gpxExportChat": "Emplacements des compagnons", + "settings_gpxExportSuccess": "Fichier GPX exporté avec succès.", + "settings_gpxExportAllContacts": "Tous les emplacements des contacts", + "settings_gpxExportShareText": "Données de carte exportées à partir de meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open exporter les données de carte GPX" } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index c32e863..28aea4e 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopyFailed": "Copia dell'annuncio nella Clipboard non riuscita.", "contacts_ShareContactZeroHop": "Condividi contatto tramite annuncio", "contacts_zeroHopContactAdvertFailed": "Invio del contatto non riuscito.", - "contacts_contactAdvertCopied": "Annuncio copiato negli Appunti." + "contacts_contactAdvertCopied": "Annuncio copiato negli Appunti.", + "settings_gpxExportRepeaters": "Esporta ripetitori / server di stanza in GPX", + "settings_gpxExportContacts": "Esporta compagni in GPX", + "settings_gpxExportSuccess": "Esportazione del file GPX completata con successo.", + "settings_gpxExportNoContacts": "Nessun contatto da esportare.", + "settings_gpxExportNotAvailable": "Non supportato sul tuo dispositivo/Sistema Operativo", + "settings_gpxExportError": "Si è verificato un errore durante l'esportazione.", + "settings_gpxExportRepeatersSubtitle": "Esporta ripetitori / roomserver con una posizione in un file GPX.", + "settings_gpxExportContactsSubtitle": "Esporta i compagni con una posizione in un file GPX.", + "settings_gpxExportAll": "Esporta tutti i contatti in GPX", + "settings_gpxExportAllSubtitle": "Esporta tutti i contatti con una posizione in un file GPX.", + "settings_gpxExportChat": "Posizioni dei compagni", + "settings_gpxExportRepeatersRoom": "Posizioni del server ripetitore e della stanza", + "settings_gpxExportAllContacts": "Tutte le posizioni dei contatti", + "settings_gpxExportShareText": "Dati mappa esportati da meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open esportazione dati mappa GPX" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 055667f..2ec2fa8 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -4855,6 +4855,96 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Copying advert to Clipboard failed.'** String get contacts_contactAdvertCopyFailed; + + /// No description provided for @settings_gpxExportRepeaters. + /// + /// In en, this message translates to: + /// **'Export repeaters / room server to GPX'** + String get settings_gpxExportRepeaters; + + /// No description provided for @settings_gpxExportRepeatersSubtitle. + /// + /// In en, this message translates to: + /// **'Exports repeaters / roomserver with a location to GPX file.'** + String get settings_gpxExportRepeatersSubtitle; + + /// No description provided for @settings_gpxExportContacts. + /// + /// In en, this message translates to: + /// **'Export companions to GPX'** + String get settings_gpxExportContacts; + + /// No description provided for @settings_gpxExportContactsSubtitle. + /// + /// In en, this message translates to: + /// **'Exports companions with a location to GPX file.'** + String get settings_gpxExportContactsSubtitle; + + /// No description provided for @settings_gpxExportAll. + /// + /// In en, this message translates to: + /// **'Export all contacts to GPX'** + String get settings_gpxExportAll; + + /// No description provided for @settings_gpxExportAllSubtitle. + /// + /// In en, this message translates to: + /// **'Exports all contacts with a location to GPX file.'** + String get settings_gpxExportAllSubtitle; + + /// No description provided for @settings_gpxExportSuccess. + /// + /// In en, this message translates to: + /// **'Successfully exported GPX file.'** + String get settings_gpxExportSuccess; + + /// No description provided for @settings_gpxExportNoContacts. + /// + /// In en, this message translates to: + /// **'No contacts to export.'** + String get settings_gpxExportNoContacts; + + /// No description provided for @settings_gpxExportNotAvailable. + /// + /// In en, this message translates to: + /// **'Not supported on your device/OS'** + String get settings_gpxExportNotAvailable; + + /// No description provided for @settings_gpxExportError. + /// + /// In en, this message translates to: + /// **'There was an error when exporting.'** + String get settings_gpxExportError; + + /// No description provided for @settings_gpxExportRepeatersRoom. + /// + /// In en, this message translates to: + /// **'Repeater & room server locations'** + String get settings_gpxExportRepeatersRoom; + + /// No description provided for @settings_gpxExportChat. + /// + /// In en, this message translates to: + /// **'Companion locations'** + String get settings_gpxExportChat; + + /// No description provided for @settings_gpxExportAllContacts. + /// + /// In en, this message translates to: + /// **'All contacts locations'** + String get settings_gpxExportAllContacts; + + /// No description provided for @settings_gpxExportShareText. + /// + /// In en, this message translates to: + /// **'Map data exported from meshcore-open'** + String get settings_gpxExportShareText; + + /// No description provided for @settings_gpxExportShareSubject. + /// + /// In en, this message translates to: + /// **'meshcore-open GPX map data export'** + String get settings_gpxExportShareSubject; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index 701429e..45a0267 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -2766,4 +2766,58 @@ class AppLocalizationsBg extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Копирането на обявата в клипборда не успя.'; + + @override + String get settings_gpxExportRepeaters => + 'Експортиране на повтарящи се устройства / сървър на стаята до GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Изпраща повторители / roomserver с местоположение в GPX файл.'; + + @override + String get settings_gpxExportContacts => 'Експортирай спътници към GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Експортира спътници с местоположение в GPX файл.'; + + @override + String get settings_gpxExportAll => 'Експортирай всички контакти в GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Експортира всички контакти с местоположение в файл GPX.'; + + @override + String get settings_gpxExportSuccess => 'Успешно изlexport на файл GPX.'; + + @override + String get settings_gpxExportNoContacts => 'Няма контакти за изlexport.'; + + @override + String get settings_gpxExportNotAvailable => + 'Не е поддържан на вашето устройство/ОС'; + + @override + String get settings_gpxExportError => 'Възникна грешка при изнасяне.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Местоположения на повторител и сървър на стаята'; + + @override + String get settings_gpxExportChat => 'Местоположения на спътници'; + + @override + String get settings_gpxExportAllContacts => + 'Местоположения на всички контакти'; + + @override + String get settings_gpxExportShareText => + 'Картинни данни изнесени от meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open износ на данни за карта в формат GPX'; } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 514a7a1..8c5c50b 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -2773,4 +2773,58 @@ class AppLocalizationsDe extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Kopieren des Werbeinhalts in die Zwischenablage fehlgeschlagen.'; + + @override + String get settings_gpxExportRepeaters => + 'Repeater und Raumserver nach GPX exportieren'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exportiert Repeater und Raumserver mit einem Standort in eine GPX-Datei.'; + + @override + String get settings_gpxExportContacts => 'Begleiter nach GPX exportieren'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exportiert Begleiter mit einem Ort in eine GPX-Datei.'; + + @override + String get settings_gpxExportAll => 'Alle Kontakte nach GPX exportieren'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exportiert alle Kontakte mit einem Standort in eine GPX-Datei.'; + + @override + String get settings_gpxExportSuccess => 'Erfolgreich GPX-Datei exportiert.'; + + @override + String get settings_gpxExportNoContacts => 'Keine Kontakte zum Exportieren.'; + + @override + String get settings_gpxExportNotAvailable => + 'Nicht auf Ihrem Gerät/Betriebssystem unterstützt'; + + @override + String get settings_gpxExportError => + 'Beim Export ist ein Fehler aufgetreten.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Repeater- und Raumserver-Standorte'; + + @override + String get settings_gpxExportChat => 'Begleiterstandorte'; + + @override + String get settings_gpxExportAllContacts => 'Alle Kontaktstandorte'; + + @override + String get settings_gpxExportShareText => + 'Kartendaten aus meshcore-open exportiert'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open GPX-Kartendaten exportieren'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 040d809..6667a36 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -2723,4 +2723,57 @@ class AppLocalizationsEn extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Copying advert to Clipboard failed.'; + + @override + String get settings_gpxExportRepeaters => + 'Export repeaters / room server to GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exports repeaters / roomserver with a location to GPX file.'; + + @override + String get settings_gpxExportContacts => 'Export companions to GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exports companions with a location to GPX file.'; + + @override + String get settings_gpxExportAll => 'Export all contacts to GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exports all contacts with a location to GPX file.'; + + @override + String get settings_gpxExportSuccess => 'Successfully exported GPX file.'; + + @override + String get settings_gpxExportNoContacts => 'No contacts to export.'; + + @override + String get settings_gpxExportNotAvailable => + 'Not supported on your device/OS'; + + @override + String get settings_gpxExportError => 'There was an error when exporting.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Repeater & room server locations'; + + @override + String get settings_gpxExportChat => 'Companion locations'; + + @override + String get settings_gpxExportAllContacts => 'All contacts locations'; + + @override + String get settings_gpxExportShareText => + 'Map data exported from meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open GPX map data export'; } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index e65cbcd..4661c25 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -2766,4 +2766,58 @@ class AppLocalizationsEs extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Copiar anuncio al Portapapeles ha fallado.'; + + @override + String get settings_gpxExportRepeaters => + 'Exportar repetidores / servidor de sala a GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exporta repetidores o roomserver con una ubicación a un archivo GPX.'; + + @override + String get settings_gpxExportContacts => 'Exportar compañeros a GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exporta compañeros con una ubicación a archivo GPX.'; + + @override + String get settings_gpxExportAll => 'Exportar todos los contactos a GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exporta todos los contactos con una ubicación a un archivo GPX.'; + + @override + String get settings_gpxExportSuccess => 'Archivo GPX exportado con éxito.'; + + @override + String get settings_gpxExportNoContacts => 'No hay contactos para exportar.'; + + @override + String get settings_gpxExportNotAvailable => + 'No compatible con tu dispositivo/SO'; + + @override + String get settings_gpxExportError => 'Hubo un error al exportar.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Ubicaciones del servidor de repetidor y sala'; + + @override + String get settings_gpxExportChat => 'Ubicaciones de compañero'; + + @override + String get settings_gpxExportAllContacts => + 'Todas las ubicaciones de contactos'; + + @override + String get settings_gpxExportShareText => + 'Datos del mapa exportados desde meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open exportación de datos de mapa GPX'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 4496fc8..f0d8148 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -2787,4 +2787,61 @@ class AppLocalizationsFr extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'La copie de l\'annonce vers le presse-papiers a échoué.'; + + @override + String get settings_gpxExportRepeaters => + 'Exporter les répéteurs / serveur de salle au format GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exporte les répéteurs / roomserver avec une localisation vers un fichier GPX.'; + + @override + String get settings_gpxExportContacts => + 'Exporter les compagnons au format GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exporte les compagnons avec un emplacement vers un fichier GPX.'; + + @override + String get settings_gpxExportAll => + 'Exporter tous les contacts au format GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exporte tous les contacts avec une localisation vers un fichier GPX.'; + + @override + String get settings_gpxExportSuccess => 'Fichier GPX exporté avec succès.'; + + @override + String get settings_gpxExportNoContacts => 'Aucun contact à exporter.'; + + @override + String get settings_gpxExportNotAvailable => + 'Non pris en charge sur votre appareil/Système d\'exploitation'; + + @override + String get settings_gpxExportError => + 'Une erreur s\'est produite lors de l\'exportation.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Emplacements des serveurs de répéteur et de salle'; + + @override + String get settings_gpxExportChat => 'Emplacements des compagnons'; + + @override + String get settings_gpxExportAllContacts => + 'Tous les emplacements des contacts'; + + @override + String get settings_gpxExportShareText => + 'Données de carte exportées à partir de meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open exporter les données de carte GPX'; } diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index 02345c4..25c55af 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -2769,4 +2769,59 @@ class AppLocalizationsIt extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Copia dell\'annuncio nella Clipboard non riuscita.'; + + @override + String get settings_gpxExportRepeaters => + 'Esporta ripetitori / server di stanza in GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Esporta ripetitori / roomserver con una posizione in un file GPX.'; + + @override + String get settings_gpxExportContacts => 'Esporta compagni in GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Esporta i compagni con una posizione in un file GPX.'; + + @override + String get settings_gpxExportAll => 'Esporta tutti i contatti in GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Esporta tutti i contatti con una posizione in un file GPX.'; + + @override + String get settings_gpxExportSuccess => + 'Esportazione del file GPX completata con successo.'; + + @override + String get settings_gpxExportNoContacts => 'Nessun contatto da esportare.'; + + @override + String get settings_gpxExportNotAvailable => + 'Non supportato sul tuo dispositivo/Sistema Operativo'; + + @override + String get settings_gpxExportError => + 'Si è verificato un errore durante l\'esportazione.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Posizioni del server ripetitore e della stanza'; + + @override + String get settings_gpxExportChat => 'Posizioni dei compagni'; + + @override + String get settings_gpxExportAllContacts => 'Tutte le posizioni dei contatti'; + + @override + String get settings_gpxExportShareText => + 'Dati mappa esportati da meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open esportazione dati mappa GPX'; } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 292181f..5940333 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -2758,4 +2758,57 @@ class AppLocalizationsNl extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Kopiëren van advertentie naar Clipboard is mislukt.'; + + @override + String get settings_gpxExportRepeaters => + 'Exporteer repeaters / roomserver naar GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exporteert repeaters / roomserver met een locatie naar GPX-bestand.'; + + @override + String get settings_gpxExportContacts => 'Companions exporteren naar GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exporteert metgezellen met een locatie naar een GPX-bestand.'; + + @override + String get settings_gpxExportAll => 'Alle contacten exporteren naar GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exporteert alle contacten met een locatie naar een GPX-bestand.'; + + @override + String get settings_gpxExportSuccess => 'Succesvol GPX-bestand geëxporteerd.'; + + @override + String get settings_gpxExportNoContacts => 'Geen contacten om te exporteren.'; + + @override + String get settings_gpxExportNotAvailable => + 'Niet ondersteund op uw apparaat/besturingssysteem'; + + @override + String get settings_gpxExportError => 'Er was een fout bij het exporteren.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Repeater- en kamer servers locaties'; + + @override + String get settings_gpxExportChat => 'Locaties van metgezellen'; + + @override + String get settings_gpxExportAllContacts => 'Alle contactlocaties'; + + @override + String get settings_gpxExportShareText => + 'Kaartgegevens geëxporteerd uit meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open GPX kaartgegevens exporteren'; } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index 0832329..00b5c1e 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -2766,4 +2766,58 @@ class AppLocalizationsPl extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Kopiowanie ogłoszenia do schowka nie powiodło się.'; + + @override + String get settings_gpxExportRepeaters => + 'Eksportuj powtórki / serwer pokojowy do GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Eksportuje powtarzacze / roomserver z lokalizacją do pliku GPX.'; + + @override + String get settings_gpxExportContacts => 'Eksportuj towarzyszy do GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Eksportuje towarzyszy z lokalizacją do pliku GPX.'; + + @override + String get settings_gpxExportAll => 'Eksportuj wszystkie kontakty do GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Eksportuje wszystkie kontakty z lokalizacją do pliku GPX.'; + + @override + String get settings_gpxExportSuccess => 'Pomyślnie wyeksportowano plik GPX.'; + + @override + String get settings_gpxExportNoContacts => + 'Brak kontaktów do wyeksportowania.'; + + @override + String get settings_gpxExportNotAvailable => + 'Nie obsługiwane na Twoim urządzeniu/systemie operacyjnym'; + + @override + String get settings_gpxExportError => 'Wystąpił błąd podczas eksportowania.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Lokalizacje serwerów powtarzających i pomieszczeń'; + + @override + String get settings_gpxExportChat => 'Lokalizacje towarzyszy'; + + @override + String get settings_gpxExportAllContacts => 'Wszystkie lokalizacje kontaktów'; + + @override + String get settings_gpxExportShareText => + 'Dane mapy wyeksportowane z meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'Eksport danych mapy GPX meshcore-open'; } diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index eadea3b..e4877c8 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -2768,4 +2768,57 @@ class AppLocalizationsPt extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Cópia do anúncio para a Área de Transferência falhou.'; + + @override + String get settings_gpxExportRepeaters => + 'Exportar repetidores / servidor de sala para GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exporta repetidores / roomserver com localização para arquivo GPX.'; + + @override + String get settings_gpxExportContacts => 'Exportar companheiros para GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exporta companheiros com uma localização para um arquivo GPX.'; + + @override + String get settings_gpxExportAll => 'Exportar todos os contatos para GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exporta todos os contatos com uma localização para um arquivo GPX.'; + + @override + String get settings_gpxExportSuccess => 'Arquivo GPX exportado com sucesso.'; + + @override + String get settings_gpxExportNoContacts => 'Nenhum contato para exportar.'; + + @override + String get settings_gpxExportNotAvailable => + 'Não suportado no seu dispositivo/SO'; + + @override + String get settings_gpxExportError => 'Ocorreu um erro ao exportar.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Localizações do servidor de repetidor e sala'; + + @override + String get settings_gpxExportChat => 'Localizações de companheiros'; + + @override + String get settings_gpxExportAllContacts => 'Todos os locais de contatos'; + + @override + String get settings_gpxExportShareText => + 'Dados do mapa exportados do meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open exportação de dados de mapa GPX'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index ec0f1ba..4facd82 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -2773,4 +2773,57 @@ class AppLocalizationsRu extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Копирование рекламы в буфер обмена не удалось.'; + + @override + String get settings_gpxExportRepeaters => + 'Экспортировать рипитеры / сервер комнаты в GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Экспортирует ретрансляторы / сервер комнат с местоположением в файл GPX.'; + + @override + String get settings_gpxExportContacts => 'Экспортировать спутников в GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Экспортирует спутников с местоположением в файл GPX.'; + + @override + String get settings_gpxExportAll => 'Экспортировать все контакты в GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Экспортирует все контакты с местоположением в файл GPX.'; + + @override + String get settings_gpxExportSuccess => 'Успешно экспортирован файл GPX.'; + + @override + String get settings_gpxExportNoContacts => 'Нет контактов для экспорта.'; + + @override + String get settings_gpxExportNotAvailable => + 'Не поддерживается на вашем устройстве/ОС'; + + @override + String get settings_gpxExportError => 'Произошла ошибка при экспорте.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Местоположения повторителей и серверов комнат'; + + @override + String get settings_gpxExportChat => 'Местоположения спутников'; + + @override + String get settings_gpxExportAllContacts => 'Все местоположения контактов'; + + @override + String get settings_gpxExportShareText => + 'Данные карты экспортированы из meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open экспорт данных карты GPX'; } diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index 346047b..c555123 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -2752,4 +2752,57 @@ class AppLocalizationsSk extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Kopírovanie inzerátu do schránky zlyhalo.'; + + @override + String get settings_gpxExportRepeaters => + 'Exportovať repeater / server miestnosti do GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exportuje repeater / roomserver s lokalitou do súboru GPX.'; + + @override + String get settings_gpxExportContacts => 'Export sprievodcov do GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exportuje sprievodcov s umiestnením do súboru GPX.'; + + @override + String get settings_gpxExportAll => 'Exportovať všetky kontakty do GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exportuje všetky kontakty s lokalitou do súboru GPX.'; + + @override + String get settings_gpxExportSuccess => 'Úspešne exportovaný súbor GPX.'; + + @override + String get settings_gpxExportNoContacts => 'Žiadne kontakty na export.'; + + @override + String get settings_gpxExportNotAvailable => + 'Nie je podporované na vašom zariadení/operáciomnom systéme'; + + @override + String get settings_gpxExportError => 'Vyskytol sa chyba počas exportu.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Umiestnenia opakovačov a serverov miestností'; + + @override + String get settings_gpxExportChat => 'Lokácie sprievodcov'; + + @override + String get settings_gpxExportAllContacts => 'Všetky kontaktné lokality'; + + @override + String get settings_gpxExportShareText => + 'Mapové údaje exportované z meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open export dát GPX mapových údajov'; } diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index ed71122..7190a9c 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -2754,4 +2754,57 @@ class AppLocalizationsSl extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Kopiranje oglasa v odložišče je spodletelo.'; + + @override + String get settings_gpxExportRepeaters => + 'Izvoz ponoviteljev / strežnika sobe v GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Izvozi ponovljene oddajnike / strežnik sobe z lokacijo v datoteko GPX.'; + + @override + String get settings_gpxExportContacts => 'Izvoz spremljevalcev v GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Izvozi spremljevalce z lokacijo v datoteko GPX.'; + + @override + String get settings_gpxExportAll => 'Izvozi vse kontakte v GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Izvozi vse kontakte z lokacijo v datoteko GPX.'; + + @override + String get settings_gpxExportSuccess => 'Uspešno izvoz GPX datoteke.'; + + @override + String get settings_gpxExportNoContacts => 'Ni stikov za izvoz.'; + + @override + String get settings_gpxExportNotAvailable => + 'Ni podprto na vašem napravi/operacijskem sistemu'; + + @override + String get settings_gpxExportError => 'Pri izvozu je prišlo do napake.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Lokacije ponovljivca in strežnika sobe'; + + @override + String get settings_gpxExportChat => 'Lokacije spremljevalcev'; + + @override + String get settings_gpxExportAllContacts => 'Lokacije vseh stikov'; + + @override + String get settings_gpxExportShareText => + 'Podatki kart izvoženi iz meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open izvoz podatkov GPX karte'; } diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 97b849f..63f3ea2 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -2739,4 +2739,58 @@ class AppLocalizationsSv extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Kopiering av annons till Urklipp misslyckades.'; + + @override + String get settings_gpxExportRepeaters => + 'Exportera repeater / rumsservrar till GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Exporterar repeater / roomserver med plats till GPX-fil.'; + + @override + String get settings_gpxExportContacts => 'Exportera följeslagare till GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Exporterar följeslagare med en plats till GPX-fil.'; + + @override + String get settings_gpxExportAll => 'Exportera alla kontakter till GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Exporterar alla kontakter med en plats till GPX-fil.'; + + @override + String get settings_gpxExportSuccess => 'Har exporterat GPX-fil med framgång'; + + @override + String get settings_gpxExportNoContacts => 'Inga kontakter att exportera.'; + + @override + String get settings_gpxExportNotAvailable => + 'Stöds inte på din enhet/operativsystem'; + + @override + String get settings_gpxExportError => + 'Det uppstod ett fel när data exporterades.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Repeater- och rumsserverplatser'; + + @override + String get settings_gpxExportChat => 'Medhjälparplatser'; + + @override + String get settings_gpxExportAllContacts => 'Alla kontakters platser'; + + @override + String get settings_gpxExportShareText => + 'Kartdata exporterad från meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'meshcore-open export av GPX-kartdata'; } diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 899d540..838961a 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -2779,4 +2779,57 @@ class AppLocalizationsUk extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => 'Копіювання оголошення в буфер обміну завершилося невдало'; + + @override + String get settings_gpxExportRepeaters => + 'Експортувати ретранслятори / сервер кімнати до GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => + 'Експортує ретранслятори / сервер кімнати з місцезнаходженням у файл GPX.'; + + @override + String get settings_gpxExportContacts => 'Експортувати супутників до GPX'; + + @override + String get settings_gpxExportContactsSubtitle => + 'Експортує супутників з місцезнаходженням у файл GPX.'; + + @override + String get settings_gpxExportAll => 'Експортувати всі контакти до GPX'; + + @override + String get settings_gpxExportAllSubtitle => + 'Експортує всі контакти з місцем розташування у файл GPX.'; + + @override + String get settings_gpxExportSuccess => 'Успішно експортовано файл GPX.'; + + @override + String get settings_gpxExportNoContacts => 'Немає контактів для експорту.'; + + @override + String get settings_gpxExportNotAvailable => + 'Не підтримується на вашому пристрої/операційній системі'; + + @override + String get settings_gpxExportError => 'Сталася помилка під час експорту.'; + + @override + String get settings_gpxExportRepeatersRoom => + 'Місцезнаходження повторювача та сервера кімнати'; + + @override + String get settings_gpxExportChat => 'Місця супутників'; + + @override + String get settings_gpxExportAllContacts => 'Усі місця контактів'; + + @override + String get settings_gpxExportShareText => + 'Дані карти експортовані з meshcore-open'; + + @override + String get settings_gpxExportShareSubject => + 'експорт даних карти meshcore-open у форматі GPX'; } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 7746792..020f795 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -2621,4 +2621,49 @@ class AppLocalizationsZh extends AppLocalizations { @override String get contacts_contactAdvertCopyFailed => '将广告复制到剪贴板操作失败。'; + + @override + String get settings_gpxExportRepeaters => '导出重复器/房间服务器到GPX'; + + @override + String get settings_gpxExportRepeatersSubtitle => '导出带有位置的重复器/房间服务器到GPX文件。'; + + @override + String get settings_gpxExportContacts => '导出伴侣到GPX'; + + @override + String get settings_gpxExportContactsSubtitle => '导出带有位置的伙伴到GPX文件。'; + + @override + String get settings_gpxExportAll => '导出所有联系人到GPX'; + + @override + String get settings_gpxExportAllSubtitle => '导出所有带有位置的联系人到GPX文件。'; + + @override + String get settings_gpxExportSuccess => '成功导出GPX文件'; + + @override + String get settings_gpxExportNoContacts => '没有联系人可导出'; + + @override + String get settings_gpxExportNotAvailable => '您的设备/操作系统不支持'; + + @override + String get settings_gpxExportError => '导出时发生错误'; + + @override + String get settings_gpxExportRepeatersRoom => '重复器和房间服务器位置'; + + @override + String get settings_gpxExportChat => '伴侣位置'; + + @override + String get settings_gpxExportAllContacts => '所有联系人位置'; + + @override + String get settings_gpxExportShareText => '来自meshcore-open的导出地图数据'; + + @override + String get settings_gpxExportShareSubject => 'meshcore-open GPX 地图数据导出'; } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index e94deb3..4dbd506 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopyFailed": "Kopiëren van advertentie naar Clipboard is mislukt.", "contacts_ShareContact": "Kontakt naar Klembord kopiëren", "contacts_ShareContactZeroHop": "Contact delen via advertentie", - "contacts_zeroHopContactAdvertFailed": "Mislukt om contact te verzenden" + "contacts_zeroHopContactAdvertFailed": "Mislukt om contact te verzenden", + "settings_gpxExportRepeatersSubtitle": "Exporteert repeaters / roomserver met een locatie naar GPX-bestand.", + "settings_gpxExportRepeaters": "Exporteer repeaters / roomserver naar GPX", + "settings_gpxExportSuccess": "Succesvol GPX-bestand geëxporteerd.", + "settings_gpxExportNoContacts": "Geen contacten om te exporteren.", + "settings_gpxExportNotAvailable": "Niet ondersteund op uw apparaat/besturingssysteem", + "settings_gpxExportError": "Er was een fout bij het exporteren.", + "settings_gpxExportContacts": "Companions exporteren naar GPX", + "settings_gpxExportAll": "Alle contacten exporteren naar GPX", + "settings_gpxExportAllSubtitle": "Exporteert alle contacten met een locatie naar een GPX-bestand.", + "settings_gpxExportContactsSubtitle": "Exporteert metgezellen met een locatie naar een GPX-bestand.", + "settings_gpxExportRepeatersRoom": "Repeater- en kamer servers locaties", + "settings_gpxExportChat": "Locaties van metgezellen", + "settings_gpxExportAllContacts": "Alle contactlocaties", + "settings_gpxExportShareText": "Kaartgegevens geëxporteerd uit meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open GPX kaartgegevens exporteren" } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 44552c3..5327215 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopyFailed": "Kopiowanie ogłoszenia do schowka nie powiodło się.", "contacts_ShareContactZeroHop": "Udostępnij kontakt przez ogłoszenie", "contacts_ShareContact": "Kopiuj kontakt do schowka", - "contacts_zeroHopContactAdvertFailed": "Nie udało się wysłać kontaktu." + "contacts_zeroHopContactAdvertFailed": "Nie udało się wysłać kontaktu.", + "settings_gpxExportContacts": "Eksportuj towarzyszy do GPX", + "settings_gpxExportRepeaters": "Eksportuj powtórki / serwer pokojowy do GPX", + "settings_gpxExportRepeatersSubtitle": "Eksportuje powtarzacze / roomserver z lokalizacją do pliku GPX.", + "settings_gpxExportSuccess": "Pomyślnie wyeksportowano plik GPX.", + "settings_gpxExportNotAvailable": "Nie obsługiwane na Twoim urządzeniu/systemie operacyjnym", + "settings_gpxExportError": "Wystąpił błąd podczas eksportowania.", + "settings_gpxExportRepeatersRoom": "Lokalizacje serwerów powtarzających i pomieszczeń", + "settings_gpxExportContactsSubtitle": "Eksportuje towarzyszy z lokalizacją do pliku GPX.", + "settings_gpxExportAll": "Eksportuj wszystkie kontakty do GPX", + "settings_gpxExportAllSubtitle": "Eksportuje wszystkie kontakty z lokalizacją do pliku GPX.", + "settings_gpxExportAllContacts": "Wszystkie lokalizacje kontaktów", + "settings_gpxExportNoContacts": "Brak kontaktów do wyeksportowania.", + "settings_gpxExportChat": "Lokalizacje towarzyszy", + "settings_gpxExportShareText": "Dane mapy wyeksportowane z meshcore-open", + "settings_gpxExportShareSubject": "Eksport danych mapy GPX meshcore-open" } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 56a7f2b..7da9019 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1568,5 +1568,20 @@ "contacts_floodAdvert": "Anúncio de Inundação", "contacts_contactAdvertCopyFailed": "Cópia do anúncio para a Área de Transferência falhou.", "contacts_ShareContactZeroHop": "Compartilhar contato por anúncio", - "contacts_zeroHopContactAdvertFailed": "Falha ao enviar contato." + "contacts_zeroHopContactAdvertFailed": "Falha ao enviar contato.", + "settings_gpxExportRepeaters": "Exportar repetidores / servidor de sala para GPX", + "settings_gpxExportRepeatersSubtitle": "Exporta repetidores / roomserver com localização para arquivo GPX.", + "settings_gpxExportSuccess": "Arquivo GPX exportado com sucesso.", + "settings_gpxExportAllSubtitle": "Exporta todos os contatos com uma localização para um arquivo GPX.", + "settings_gpxExportNotAvailable": "Não suportado no seu dispositivo/SO", + "settings_gpxExportError": "Ocorreu um erro ao exportar.", + "settings_gpxExportAll": "Exportar todos os contatos para GPX", + "settings_gpxExportContacts": "Exportar companheiros para GPX", + "settings_gpxExportContactsSubtitle": "Exporta companheiros com uma localização para um arquivo GPX.", + "settings_gpxExportRepeatersRoom": "Localizações do servidor de repetidor e sala", + "settings_gpxExportChat": "Localizações de companheiros", + "settings_gpxExportNoContacts": "Nenhum contato para exportar.", + "settings_gpxExportAllContacts": "Todos os locais de contatos", + "settings_gpxExportShareText": "Dados do mapa exportados do meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open exportação de dados de mapa GPX" } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 0bca5ef..e0f4402 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -808,5 +808,20 @@ "contacts_contactAdvertCopyFailed": "Копирование рекламы в буфер обмена не удалось.", "contacts_addContactFromClipboard": "Добавить контакт из буфера обмена", "contacts_ShareContactZeroHop": "Поделиться контактом по объявлению", - "contacts_zeroHopContactAdvertSent": "Отправлено сообщение по объявлению." + "contacts_zeroHopContactAdvertSent": "Отправлено сообщение по объявлению.", + "settings_gpxExportRepeaters": "Экспортировать рипитеры / сервер комнаты в GPX", + "settings_gpxExportRepeatersSubtitle": "Экспортирует ретрансляторы / сервер комнат с местоположением в файл GPX.", + "settings_gpxExportContacts": "Экспортировать спутников в GPX", + "settings_gpxExportNotAvailable": "Не поддерживается на вашем устройстве/ОС", + "settings_gpxExportError": "Произошла ошибка при экспорте.", + "settings_gpxExportRepeatersRoom": "Местоположения повторителей и серверов комнат", + "settings_gpxExportChat": "Местоположения спутников", + "settings_gpxExportContactsSubtitle": "Экспортирует спутников с местоположением в файл GPX.", + "settings_gpxExportAll": "Экспортировать все контакты в GPX", + "settings_gpxExportAllSubtitle": "Экспортирует все контакты с местоположением в файл GPX.", + "settings_gpxExportAllContacts": "Все местоположения контактов", + "settings_gpxExportSuccess": "Успешно экспортирован файл GPX.", + "settings_gpxExportNoContacts": "Нет контактов для экспорта.", + "settings_gpxExportShareText": "Данные карты экспортированы из meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open экспорт данных карты GPX" } diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index d61cca6..e72888e 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopyFailed": "Kopírovanie inzerátu do schránky zlyhalo.", "contacts_zeroHopContactAdvertFailed": "Zlyhalo odoslanie kontaktu.", "contacts_ShareContactZeroHop": "Zdieľať kontakt cez inzerát", - "contacts_ShareContact": "Kopírovať kontakt do schránky" + "contacts_ShareContact": "Kopírovať kontakt do schránky", + "settings_gpxExportRepeatersSubtitle": "Exportuje repeater / roomserver s lokalitou do súboru GPX.", + "settings_gpxExportContacts": "Export sprievodcov do GPX", + "settings_gpxExportSuccess": "Úspešne exportovaný súbor GPX.", + "settings_gpxExportNoContacts": "Žiadne kontakty na export.", + "settings_gpxExportNotAvailable": "Nie je podporované na vašom zariadení/operáciomnom systéme", + "settings_gpxExportRepeatersRoom": "Umiestnenia opakovačov a serverov miestností", + "settings_gpxExportError": "Vyskytol sa chyba počas exportu.", + "settings_gpxExportAllSubtitle": "Exportuje všetky kontakty s lokalitou do súboru GPX.", + "settings_gpxExportContactsSubtitle": "Exportuje sprievodcov s umiestnením do súboru GPX.", + "settings_gpxExportRepeaters": "Exportovať repeater / server miestnosti do GPX", + "settings_gpxExportAll": "Exportovať všetky kontakty do GPX", + "settings_gpxExportAllContacts": "Všetky kontaktné lokality", + "settings_gpxExportChat": "Lokácie sprievodcov", + "settings_gpxExportShareText": "Mapové údaje exportované z meshcore-open", + "settings_gpxExportShareSubject": "meshcore-open export dát GPX mapových údajov" } diff --git a/lib/l10n/app_sl.arb b/lib/l10n/app_sl.arb index cbc4e3f..97cd1f8 100644 --- a/lib/l10n/app_sl.arb +++ b/lib/l10n/app_sl.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopied": "Oglas je bil kopiran v odložišče.", "contacts_contactAdvertCopyFailed": "Kopiranje oglasa v odložišče je spodletelo.", "contacts_ShareContactZeroHop": "Deliti kontakt prek oglasa", - "contacts_ShareContact": "Kopiraj stik v Odložišče" + "contacts_ShareContact": "Kopiraj stik v Odložišče", + "settings_gpxExportAll": "Izvozi vse kontakte v GPX", + "settings_gpxExportContacts": "Izvoz spremljevalcev v GPX", + "settings_gpxExportRepeatersSubtitle": "Izvozi ponovljene oddajnike / strežnik sobe z lokacijo v datoteko GPX.", + "settings_gpxExportRepeaters": "Izvoz ponoviteljev / strežnika sobe v GPX", + "settings_gpxExportError": "Pri izvozu je prišlo do napake.", + "settings_gpxExportRepeatersRoom": "Lokacije ponovljivca in strežnika sobe", + "settings_gpxExportChat": "Lokacije spremljevalcev", + "settings_gpxExportAllContacts": "Lokacije vseh stikov", + "settings_gpxExportContactsSubtitle": "Izvozi spremljevalce z lokacijo v datoteko GPX.", + "settings_gpxExportAllSubtitle": "Izvozi vse kontakte z lokacijo v datoteko GPX.", + "settings_gpxExportSuccess": "Uspešno izvoz GPX datoteke.", + "settings_gpxExportShareText": "Podatki kart izvoženi iz meshcore-open", + "settings_gpxExportNoContacts": "Ni stikov za izvoz.", + "settings_gpxExportNotAvailable": "Ni podprto na vašem napravi/operacijskem sistemu", + "settings_gpxExportShareSubject": "meshcore-open izvoz podatkov GPX karte" } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index 05f77cb..03844f3 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopyFailed": "Kopiering av annons till Urklipp misslyckades.", "contacts_ShareContact": "Kopiera kontakt till Urklipp", "contacts_zeroHopContactAdvertFailed": "Misslyckades med att skicka kontakt.", - "contacts_ShareContactZeroHop": "Dela kontakt via annons" + "contacts_ShareContactZeroHop": "Dela kontakt via annons", + "settings_gpxExportAll": "Exportera alla kontakter till GPX", + "settings_gpxExportRepeatersSubtitle": "Exporterar repeater / roomserver med plats till GPX-fil.", + "settings_gpxExportSuccess": "Har exporterat GPX-fil med framgång", + "settings_gpxExportNoContacts": "Inga kontakter att exportera.", + "settings_gpxExportNotAvailable": "Stöds inte på din enhet/operativsystem", + "settings_gpxExportRepeatersRoom": "Repeater- och rumsserverplatser", + "settings_gpxExportRepeaters": "Exportera repeater / rumsservrar till GPX", + "settings_gpxExportAllSubtitle": "Exporterar alla kontakter med en plats till GPX-fil.", + "settings_gpxExportContacts": "Exportera följeslagare till GPX", + "settings_gpxExportContactsSubtitle": "Exporterar följeslagare med en plats till GPX-fil.", + "settings_gpxExportChat": "Medhjälparplatser", + "settings_gpxExportError": "Det uppstod ett fel när data exporterades.", + "settings_gpxExportAllContacts": "Alla kontakters platser", + "settings_gpxExportShareSubject": "meshcore-open export av GPX-kartdata", + "settings_gpxExportShareText": "Kartdata exporterad från meshcore-open" } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 3362d40..796be1e 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -1568,5 +1568,20 @@ "contacts_contactAdvertCopyFailed": "Копіювання оголошення в буфер обміну завершилося невдало", "contacts_zeroHopContactAdvertSent": "Відправлено контакт за оголошенням", "contacts_addContactFromClipboard": "Додати контакт з буфера обміну", - "contacts_ShareContactZeroHop": "Поділитися контактом за оголошенням" + "contacts_ShareContactZeroHop": "Поділитися контактом за оголошенням", + "settings_gpxExportRepeaters": "Експортувати ретранслятори / сервер кімнати до GPX", + "settings_gpxExportRepeatersSubtitle": "Експортує ретранслятори / сервер кімнати з місцезнаходженням у файл GPX.", + "settings_gpxExportSuccess": "Успішно експортовано файл GPX.", + "settings_gpxExportNoContacts": "Немає контактів для експорту.", + "settings_gpxExportNotAvailable": "Не підтримується на вашому пристрої/операційній системі", + "settings_gpxExportError": "Сталася помилка під час експорту.", + "settings_gpxExportAllSubtitle": "Експортує всі контакти з місцем розташування у файл GPX.", + "settings_gpxExportAll": "Експортувати всі контакти до GPX", + "settings_gpxExportContactsSubtitle": "Експортує супутників з місцезнаходженням у файл GPX.", + "settings_gpxExportContacts": "Експортувати супутників до GPX", + "settings_gpxExportRepeatersRoom": "Місцезнаходження повторювача та сервера кімнати", + "settings_gpxExportChat": "Місця супутників", + "settings_gpxExportShareText": "Дані карти експортовані з meshcore-open", + "settings_gpxExportAllContacts": "Усі місця контактів", + "settings_gpxExportShareSubject": "експорт даних карти meshcore-open у форматі GPX" } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index c941461..a71541b 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1568,5 +1568,20 @@ "contacts_zeroHopContactAdvertSent": "通过广告获取联系方式。", "contacts_zeroHopContactAdvertFailed": "发送联系方式失败。", "contacts_contactAdvertCopied": "广告内容已复制到剪贴板。", - "contacts_contactAdvertCopyFailed": "将广告复制到剪贴板操作失败。" + "contacts_contactAdvertCopyFailed": "将广告复制到剪贴板操作失败。", + "settings_gpxExportRepeaters": "导出重复器/房间服务器到GPX", + "settings_gpxExportRepeatersSubtitle": "导出带有位置的重复器/房间服务器到GPX文件。", + "settings_gpxExportContactsSubtitle": "导出带有位置的伙伴到GPX文件。", + "settings_gpxExportNotAvailable": "您的设备/操作系统不支持", + "settings_gpxExportSuccess": "成功导出GPX文件", + "settings_gpxExportError": "导出时发生错误", + "settings_gpxExportRepeatersRoom": "重复器和房间服务器位置", + "settings_gpxExportChat": "伴侣位置", + "settings_gpxExportAll": "导出所有联系人到GPX", + "settings_gpxExportContacts": "导出伴侣到GPX", + "settings_gpxExportAllSubtitle": "导出所有带有位置的联系人到GPX文件。", + "settings_gpxExportAllContacts": "所有联系人位置", + "settings_gpxExportNoContacts": "没有联系人可导出", + "settings_gpxExportShareText": "来自meshcore-open的导出地图数据", + "settings_gpxExportShareSubject": "meshcore-open GPX 地图数据导出" } From 2db30ace6a1e3f7937fd562697ca5961810dddcd Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 8 Feb 2026 12:26:49 -0800 Subject: [PATCH 6/6] Integrate SharePlus plugin for enhanced sharing functionality across platforms --- lib/utils/gpx_export.dart | 60 ++++++++----------- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 50 +++++++++++++++- .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 5 files changed, 80 insertions(+), 36 deletions(-) diff --git a/lib/utils/gpx_export.dart b/lib/utils/gpx_export.dart index 92494c9..595479c 100644 --- a/lib/utils/gpx_export.dart +++ b/lib/utils/gpx_export.dart @@ -54,50 +54,50 @@ class GpxExport { } void addRepeaters() { - final contacts = _connector.contacts; - final repeaters = contacts + final contacts = _connector.contacts .where((c) => c.type == advTypeRepeater || c.type == advTypeRoom) .toList(); - for (var repeater in repeaters) { - if (repeater.latitude == null || repeater.longitude == null) { + for (var contact in contacts) { + if (contact.latitude == null || contact.longitude == null) { continue; } _addContact( - repeater.name, - repeater.latitude ?? 0.0, - repeater.longitude ?? 0.0, - "Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}", + contact.name, + contact.latitude!, + contact.longitude!, + "Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}", ); } } void addContacts() { - final contacts = _connector.contacts; - final repeaters = contacts.where((c) => c.type == advTypeChat).toList(); - for (var repeater in repeaters) { - if (repeater.latitude == null || repeater.longitude == null) { + final contacts = _connector.contacts + .where((c) => c.type == advTypeChat) + .toList(); + for (var contact in contacts) { + if (contact.latitude == null || contact.longitude == null) { continue; } _addContact( - repeater.name, - repeater.latitude ?? 0.0, - repeater.longitude ?? 0.0, - "Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}", + contact.name, + contact.latitude!, + contact.longitude!, + "Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}", ); } } void addAll() { final contacts = _connector.contacts; - for (var repeater in contacts.toList()) { - if (repeater.latitude == null || repeater.longitude == null) { + for (var contact in contacts.toList()) { + if (contact.latitude == null || contact.longitude == null) { continue; } _addContact( - repeater.name, - repeater.latitude ?? 0.0, - repeater.longitude ?? 0.0, - "Type: ${repeater.typeLabel}\nPublic Key: ${repeater.publicKeyHex}", + contact.name, + contact.latitude ?? 0.0, + contact.longitude ?? 0.0, + "Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}", ); } } @@ -149,23 +149,17 @@ class GpxExport { .split('T') .join('_'); - // ignore: unnecessary_string_escapes final path = '${dir.path}/$filename$timestamp.gpx'; final file = File(path); await file.writeAsString(xml); - // 3. Modern share call (2025+ style) final result = await SharePlus.instance.share( - ShareParams( - text: shareText, - subject: subject, - files: [XFile(path)], - // Optional: sharePositionOrigin: ... (if you want iPad popover positioning) - ), + ShareParams(text: shareText, subject: subject, files: [XFile(path)]), ); - // 4. Handle result + await file.delete(); + switch (result.status) { case ShareResultStatus.success: debugPrint('Share successful – user completed the action.'); @@ -177,12 +171,8 @@ class GpxExport { debugPrint('Sharing is not available on this platform / context.'); return gpxExportNotAvailable; } - - // Optional cleanup (uncomment if you don't want to keep the file) - // await file.delete(); } catch (e, stack) { debugPrint('Export or share failed: $e\n$stack'); - // → here you could show a SnackBar / AlertDialog in real UI code } return gpxExportFailed; } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index b4a41dd..d2ea57e 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import flutter_blue_plus_darwin import flutter_local_notifications import mobile_scanner import package_info_plus +import share_plus import shared_preferences_foundation import sqflite_darwin import url_launcher_macos @@ -19,6 +20,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) + SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 1e275d4..fc11656 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -121,6 +121,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" crypto: dependency: "direct main" description: @@ -341,6 +349,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + gpx: + dependency: "direct main" + description: + name: gpx + sha256: f5b12b86402c639079243600ee2b3afd85cd08d26117fc8885cf48efce471d8e + url: "https://pub.dev" + source: hosted + version: "2.3.0" hooks: dependency: transitive description: @@ -501,6 +517,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" mobile_scanner: dependency: "direct main" description: @@ -566,7 +590,7 @@ packages: source: hosted version: "1.9.1" path_provider: - dependency: transitive + dependency: "direct main" description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" @@ -701,6 +725,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" + quiver: + dependency: transitive + description: + name: quiver + sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 + url: "https://pub.dev" + source: hosted + version: "3.2.2" rxdart: dependency: transitive description: @@ -709,6 +741,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.28.0" + share_plus: + dependency: "direct main" + description: + name: share_plus + sha256: "14c8860d4de93d3a7e53af51bff479598c4e999605290756bbbe45cf65b37840" + url: "https://pub.dev" + source: hosted + version: "12.0.1" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a" + url: "https://pub.dev" + source: hosted + version: "6.1.0" shared_preferences: dependency: "direct main" description: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index eeb548f..cd4fc19 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,11 +7,14 @@ #include "generated_plugin_registrant.h" #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { FlutterBluePlusPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterBluePlusPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 68825d8..571addb 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST flutter_blue_plus_winrt + share_plus url_launcher_windows )