mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-06-14 22:55:12 +10:00
consolidate parsing in single parseMarkerText in map_screen.dart
This commit is contained in:
@@ -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<ChannelChatScreen> {
|
||||
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<ChannelChatScreen> {
|
||||
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<ChannelChatScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
_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<ChannelChatScreen> {
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
+26
-27
@@ -1286,7 +1286,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
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<MapScreen> {
|
||||
_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<MapScreen> {
|
||||
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<MapScreen> {
|
||||
_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<MapScreen> {
|
||||
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:<lat>,<lon>|<label>|<flags>` and return a [MarkerPayload].
|
||||
MarkerPayload? parseMarkerText(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) ?? '').trim();
|
||||
final flags = (match.group(4) ?? '').trim();
|
||||
return MarkerPayload(position: LatLng(lat, lon), label: label, flags: flags);
|
||||
}
|
||||
|
||||
/// Build a normalized dedupe key for shared markers.
|
||||
/// Keeps the same algorithm previously present in both chat and map screens.
|
||||
String buildSharedMarkerKey({
|
||||
|
||||
Reference in New Issue
Block a user