feat: Enhance SAR message handling with color indexing and localization

- Added `sarColorIndex` to `Message` and `SarMarker` models to support color indexing for SAR markers.
- Introduced a standard color palette in `SarTemplate` and methods to retrieve colors based on index.
- Updated `SarTemplate` to include localization for template names.
- Modified `SarUpdateSheet` and message sending logic to include color index in SAR messages.
- Enhanced `SarMessageParser` to support both old and new message formats with color index.
- Updated UI components to reflect changes in SAR marker color handling based on the new color index.
- Improved sample data generation to utilize localized strings for better testing and demonstration.
This commit is contained in:
Janez T
2025-10-23 19:17:13 +02:00
parent b70eed1bf2
commit 98cda8c976
28 changed files with 2734 additions and 270 deletions

View File

@@ -9,6 +9,7 @@ import '../../models/message.dart';
import '../../providers/connection_provider.dart';
import '../../providers/messages_provider.dart';
import '../../providers/app_provider.dart';
import '../../services/message_destination_preferences.dart';
import '../../utils/toast_logger.dart';
import '../../l10n/app_localizations.dart';
@@ -159,6 +160,15 @@ class _DirectMessageSheetState extends State<DirectMessageSheet> {
messagesProvider.markMessageFailed(messageId);
}
// Save the recipient to preferences so messages tab filters to this contact
final recipientType = widget.contact.type == ContactType.room
? MessageDestinationPreferences.destinationTypeRoom
: MessageDestinationPreferences.destinationTypeContact;
await MessageDestinationPreferences.setDestination(
recipientType,
recipientPublicKey: widget.contact.publicKeyHex,
);
_textController.clear();
_focusNode.unfocus();

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import '../models/contact.dart';
import '../models/sar_marker.dart';
import '../models/sar_template.dart';
import '../l10n/app_localizations.dart';
class MapMarkers {
@@ -129,7 +130,7 @@ class MapMarkers {
Container(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
decoration: BoxDecoration(
color: _getSarMarkerColor(marker.type),
color: _getSarMarkerColor(marker),
borderRadius: BorderRadius.circular(3),
),
child: Text(
@@ -145,7 +146,7 @@ class MapMarkers {
// Marker emoji/icon
Container(
decoration: BoxDecoration(
color: _getSarMarkerColor(marker.type),
color: _getSarMarkerColor(marker),
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 2),
boxShadow: [
@@ -302,8 +303,16 @@ class MapMarkers {
return Colors.red; // Stale
}
static Color _getSarMarkerColor(SarMarkerType type) {
switch (type) {
static Color _getSarMarkerColor(SarMarker marker) {
// If marker has a color index, use it (new format)
if (marker.colorIndex != null && marker.colorIndex! >= 0 && marker.colorIndex! < 8) {
final colorHex = SarTemplate.getColorFromIndex(marker.colorIndex!);
final hexCode = colorHex.replaceAll('#', '');
return Color(int.parse('FF$hexCode', radix: 16));
}
// Otherwise fall back to type-based colors (old format or backward compatibility)
switch (marker.type) {
case SarMarkerType.foundPerson:
return Colors.green;
case SarMarkerType.fire:

View File

@@ -18,6 +18,7 @@ class SarUpdateSheet extends StatefulWidget {
Position,
Uint8List?,
bool,
int colorIndex,
)
onSend;
final Position? prePopulatedPosition;
@@ -784,7 +785,7 @@ class _SarUpdateSheetState extends State<SarUpdateSheet> {
displayText = _selectedTemplate!.name;
}
// Send SAR marker with emoji and display text
// Send SAR marker with emoji, display text, and color index
await widget.onSend(
_selectedTemplate!.emoji,
displayText,
@@ -793,6 +794,7 @@ class _SarUpdateSheetState extends State<SarUpdateSheet> {
? null
: _selectedContact!.publicKey,
_selectedContact!.isChannel,
_selectedTemplate!.getColorIndex(), // Include color index
);
if (context.mounted) {
Navigator.pop(context);
@@ -869,7 +871,7 @@ class TemplateChip extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
template.name,
template.getLocalizedName(context),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,