diff --git a/lib/screens/channel_chat_screen.dart b/lib/screens/channel_chat_screen.dart index e89eb158..f7821a14 100644 --- a/lib/screens/channel_chat_screen.dart +++ b/lib/screens/channel_chat_screen.dart @@ -4,7 +4,6 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; -import 'package:latlong2/latlong.dart'; import 'package:provider/provider.dart'; import '../connector/meshcore_connector.dart'; @@ -357,7 +356,7 @@ class _ChannelChatScreenState extends State { final enableTracing = settingsService.settings.enableMessageTracing; final isOutgoing = message.isOutgoing; final gifId = GifHelper.parseGif(message.text); - final poi = _parsePoiMessage(message.text); + final poi = parseMarkerText(message.text); final translatedDisplayText = message.translatedText != null && message.translatedText!.trim().isNotEmpty @@ -702,7 +701,7 @@ class _ChannelChatScreenState extends State { final previewTextColor = colorScheme.onSurface.withValues(alpha: 0.7); final gifId = GifHelper.parseGif(replyText); - final poi = _parsePoiMessage(replyText); + final poi = parseMarkerText(replyText); Widget contentPreview; if (gifId != null) { @@ -813,23 +812,9 @@ class _ChannelChatScreenState extends State { ); } - _PoiInfo? _parsePoiMessage(String text) { - final trimmed = text.trim(); - final match = RegExp( - r'm:([\-0-9.]+),([\-0-9.]+)\|([^|]*)\|(.*)', - ).firstMatch(trimmed); - if (match == null) return null; - final lat = double.tryParse(match.group(1) ?? ''); - final lon = double.tryParse(match.group(2) ?? ''); - if (lat == null || lon == null) return null; - final label = match.group(3) ?? ''; - final flags = match.group(4) ?? ''; - return _PoiInfo(lat: lat, lon: lon, label: label, flags: flags); - } - Widget _buildPoiMessage( BuildContext context, - _PoiInfo poi, + MarkerPayload poi, bool isOutgoing, double textScale, String senderName, { @@ -865,7 +850,7 @@ class _ChannelChatScreenState extends State { context, MaterialPageRoute( builder: (context) => MapScreen( - highlightPosition: LatLng(poi.lat, poi.lon), + highlightPosition: poi.position, highlightLabel: poi.label, highlightMarkerKey: key, ), @@ -1520,17 +1505,3 @@ class _SwipeReplyBubbleState extends State<_SwipeReplyBubble> { ); } } - -class _PoiInfo { - final double lat; - final double lon; - final String label; - final String flags; - - const _PoiInfo({ - required this.lat, - required this.lon, - required this.label, - required this.flags, - }); -} diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 129f6925..fe7b0086 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -9,7 +9,6 @@ import 'package:meshcore_open/screens/path_trace_map.dart'; import 'package:provider/provider.dart'; import '../utils/platform_info.dart'; -import 'package:latlong2/latlong.dart'; import '../connector/meshcore_connector.dart'; import '../connector/meshcore_protocol.dart'; @@ -1589,7 +1588,7 @@ class _MessageBubble extends StatelessWidget { final isOutgoing = message.isOutgoing; final colorScheme = Theme.of(context).colorScheme; final gifId = GifHelper.parseGif(message.text); - final poi = _parsePoiMessage(message.text); + final poi = parseMarkerText(message.text); final isFailed = message.status == MessageStatus.failed; final bubbleColor = isFailed ? colorScheme.errorContainer @@ -1863,23 +1862,9 @@ class _MessageBubble extends StatelessWidget { ); } - _PoiInfo? _parsePoiMessage(String text) { - final trimmed = text.trim(); - final match = RegExp( - r'^m:([\-0-9.]+),([\-0-9.]+)\|([^|]*)\|(.*)$', - ).firstMatch(trimmed); - if (match == null) return null; - final lat = double.tryParse(match.group(1) ?? ''); - final lon = double.tryParse(match.group(2) ?? ''); - if (lat == null || lon == null) return null; - final label = match.group(3) ?? ''; - final flags = match.group(4) ?? ''; - return _PoiInfo(lat: lat, lon: lon, label: label, flags: flags); - } - Widget _buildPoiMessage( BuildContext context, - _PoiInfo poi, + MarkerPayload poi, Color textColor, Color metaColor, double textScale, @@ -1907,7 +1892,7 @@ class _MessageBubble extends StatelessWidget { context, MaterialPageRoute( builder: (context) => MapScreen( - highlightPosition: LatLng(poi.lat, poi.lon), + highlightPosition: poi.position, highlightLabel: poi.label, highlightMarkerKey: key, ), @@ -2090,17 +2075,3 @@ class _MessageBubble extends StatelessWidget { return '$hour:$minute'; } } - -class _PoiInfo { - final double lat; - final double lon; - final String label; - final String flags; - - const _PoiInfo({ - required this.lat, - required this.lon, - required this.label, - required this.flags, - }); -} diff --git a/lib/screens/map_screen.dart b/lib/screens/map_screen.dart index 1f8bce26..fb48f838 100644 --- a/lib/screens/map_screen.dart +++ b/lib/screens/map_screen.dart @@ -1286,7 +1286,7 @@ class _MapScreenState extends State { for (final contact in connector.contacts) { final messages = connector.getMessages(contact); for (final message in messages) { - final payload = _parseMarkerText(message.text); + final payload = parseMarkerText(message.text); if (payload == null) continue; final fromName = message.isOutgoing ? selfName : contact.name; final key = buildSharedMarkerKey( @@ -1300,7 +1300,9 @@ class _MapScreenState extends State { _SharedMarker( id: key, position: payload.position, - label: payload.label, + label: payload.label.isEmpty + ? context.l10n.map_sharedPin + : payload.label, flags: payload.flags, fromName: fromName, sourceLabel: contact.name, @@ -1316,7 +1318,7 @@ class _MapScreenState extends State { final isPublic = _isPublicChannel(channel); final messages = connector.getChannelMessages(channel); for (final message in messages) { - final payload = _parseMarkerText(message.text); + final payload = parseMarkerText(message.text); if (payload == null) continue; final key = buildSharedMarkerKey( sourceId: 'channel:${channel.index}', @@ -1329,7 +1331,9 @@ class _MapScreenState extends State { _SharedMarker( id: key, position: payload.position, - label: payload.label, + label: payload.label.isEmpty + ? context.l10n.map_sharedPin + : payload.label, flags: payload.flags, fromName: message.senderName, sourceLabel: channel.name.isEmpty @@ -1364,27 +1368,6 @@ class _MapScreenState extends State { return markers; } - _MarkerPayload? _parseMarkerText(String text) { - final trimmed = text.trim(); - if (!trimmed.startsWith('m:')) return null; - - final parts = trimmed.substring(2).split('|'); - if (parts.isEmpty) return null; - final coords = parts[0].split(','); - if (coords.length != 2) return null; - final lat = double.tryParse(coords[0].trim()); - final lon = double.tryParse(coords[1].trim()); - if (lat == null || lon == null) return null; - - final label = parts.length > 1 ? parts[1].trim() : ''; - final flags = parts.length > 2 ? parts[2].trim() : ''; - return _MarkerPayload( - position: LatLng(lat, lon), - label: label.isEmpty ? context.l10n.map_sharedPin : label, - flags: flags, - ); - } - Marker _buildSharedMarker(_SharedMarker marker) { final markerColor = marker.isChannel ? (marker.isPublicChannel ? Colors.orange : Colors.purple) @@ -2385,18 +2368,34 @@ class _GuessedLocation { }); } -class _MarkerPayload { +class MarkerPayload { final LatLng position; final String label; final String flags; - _MarkerPayload({ + MarkerPayload({ required this.position, required this.label, required this.flags, }); } +/// Parse a shared marker text message of the form +/// `m:,|