Enhance compass dialog to include SAR markers; update settings screen to load combined messages from SAR and channel sources

This commit is contained in:
Janez T
2025-10-14 00:21:23 +02:00
parent c2e882bb2b
commit d1b80b92c7
3 changed files with 119 additions and 4 deletions

View File

@@ -506,7 +506,7 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
); );
} }
void _showDetailedCompass(BuildContext context, List<Contact> contacts) { void _showDetailedCompass(BuildContext context, List<Contact> contacts, List<SarMarker> sarMarkers) {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
@@ -521,6 +521,7 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
initialPosition: _currentPosition, initialPosition: _currentPosition,
initialHeading: _currentHeading, initialHeading: _currentHeading,
contacts: contacts, contacts: contacts,
sarMarkers: sarMarkers,
), ),
), ),
); );
@@ -665,6 +666,7 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
onTap: () => _showDetailedCompass( onTap: () => _showDetailedCompass(
context, context,
contactsProvider.chatContactsWithLocation, contactsProvider.chatContactsWithLocation,
messagesProvider.sarMarkers,
), ),
child: _CompassWidget( child: _CompassWidget(
heading: _currentHeading ?? 0, heading: _currentHeading ?? 0,
@@ -972,11 +974,13 @@ class _DetailedCompassDialog extends StatefulWidget {
final Position? initialPosition; final Position? initialPosition;
final double? initialHeading; final double? initialHeading;
final List<Contact> contacts; final List<Contact> contacts;
final List<SarMarker> sarMarkers;
const _DetailedCompassDialog({ const _DetailedCompassDialog({
required this.initialPosition, required this.initialPosition,
required this.initialHeading, required this.initialHeading,
required this.contacts, required this.contacts,
required this.sarMarkers,
}); });
@override @override

View File

@@ -93,12 +93,20 @@ class _SettingsScreenState extends State<SettingsScreen> {
stagingCount: 1, stagingCount: 1,
); );
final channelMessages = SampleDataGenerator.generateChannelMessages(
generalChannelMessages: 8,
emergencyChannelMessages: 5,
);
// Combine all messages
final allMessages = [...sarMessages, ...channelMessages];
// Add to providers // Add to providers
final contactsProvider = Provider.of<ContactsProvider>(context, listen: false); final contactsProvider = Provider.of<ContactsProvider>(context, listen: false);
final messagesProvider = Provider.of<MessagesProvider>(context, listen: false); final messagesProvider = Provider.of<MessagesProvider>(context, listen: false);
contactsProvider.addContacts(contacts); contactsProvider.addContacts(contacts);
messagesProvider.addMessages(sarMessages); messagesProvider.addMessages(allMessages);
if (!mounted) return; if (!mounted) return;
@@ -108,7 +116,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
'Loaded $teamCount team members, $channelCount channels, ${sarMessages.length} SAR markers', 'Loaded $teamCount team members, $channelCount channels, ${sarMessages.length} SAR markers, ${channelMessages.length} messages',
), ),
backgroundColor: Colors.green, backgroundColor: Colors.green,
), ),
@@ -227,7 +235,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text( child: Text(
'Load or clear sample contacts and SAR markers for testing', 'Load or clear sample contacts, channel messages, and SAR markers for testing',
style: Theme.of(context).textTheme.bodySmall?.copyWith( style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
), ),

View File

@@ -211,4 +211,107 @@ class SampleDataGenerator {
return messages; return messages;
} }
/// Generate sample channel messages for public channels
static List<Message> generateChannelMessages({
int generalChannelMessages = 8,
int emergencyChannelMessages = 5,
}) {
final messages = <Message>[];
final now = DateTime.now();
int messageId = 1000; // Start with high ID to avoid conflicts
// Sample messages for General channel (index 0)
final generalMessages = [
'All teams check in',
'Weather update: Clear skies, temp 18°C',
'Base camp established at staging area',
'Team Alpha moving to sector 2',
'Radio check - all stations respond',
'Water supply available at checkpoint 3',
'Team Bravo reporting: sector 1 clear',
'ETA to rally point: 15 minutes',
'Supply drop confirmed for 14:00',
'Drone survey completed - no findings',
'Team Charlie requesting backup',
'All units: maintain radio discipline',
];
// Sample messages for Emergency channel (index 1)
final emergencyMessages = [
'URGENT: Medical assistance needed at sector 4',
'Found person - requesting immediate evac',
'Fire spotted - coordinates incoming',
'Team member injured - sending location',
'PRIORITY: Need helicopter support',
'Medical team en route to your location',
'Evac helicopter ETA 10 minutes',
'Emergency resolved - all clear',
'Casualties: 1 minor injury, being treated',
'Emergency services notified and responding',
];
final teamNames = [
'Alpha Team Lead',
'Bravo Scout',
'Charlie Medic',
'Delta Navigator',
'Echo Support',
'Base Command',
'Field Coordinator',
'Medical Team',
];
// Generate General channel messages
for (int i = 0; i < generalChannelMessages && i < generalMessages.length; i++) {
final senderKey = Uint8List.fromList(
List.generate(32, (_) => _random.nextInt(256)),
);
// Messages spread over the last 2 hours
final minutesAgo = 120 - (i * 15) - _random.nextInt(10);
final timestamp = now.subtract(Duration(minutes: minutesAgo));
messages.add(Message(
id: 'sample_general_$messageId',
messageType: MessageType.channel,
channelIdx: 0, // General channel
senderPublicKeyPrefix: senderKey.sublist(0, 6),
pathLen: 1,
textType: MessageTextType.plain,
senderTimestamp: timestamp.millisecondsSinceEpoch ~/ 1000,
text: generalMessages[i],
receivedAt: timestamp,
senderName: teamNames[_random.nextInt(teamNames.length)],
));
messageId++;
}
// Generate Emergency channel messages
for (int i = 0; i < emergencyChannelMessages && i < emergencyMessages.length; i++) {
final senderKey = Uint8List.fromList(
List.generate(32, (_) => _random.nextInt(256)),
);
// Emergency messages more recent (last hour)
final minutesAgo = 60 - (i * 10) - _random.nextInt(5);
final timestamp = now.subtract(Duration(minutes: minutesAgo));
messages.add(Message(
id: 'sample_emergency_$messageId',
messageType: MessageType.channel,
channelIdx: 1, // Emergency channel
senderPublicKeyPrefix: senderKey.sublist(0, 6),
pathLen: 1,
textType: MessageTextType.plain,
senderTimestamp: timestamp.millisecondsSinceEpoch ~/ 1000,
text: emergencyMessages[i],
receivedAt: timestamp,
senderName: teamNames[_random.nextInt(teamNames.length)],
));
messageId++;
}
return messages;
}
} }