mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
feat: Enhance messaging and SAR marker functionalities
- Integrated SAR marker sending feature in MessagesTab with a dedicated dialog for user input. - Updated message sending logic to default to the first available room if no contact is selected. - Improved user feedback with SnackBars for connection issues and successful marker sends. - Refactored contact selection to remove unused code and streamline the process. - Added location fetching capabilities using Geolocator for SAR markers. - Updated sample data with more relevant team names using emojis. - Enhanced map markers to include rotation handling and improved display of contact information. - Introduced color coding for location update age in map markers for better visibility.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'contact_telemetry.dart';
|
||||
|
||||
/// MeshCore contact types
|
||||
@@ -129,6 +130,67 @@ class Contact {
|
||||
return '${diff.inDays}d ago';
|
||||
}
|
||||
|
||||
/// Get time when location was last updated
|
||||
DateTime? get locationUpdateTime {
|
||||
// Prefer telemetry timestamp if available
|
||||
if (telemetry?.gpsLocation != null) {
|
||||
return telemetry!.timestamp;
|
||||
}
|
||||
// Fall back to lastAdvert time if using advertised location
|
||||
if (advertLocation != null) {
|
||||
return lastSeenTime;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get friendly time since location was last updated
|
||||
String get timeSinceLocationUpdate {
|
||||
final updateTime = locationUpdateTime;
|
||||
if (updateTime == null) return 'Unknown';
|
||||
|
||||
final diff = DateTime.now().difference(updateTime);
|
||||
if (diff.inMinutes < 1) return 'Now';
|
||||
if (diff.inMinutes < 60) return '${diff.inMinutes}m';
|
||||
if (diff.inHours < 24) return '${diff.inHours}h';
|
||||
return '${diff.inDays}d';
|
||||
}
|
||||
|
||||
/// Extract role emoji from name (e.g., "🧑🏻🚒Janez" → "🧑🏻🚒")
|
||||
/// Returns null if no emoji at start of name
|
||||
String? get roleEmoji {
|
||||
if (advName.isEmpty) return null;
|
||||
|
||||
// Get the first character/grapheme cluster (which could be a complex emoji)
|
||||
final firstChar = advName.characters.first;
|
||||
|
||||
// Check if it's an emoji (basic check - emojis are typically in certain Unicode ranges)
|
||||
final firstCodeUnit = firstChar.runes.first;
|
||||
|
||||
// Emoji ranges (simplified check):
|
||||
// 0x1F300-0x1F9FF: Misc Symbols and Pictographs, Emoticons, Transport, etc.
|
||||
// 0x2600-0x26FF: Misc symbols
|
||||
// 0x2700-0x27BF: Dingbats
|
||||
// 0xFE00-0xFE0F: Variation Selectors
|
||||
// 0x1F900-0x1F9FF: Supplemental Symbols and Pictographs
|
||||
if ((firstCodeUnit >= 0x1F300 && firstCodeUnit <= 0x1F9FF) ||
|
||||
(firstCodeUnit >= 0x2600 && firstCodeUnit <= 0x27BF) ||
|
||||
(firstCodeUnit >= 0x1F600 && firstCodeUnit <= 0x1F64F)) {
|
||||
return firstChar;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get display name without role emoji (e.g., "🧑🏻🚒Janez" → "Janez")
|
||||
/// If no emoji, returns full advName
|
||||
String get displayName {
|
||||
final emoji = roleEmoji;
|
||||
if (emoji == null) return advName;
|
||||
|
||||
// Remove the emoji from the beginning
|
||||
return advName.substring(emoji.length).trim();
|
||||
}
|
||||
|
||||
Contact copyWith({
|
||||
Uint8List? publicKey,
|
||||
ContactType? type,
|
||||
|
||||
@@ -6,6 +6,7 @@ enum SarMarkerType {
|
||||
foundPerson('🧑', 'Found Person'),
|
||||
fire('🔥', 'Fire'),
|
||||
stagingArea('🏕️', 'Staging Area'),
|
||||
object('📦', 'Object'),
|
||||
unknown('❓', 'Unknown');
|
||||
|
||||
const SarMarkerType(this.emoji, this.displayName);
|
||||
@@ -22,6 +23,8 @@ enum SarMarkerType {
|
||||
case '🏕️':
|
||||
case '⛺':
|
||||
return SarMarkerType.stagingArea;
|
||||
case '📦':
|
||||
return SarMarkerType.object;
|
||||
default:
|
||||
return SarMarkerType.unknown;
|
||||
}
|
||||
@@ -36,6 +39,8 @@ enum SarMarkerType {
|
||||
return '#F44336'; // Red
|
||||
case SarMarkerType.stagingArea:
|
||||
return '#2196F3'; // Blue
|
||||
case SarMarkerType.object:
|
||||
return '#9C27B0'; // Purple
|
||||
default:
|
||||
return '#9E9E9E'; // Gray
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user