mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
feat: Add functionality to save SAR messages as templates with corresponding localization
This commit is contained in:
@@ -1830,6 +1830,21 @@
|
|||||||
"description": "Success message when text is copied"
|
"description": "Success message when text is copied"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"saveAsTemplate": "Save as Template",
|
||||||
|
"@saveAsTemplate": {
|
||||||
|
"description": "Option to save SAR message as a reusable template"
|
||||||
|
},
|
||||||
|
|
||||||
|
"templateSaved": "Template saved successfully",
|
||||||
|
"@templateSaved": {
|
||||||
|
"description": "Success message when SAR template is saved"
|
||||||
|
},
|
||||||
|
|
||||||
|
"templateAlreadyExists": "Template with this emoji already exists",
|
||||||
|
"@templateAlreadyExists": {
|
||||||
|
"description": "Error message when trying to save duplicate template"
|
||||||
|
},
|
||||||
|
|
||||||
"deleteMessage": "Delete message",
|
"deleteMessage": "Delete message",
|
||||||
"@deleteMessage": {
|
"@deleteMessage": {
|
||||||
"description": "Dialog title for deleting a message"
|
"description": "Dialog title for deleting a message"
|
||||||
|
|||||||
@@ -636,6 +636,9 @@
|
|||||||
"messageDeleted": "Poruka izbrisana",
|
"messageDeleted": "Poruka izbrisana",
|
||||||
"copyText": "Kopiraj tekst",
|
"copyText": "Kopiraj tekst",
|
||||||
"textCopiedToClipboard": "Tekst kopiran u međuspremnik",
|
"textCopiedToClipboard": "Tekst kopiran u međuspremnik",
|
||||||
|
"saveAsTemplate": "Spremi kao predložak",
|
||||||
|
"templateSaved": "Predložak uspješno spremljen",
|
||||||
|
"templateAlreadyExists": "Predložak s ovim emojijem već postoji",
|
||||||
"deleteMessage": "Izbriši poruku",
|
"deleteMessage": "Izbriši poruku",
|
||||||
"deleteMessageConfirmation": "Jeste li sigurni da želite izbrisati ovu poruku?",
|
"deleteMessageConfirmation": "Jeste li sigurni da želite izbrisati ovu poruku?",
|
||||||
"shareLocation": "Podijeli lokaciju",
|
"shareLocation": "Podijeli lokaciju",
|
||||||
|
|||||||
@@ -1954,6 +1954,24 @@ abstract class AppLocalizations {
|
|||||||
/// **'Copy text'**
|
/// **'Copy text'**
|
||||||
String get copyText;
|
String get copyText;
|
||||||
|
|
||||||
|
/// Option to save SAR message as a reusable template
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Save as Template'**
|
||||||
|
String get saveAsTemplate;
|
||||||
|
|
||||||
|
/// Success message when SAR template is saved
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Template saved successfully'**
|
||||||
|
String get templateSaved;
|
||||||
|
|
||||||
|
/// Error message when trying to save duplicate template
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Template with this emoji already exists'**
|
||||||
|
String get templateAlreadyExists;
|
||||||
|
|
||||||
/// Dialog title for deleting a message
|
/// Dialog title for deleting a message
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -1078,6 +1078,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get copyText => 'Text kopieren';
|
String get copyText => 'Text kopieren';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveAsTemplate => 'Save as Template';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateSaved => 'Template saved successfully';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateAlreadyExists => 'Template with this emoji already exists';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteMessage => 'Nachricht löschen';
|
String get deleteMessage => 'Nachricht löschen';
|
||||||
|
|
||||||
|
|||||||
@@ -1068,6 +1068,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get copyText => 'Copy text';
|
String get copyText => 'Copy text';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveAsTemplate => 'Save as Template';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateSaved => 'Template saved successfully';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateAlreadyExists => 'Template with this emoji already exists';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteMessage => 'Delete message';
|
String get deleteMessage => 'Delete message';
|
||||||
|
|
||||||
|
|||||||
@@ -1074,6 +1074,15 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get copyText => 'Copiar texto';
|
String get copyText => 'Copiar texto';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveAsTemplate => 'Save as Template';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateSaved => 'Template saved successfully';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateAlreadyExists => 'Template with this emoji already exists';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteMessage => 'Eliminar mensaje';
|
String get deleteMessage => 'Eliminar mensaje';
|
||||||
|
|
||||||
|
|||||||
@@ -1079,6 +1079,15 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get copyText => 'Copier le texte';
|
String get copyText => 'Copier le texte';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveAsTemplate => 'Save as Template';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateSaved => 'Template saved successfully';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateAlreadyExists => 'Template with this emoji already exists';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteMessage => 'Supprimer le message';
|
String get deleteMessage => 'Supprimer le message';
|
||||||
|
|
||||||
|
|||||||
@@ -1070,6 +1070,15 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get copyText => 'Kopiraj tekst';
|
String get copyText => 'Kopiraj tekst';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveAsTemplate => 'Spremi kao predložak';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateSaved => 'Predložak uspješno spremljen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateAlreadyExists => 'Predložak s ovim emojijem već postoji';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteMessage => 'Izbriši poruku';
|
String get deleteMessage => 'Izbriši poruku';
|
||||||
|
|
||||||
|
|||||||
@@ -1076,6 +1076,15 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get copyText => 'Copia testo';
|
String get copyText => 'Copia testo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveAsTemplate => 'Save as Template';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateSaved => 'Template saved successfully';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateAlreadyExists => 'Template with this emoji already exists';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteMessage => 'Elimina messaggio';
|
String get deleteMessage => 'Elimina messaggio';
|
||||||
|
|
||||||
|
|||||||
@@ -1070,6 +1070,15 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get copyText => 'Kopiraj besedilo';
|
String get copyText => 'Kopiraj besedilo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveAsTemplate => 'Shrani kot predlogo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateSaved => 'Predloga uspešno shranjena';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get templateAlreadyExists => 'Predloga s tem emojijem že obstaja';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteMessage => 'Izbriši sporočilo';
|
String get deleteMessage => 'Izbriši sporočilo';
|
||||||
|
|
||||||
|
|||||||
@@ -636,6 +636,9 @@
|
|||||||
"messageDeleted": "Sporočilo izbrisano",
|
"messageDeleted": "Sporočilo izbrisano",
|
||||||
"copyText": "Kopiraj besedilo",
|
"copyText": "Kopiraj besedilo",
|
||||||
"textCopiedToClipboard": "Besedilo kopirano v odložišče",
|
"textCopiedToClipboard": "Besedilo kopirano v odložišče",
|
||||||
|
"saveAsTemplate": "Shrani kot predlogo",
|
||||||
|
"templateSaved": "Predloga uspešno shranjena",
|
||||||
|
"templateAlreadyExists": "Predloga s tem emojijem že obstaja",
|
||||||
"deleteMessage": "Izbriši sporočilo",
|
"deleteMessage": "Izbriši sporočilo",
|
||||||
"deleteMessageConfirmation": "Ali ste prepričani, da želite izbrisati to sporočilo?",
|
"deleteMessageConfirmation": "Ali ste prepričani, da želite izbrisati to sporočilo?",
|
||||||
"shareLocation": "Deli lokacijo",
|
"shareLocation": "Deli lokacijo",
|
||||||
|
|||||||
@@ -11,13 +11,16 @@ import '../providers/drawing_provider.dart';
|
|||||||
import '../models/message.dart';
|
import '../models/message.dart';
|
||||||
import '../models/contact.dart';
|
import '../models/contact.dart';
|
||||||
import '../models/sar_marker.dart';
|
import '../models/sar_marker.dart';
|
||||||
|
import '../models/sar_template.dart';
|
||||||
import '../models/map_drawing.dart';
|
import '../models/map_drawing.dart';
|
||||||
import '../widgets/messages/sar_update_sheet.dart';
|
import '../widgets/messages/sar_update_sheet.dart';
|
||||||
import '../widgets/messages/recipient_selector_sheet.dart';
|
import '../widgets/messages/recipient_selector_sheet.dart';
|
||||||
import '../widgets/contacts/direct_message_sheet.dart';
|
import '../widgets/contacts/direct_message_sheet.dart';
|
||||||
import '../widgets/drawing_minimap_preview.dart';
|
import '../widgets/drawing_minimap_preview.dart';
|
||||||
import '../services/message_destination_preferences.dart';
|
import '../services/message_destination_preferences.dart';
|
||||||
|
import '../services/sar_template_service.dart';
|
||||||
import '../utils/toast_logger.dart';
|
import '../utils/toast_logger.dart';
|
||||||
|
import '../utils/sar_message_parser.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import '../utils/message_extensions.dart';
|
import '../utils/message_extensions.dart';
|
||||||
|
|
||||||
@@ -966,6 +969,35 @@ class _MessageBubble extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
// Save as Template option (only for SAR markers without existing template)
|
||||||
|
if (message.isSarMarker)
|
||||||
|
Builder(
|
||||||
|
builder: (context) {
|
||||||
|
// Extract emoji from SAR message
|
||||||
|
final sarInfo = SarMessageParser.parse(message.text);
|
||||||
|
if (sarInfo == null || sarInfo.emoji.isEmpty) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if template with this emoji already exists
|
||||||
|
final sarTemplateService = SarTemplateService();
|
||||||
|
final templateExists = sarTemplateService.templates
|
||||||
|
.any((t) => t.emoji == sarInfo.emoji);
|
||||||
|
|
||||||
|
if (templateExists) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(Icons.bookmark_add),
|
||||||
|
title: Text(AppLocalizations.of(context)!.saveAsTemplate),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
_saveAsTemplate(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
// Share location option (only for SAR markers with GPS coordinates)
|
// Share location option (only for SAR markers with GPS coordinates)
|
||||||
if (message.isSarMarker && message.sarGpsCoordinates != null)
|
if (message.isSarMarker && message.sarGpsCoordinates != null)
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -1215,6 +1247,48 @@ class _MessageBubble extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _saveAsTemplate(BuildContext context) async {
|
||||||
|
if (!message.isSarMarker) {
|
||||||
|
ToastLogger.error(context, 'Not a SAR marker');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Parse the SAR message to create a template
|
||||||
|
final template = SarTemplate.fromSarMessage(message.text);
|
||||||
|
|
||||||
|
// Get SAR template service
|
||||||
|
final sarTemplateService = SarTemplateService();
|
||||||
|
|
||||||
|
// Check if template with this emoji already exists
|
||||||
|
final existingTemplates = sarTemplateService.templates
|
||||||
|
.where((t) => t.emoji == template.emoji)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (existingTemplates.isNotEmpty) {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
ToastLogger.warning(
|
||||||
|
context,
|
||||||
|
AppLocalizations.of(context)!.templateAlreadyExists,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the template
|
||||||
|
await sarTemplateService.addTemplate(template);
|
||||||
|
|
||||||
|
if (!context.mounted) return;
|
||||||
|
ToastLogger.success(
|
||||||
|
context,
|
||||||
|
AppLocalizations.of(context)!.templateSaved,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Error saving template: $e');
|
||||||
|
if (!context.mounted) return;
|
||||||
|
ToastLogger.error(context, 'Failed to save template: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isSarMarker = message.isSarMarker;
|
final isSarMarker = message.isSarMarker;
|
||||||
|
|||||||
Reference in New Issue
Block a user