fix: correct location validation and clean up target contact handling

- Fix asymmetric lat/lon validation in _handleContactAdvert (was checking
  longitude != 0 for latitude; now uses (latitude != 0 || longitude != 0)
  for both)
- Remove duplicate targetGuessed assignment in path_trace_map
- Rename public target field to private _targetContact, use local variable
  to avoid unnecessary null-aware operators

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
zjs81
2026-03-14 18:14:39 -07:00
parent 3593cfa843
commit 28a423e0a8
2 changed files with 14 additions and 12 deletions
+2 -2
View File
@@ -4757,14 +4757,14 @@ class MeshCoreConnector extends ChangeNotifier {
hasLocation && hasLocation &&
latitude != null && latitude != null &&
latitude.abs() <= 90 && latitude.abs() <= 90 &&
longitude != 0 (latitude != 0 || longitude != 0)
? latitude ? latitude
: existing.latitude, : existing.latitude,
longitude: longitude:
hasLocation && hasLocation &&
longitude != null && longitude != null &&
longitude.abs() <= 180 && longitude.abs() <= 180 &&
longitude != 0 (latitude != 0 || longitude != 0)
? longitude ? longitude
: existing.longitude, : existing.longitude,
name: hasName ? name : existing.name, name: hasName ? name : existing.name,
+12 -10
View File
@@ -93,7 +93,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
ValueKey<String> _mapKey = const ValueKey('initial'); ValueKey<String> _mapKey = const ValueKey('initial');
double _pathDistanceMeters = 0.0; double _pathDistanceMeters = 0.0;
bool _showNodeLabels = true; bool _showNodeLabels = true;
Contact? target; Contact? _targetContact;
String _formatPathPrefixes(Uint8List pathBytes) { String _formatPathPrefixes(Uint8List pathBytes) {
return pathBytes return pathBytes
@@ -305,11 +305,12 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
// Compute endpoint position for the target contact. // Compute endpoint position for the target contact.
LatLng? targetPos; LatLng? targetPos;
bool targetGuessed = false; bool targetGuessed = false;
target = widget.targetContact; _targetContact = widget.targetContact;
if (target != null) { if (_targetContact != null) {
if (target?.hasLocation ?? false) { final tc = _targetContact!;
targetPos = LatLng(target!.latitude!, target!.longitude!); if (tc.hasLocation) {
targetPos = LatLng(tc.latitude!, tc.longitude!);
} else if (widget.path.length > 1) { } else if (widget.path.length > 1) {
// Infer from the last hop: average GPS contacts sharing that hop. // Infer from the last hop: average GPS contacts sharing that hop.
// For a round-trip path (flipPathAround/reversePathAround), the target-side hop // For a round-trip path (flipPathAround/reversePathAround), the target-side hop
@@ -334,7 +335,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
peers.map((c) => c.longitude!).reduce((a, b) => a + b) / peers.map((c) => c.longitude!).reduce((a, b) => a + b) /
peers.length; peers.length;
const offsetDeg = 0.003; const offsetDeg = 0.003;
final angle = (target!.publicKey[1] / 255.0) * 2 * pi; final angle = (tc.publicKey[1] / 255.0) * 2 * pi;
targetPos = LatLng( targetPos = LatLng(
lat + offsetDeg * cos(angle), lat + offsetDeg * cos(angle),
lon + offsetDeg * sin(angle), lon + offsetDeg * sin(angle),
@@ -344,7 +345,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
final lat = inferredPositions[lastHop]!.latitude; final lat = inferredPositions[lastHop]!.latitude;
final lon = inferredPositions[lastHop]!.longitude; final lon = inferredPositions[lastHop]!.longitude;
const offsetDeg = 0.003; const offsetDeg = 0.003;
final angle = (target!.publicKey[1] / 255.0) * 2 * pi; final angle = (tc.publicKey[1] / 255.0) * 2 * pi;
targetPos = LatLng( targetPos = LatLng(
lat + offsetDeg * cos(angle), lat + offsetDeg * cos(angle),
lon + offsetDeg * sin(angle), lon + offsetDeg * sin(angle),
@@ -355,7 +356,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
final contact = pathContacts[lastHop]; final contact = pathContacts[lastHop];
if (contact != null && contact.hasLocation) { if (contact != null && contact.hasLocation) {
const offsetDeg = 0.003; const offsetDeg = 0.003;
final angle = (target!.publicKey[1] / 255.0) * 2 * pi; final angle = (tc.publicKey[1] / 255.0) * 2 * pi;
targetPos = LatLng( targetPos = LatLng(
contact.latitude! + offsetDeg * cos(angle), contact.latitude! + offsetDeg * cos(angle),
contact.longitude! + offsetDeg * sin(angle), contact.longitude! + offsetDeg * sin(angle),
@@ -387,7 +388,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
hopLast = hop; hopLast = hop;
} }
if (targetPos != null) { if (targetPos != null) {
if (target != null && target!.type == advTypeChat) { if (_targetContact != null && _targetContact!.type == advTypeChat) {
_points.add(targetPos); _points.add(targetPos);
} }
} }
@@ -479,7 +480,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
], ],
), ),
), ),
if (_hasData) _buildMapPathTrace(context, tileCache, target), if (_hasData)
_buildMapPathTrace(context, tileCache, _targetContact),
if (_points.isEmpty && if (_points.isEmpty &&
!_hasData && !_hasData &&
!_isLoading && !_isLoading &&