mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
Refactor SAR marker handling and add template management
- Updated CompassSarList and DetailedCompassDialog to use marker.displayName instead of marker.type.displayName. - Enhanced DrawingLayer and DrawingMarkersLayer to support simple mode for drawing visibility and interaction. - Added toggle switches in DrawingToolbar for showing/hiding received drawings and SAR markers. - Modified MapMarkers to utilize custom emojis and display names for markers. - Introduced RecipientSelectorSheet for selecting message recipients with search functionality. - Refactored SarUpdateSheet to use SAR templates instead of marker types, allowing for emoji and name customization. - Created SarTemplateEditDialog for adding and editing SAR templates with color selection and preview.
This commit is contained in:
@@ -20,6 +20,7 @@ class NotificationService {
|
||||
|
||||
// Notification IDs
|
||||
static const int _sarNotificationId = 1000;
|
||||
static const int _messageNotificationId = 2000;
|
||||
|
||||
// Notification channels
|
||||
static const String _urgentChannelId = 'sar_urgent';
|
||||
@@ -27,6 +28,11 @@ class NotificationService {
|
||||
static const String _urgentChannelDescription =
|
||||
'Critical alerts for SAR markers (found persons, fires, staging areas)';
|
||||
|
||||
static const String _messagesChannelId = 'messages';
|
||||
static const String _messagesChannelName = 'Messages';
|
||||
static const String _messagesChannelDescription =
|
||||
'Notifications for incoming messages from contacts and channels';
|
||||
|
||||
/// Initialize notification service
|
||||
Future<void> initialize() async {
|
||||
if (_isInitialized) return;
|
||||
@@ -125,8 +131,20 @@ class NotificationService {
|
||||
sound: RawResourceAndroidNotificationSound('notification'),
|
||||
);
|
||||
|
||||
// Messages channel with high priority
|
||||
const messagesChannel = AndroidNotificationChannel(
|
||||
_messagesChannelId,
|
||||
_messagesChannelName,
|
||||
description: _messagesChannelDescription,
|
||||
importance: Importance.high,
|
||||
playSound: true,
|
||||
enableVibration: true,
|
||||
showBadge: true,
|
||||
);
|
||||
|
||||
await androidPlugin.createNotificationChannel(urgentChannel);
|
||||
debugPrint('✅ [NotificationService] Created urgent notification channel');
|
||||
await androidPlugin.createNotificationChannel(messagesChannel);
|
||||
debugPrint('✅ [NotificationService] Created notification channels');
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ [NotificationService] Error creating channels: $e');
|
||||
}
|
||||
@@ -303,6 +321,93 @@ class NotificationService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Show notification for regular message (contact or channel)
|
||||
Future<void> showMessageNotification({
|
||||
required String senderName,
|
||||
required String messageText,
|
||||
required bool isChannelMessage,
|
||||
String? channelName,
|
||||
AppLocalizations? localizations,
|
||||
}) async {
|
||||
if (!_isInitialized) {
|
||||
debugPrint('⚠️ [NotificationService] Not initialized, skipping notification');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_permissionGranted) {
|
||||
debugPrint('⚠️ [NotificationService] Permission not granted, skipping notification');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Generate unique notification ID based on timestamp
|
||||
final notificationId = _messageNotificationId + (DateTime.now().millisecondsSinceEpoch % 1000);
|
||||
|
||||
// Build notification title and body
|
||||
final title = isChannelMessage
|
||||
? (localizations != null
|
||||
? '${localizations.channel}: ${channelName ?? "Public"}'
|
||||
: 'Channel: ${channelName ?? "Public"}')
|
||||
: (localizations != null
|
||||
? '${localizations.newMessage} ${localizations.from} $senderName'
|
||||
: 'New message from $senderName');
|
||||
|
||||
final body = messageText.length > 200
|
||||
? '${messageText.substring(0, 200)}...'
|
||||
: messageText;
|
||||
|
||||
// Android notification details
|
||||
final androidDetails = AndroidNotificationDetails(
|
||||
_messagesChannelId,
|
||||
_messagesChannelName,
|
||||
channelDescription: _messagesChannelDescription,
|
||||
importance: Importance.high,
|
||||
priority: Priority.high,
|
||||
ticker: title,
|
||||
playSound: true,
|
||||
enableVibration: true,
|
||||
showWhen: true,
|
||||
when: DateTime.now().millisecondsSinceEpoch,
|
||||
styleInformation: BigTextStyleInformation(
|
||||
body,
|
||||
contentTitle: title,
|
||||
summaryText: senderName,
|
||||
),
|
||||
);
|
||||
|
||||
// iOS notification details
|
||||
final darwinDetails = DarwinNotificationDetails(
|
||||
presentAlert: true,
|
||||
presentBadge: true,
|
||||
presentSound: true,
|
||||
sound: 'default',
|
||||
threadIdentifier: isChannelMessage ? 'channel_messages' : 'direct_messages',
|
||||
subtitle: senderName,
|
||||
);
|
||||
|
||||
// Combined notification details
|
||||
final notificationDetails = NotificationDetails(
|
||||
android: androidDetails,
|
||||
iOS: darwinDetails,
|
||||
);
|
||||
|
||||
// Show notification
|
||||
await _notificationsPlugin.show(
|
||||
notificationId,
|
||||
title,
|
||||
body,
|
||||
notificationDetails,
|
||||
payload: 'message:${isChannelMessage ? "channel" : "contact"}',
|
||||
);
|
||||
|
||||
debugPrint('✅ [NotificationService] Showed message notification');
|
||||
debugPrint(' Sender: $senderName');
|
||||
debugPrint(' Type: ${isChannelMessage ? "Channel" : "Direct"}');
|
||||
} catch (e) {
|
||||
debugPrint('❌ [NotificationService] Error showing message notification: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Cancel all notifications
|
||||
Future<void> cancelAll() async {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user