mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-28 06:26:39 +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/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../connector/meshcore_connector.dart';
|
import '../connector/meshcore_connector.dart';
|
||||||
@@ -357,7 +356,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
|
|||||||
final enableTracing = settingsService.settings.enableMessageTracing;
|
final enableTracing = settingsService.settings.enableMessageTracing;
|
||||||
final isOutgoing = message.isOutgoing;
|
final isOutgoing = message.isOutgoing;
|
||||||
final gifId = GifHelper.parseGif(message.text);
|
final gifId = GifHelper.parseGif(message.text);
|
||||||
final poi = _parsePoiMessage(message.text);
|
final poi = parseMarkerText(message.text);
|
||||||
final translatedDisplayText =
|
final translatedDisplayText =
|
||||||
message.translatedText != null &&
|
message.translatedText != null &&
|
||||||
message.translatedText!.trim().isNotEmpty
|
message.translatedText!.trim().isNotEmpty
|
||||||
@@ -702,7 +701,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
|
|||||||
final previewTextColor = colorScheme.onSurface.withValues(alpha: 0.7);
|
final previewTextColor = colorScheme.onSurface.withValues(alpha: 0.7);
|
||||||
|
|
||||||
final gifId = GifHelper.parseGif(replyText);
|
final gifId = GifHelper.parseGif(replyText);
|
||||||
final poi = _parsePoiMessage(replyText);
|
final poi = parseMarkerText(replyText);
|
||||||
|
|
||||||
Widget contentPreview;
|
Widget contentPreview;
|
||||||
if (gifId != null) {
|
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(
|
Widget _buildPoiMessage(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
_PoiInfo poi,
|
MarkerPayload poi,
|
||||||
bool isOutgoing,
|
bool isOutgoing,
|
||||||
double textScale,
|
double textScale,
|
||||||
String senderName, {
|
String senderName, {
|
||||||
@@ -865,7 +850,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
|
|||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => MapScreen(
|
builder: (context) => MapScreen(
|
||||||
highlightPosition: LatLng(poi.lat, poi.lon),
|
highlightPosition: poi.position,
|
||||||
highlightLabel: poi.label,
|
highlightLabel: poi.label,
|
||||||
highlightMarkerKey: key,
|
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 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../utils/platform_info.dart';
|
import '../utils/platform_info.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
|
||||||
|
|
||||||
import '../connector/meshcore_connector.dart';
|
import '../connector/meshcore_connector.dart';
|
||||||
import '../connector/meshcore_protocol.dart';
|
import '../connector/meshcore_protocol.dart';
|
||||||
@@ -1589,7 +1588,7 @@ class _MessageBubble extends StatelessWidget {
|
|||||||
final isOutgoing = message.isOutgoing;
|
final isOutgoing = message.isOutgoing;
|
||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
final gifId = GifHelper.parseGif(message.text);
|
final gifId = GifHelper.parseGif(message.text);
|
||||||
final poi = _parsePoiMessage(message.text);
|
final poi = parseMarkerText(message.text);
|
||||||
final isFailed = message.status == MessageStatus.failed;
|
final isFailed = message.status == MessageStatus.failed;
|
||||||
final bubbleColor = isFailed
|
final bubbleColor = isFailed
|
||||||
? colorScheme.errorContainer
|
? 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(
|
Widget _buildPoiMessage(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
_PoiInfo poi,
|
MarkerPayload poi,
|
||||||
Color textColor,
|
Color textColor,
|
||||||
Color metaColor,
|
Color metaColor,
|
||||||
double textScale,
|
double textScale,
|
||||||
@@ -1907,7 +1892,7 @@ class _MessageBubble extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => MapScreen(
|
builder: (context) => MapScreen(
|
||||||
highlightPosition: LatLng(poi.lat, poi.lon),
|
highlightPosition: poi.position,
|
||||||
highlightLabel: poi.label,
|
highlightLabel: poi.label,
|
||||||
highlightMarkerKey: key,
|
highlightMarkerKey: key,
|
||||||
),
|
),
|
||||||
@@ -2090,17 +2075,3 @@ class _MessageBubble extends StatelessWidget {
|
|||||||
return '$hour:$minute';
|
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) {
|
for (final contact in connector.contacts) {
|
||||||
final messages = connector.getMessages(contact);
|
final messages = connector.getMessages(contact);
|
||||||
for (final message in messages) {
|
for (final message in messages) {
|
||||||
final payload = _parseMarkerText(message.text);
|
final payload = parseMarkerText(message.text);
|
||||||
if (payload == null) continue;
|
if (payload == null) continue;
|
||||||
final fromName = message.isOutgoing ? selfName : contact.name;
|
final fromName = message.isOutgoing ? selfName : contact.name;
|
||||||
final key = buildSharedMarkerKey(
|
final key = buildSharedMarkerKey(
|
||||||
@@ -1300,7 +1300,9 @@ class _MapScreenState extends State<MapScreen> {
|
|||||||
_SharedMarker(
|
_SharedMarker(
|
||||||
id: key,
|
id: key,
|
||||||
position: payload.position,
|
position: payload.position,
|
||||||
label: payload.label,
|
label: payload.label.isEmpty
|
||||||
|
? context.l10n.map_sharedPin
|
||||||
|
: payload.label,
|
||||||
flags: payload.flags,
|
flags: payload.flags,
|
||||||
fromName: fromName,
|
fromName: fromName,
|
||||||
sourceLabel: contact.name,
|
sourceLabel: contact.name,
|
||||||
@@ -1316,7 +1318,7 @@ class _MapScreenState extends State<MapScreen> {
|
|||||||
final isPublic = _isPublicChannel(channel);
|
final isPublic = _isPublicChannel(channel);
|
||||||
final messages = connector.getChannelMessages(channel);
|
final messages = connector.getChannelMessages(channel);
|
||||||
for (final message in messages) {
|
for (final message in messages) {
|
||||||
final payload = _parseMarkerText(message.text);
|
final payload = parseMarkerText(message.text);
|
||||||
if (payload == null) continue;
|
if (payload == null) continue;
|
||||||
final key = buildSharedMarkerKey(
|
final key = buildSharedMarkerKey(
|
||||||
sourceId: 'channel:${channel.index}',
|
sourceId: 'channel:${channel.index}',
|
||||||
@@ -1329,7 +1331,9 @@ class _MapScreenState extends State<MapScreen> {
|
|||||||
_SharedMarker(
|
_SharedMarker(
|
||||||
id: key,
|
id: key,
|
||||||
position: payload.position,
|
position: payload.position,
|
||||||
label: payload.label,
|
label: payload.label.isEmpty
|
||||||
|
? context.l10n.map_sharedPin
|
||||||
|
: payload.label,
|
||||||
flags: payload.flags,
|
flags: payload.flags,
|
||||||
fromName: message.senderName,
|
fromName: message.senderName,
|
||||||
sourceLabel: channel.name.isEmpty
|
sourceLabel: channel.name.isEmpty
|
||||||
@@ -1364,27 +1368,6 @@ class _MapScreenState extends State<MapScreen> {
|
|||||||
return markers;
|
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) {
|
Marker _buildSharedMarker(_SharedMarker marker) {
|
||||||
final markerColor = marker.isChannel
|
final markerColor = marker.isChannel
|
||||||
? (marker.isPublicChannel ? Colors.orange : Colors.purple)
|
? (marker.isPublicChannel ? Colors.orange : Colors.purple)
|
||||||
@@ -2385,18 +2368,34 @@ class _GuessedLocation {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MarkerPayload {
|
class MarkerPayload {
|
||||||
final LatLng position;
|
final LatLng position;
|
||||||
final String label;
|
final String label;
|
||||||
final String flags;
|
final String flags;
|
||||||
|
|
||||||
_MarkerPayload({
|
MarkerPayload({
|
||||||
required this.position,
|
required this.position,
|
||||||
required this.label,
|
required this.label,
|
||||||
required this.flags,
|
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.
|
/// Build a normalized dedupe key for shared markers.
|
||||||
/// Keeps the same algorithm previously present in both chat and map screens.
|
/// Keeps the same algorithm previously present in both chat and map screens.
|
||||||
String buildSharedMarkerKey({
|
String buildSharedMarkerKey({
|
||||||
|
|||||||
Reference in New Issue
Block a user