From d1e45fc2ba82ef2274ae73acacb2865dc432b8a2 Mon Sep 17 00:00:00 2001 From: ericz Date: Sat, 28 Mar 2026 17:08:59 +0100 Subject: [PATCH] moved _getRepeaterPrefixMatchNearLocation since I don't need the function anywhere else anymore. --- lib/utils/contact_search.dart | 55 -------------------------- lib/widgets/snr_indicator.dart | 70 ++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 58 deletions(-) diff --git a/lib/utils/contact_search.dart b/lib/utils/contact_search.dart index 6a708e8..7a82c53 100644 --- a/lib/utils/contact_search.dart +++ b/lib/utils/contact_search.dart @@ -1,6 +1,3 @@ -import 'package:latlong2/latlong.dart'; - -import '../connector/meshcore_protocol.dart'; import '../models/contact.dart'; export 'contact_filter_types.dart'; @@ -46,55 +43,3 @@ String? _extractHexPrefix(String query) { if (!RegExp(r'^[0-9a-f]+$').hasMatch(cleaned)) return null; return cleaned; } - -Contact? getRepeaterPrefixMatchNearLocation( - List contacts, - int pubkeyFirstByte, { - LatLng? searchPoint, - bool preferFavorites = false, -}) { - final candidates = contacts - .where( - (c) => - c.publicKey.isNotEmpty && - c.publicKey.first == pubkeyFirstByte && - (c.type == advTypeRepeater || c.type == advTypeRoom), - ) - .toList(); - - if (candidates.isEmpty) return null; - - candidates.sort((a, b) { - if (preferFavorites) { - final favA = a.isFavorite ? 1 : 0; - final favB = b.isFavorite ? 1 : 0; - final favCompare = favB.compareTo(favA); - if (favCompare != 0) return favCompare; - } - - final seenCompare = b.lastSeen.compareTo(a.lastSeen); - if (seenCompare != 0) return seenCompare; - - return a.publicKeyHex.compareTo(b.publicKeyHex); - }); - - if (searchPoint == null) { - return candidates.first; - } - - final distance = Distance(); - Contact best = candidates.first; - var bestDistance = double.infinity; - - for (final c in candidates) { - if (c.hasLocation && c.latitude != null && c.longitude != null) { - final d = distance(searchPoint, LatLng(c.latitude!, c.longitude!)); - if (d < bestDistance) { - bestDistance = d; - best = c; - } - } - } - - return best; -} diff --git a/lib/widgets/snr_indicator.dart b/lib/widgets/snr_indicator.dart index cf3c275..99f2053 100644 --- a/lib/widgets/snr_indicator.dart +++ b/lib/widgets/snr_indicator.dart @@ -2,10 +2,63 @@ import 'package:flutter/material.dart'; import 'package:latlong2/latlong.dart'; import '../connector/meshcore_connector.dart'; -import '../utils/contact_search.dart'; +import '../connector/meshcore_protocol.dart'; import '../l10n/l10n.dart'; +import '../models/contact.dart'; import 'signal_ui.dart'; +Contact? _getRepeaterPrefixMatchNearLocation( + List contacts, + int pubkeyFirstByte, { + LatLng? searchPoint, + bool preferFavorites = false, +}) { + final candidates = contacts + .where( + (c) => + c.publicKey.isNotEmpty && + c.publicKey.first == pubkeyFirstByte && + (c.type == advTypeRepeater || c.type == advTypeRoom), + ) + .toList(); + + if (candidates.isEmpty) return null; + + candidates.sort((a, b) { + if (preferFavorites) { + final favA = a.isFavorite ? 1 : 0; + final favB = b.isFavorite ? 1 : 0; + final favCompare = favB.compareTo(favA); + if (favCompare != 0) return favCompare; + } + + final seenCompare = b.lastSeen.compareTo(a.lastSeen); + if (seenCompare != 0) return seenCompare; + + return a.publicKeyHex.compareTo(b.publicKeyHex); + }); + + if (searchPoint == null) { + return candidates.first; + } + + final distance = Distance(); + Contact best = candidates.first; + var bestDistance = double.infinity; + + for (final c in candidates) { + if (c.hasLocation && c.latitude != null && c.longitude != null) { + final d = distance(searchPoint, LatLng(c.latitude!, c.longitude!)); + if (d < bestDistance) { + bestDistance = d; + best = c; + } + } + } + + return best; +} + class SNRUi { final IconData icon; final Color color; @@ -67,6 +120,15 @@ class SNRIndicator extends StatefulWidget { } class _SNRIndicatorState extends State { + bool _isValidSelfLocation(double lat, double lon) { + const double epsilon = 1e-6; + return (lat.abs() > epsilon || lon.abs() > epsilon) && + lat >= -90.0 && + lat <= 90.0 && + lon >= -180.0 && + lon <= 180.0; + } + @override Widget build(BuildContext context) { final directRepeaters = widget.connector.directRepeaters; @@ -166,11 +228,13 @@ class _SNRIndicatorState extends State { final selfLon = widget.connector.selfLongitude; LatLng? selfPoint; - if (selfLat != null && selfLon != null) { + if (selfLat != null && + selfLon != null && + _isValidSelfLocation(selfLat, selfLon)) { selfPoint = LatLng(selfLat, selfLon); } - final contact = getRepeaterPrefixMatchNearLocation( + final contact = _getRepeaterPrefixMatchNearLocation( allContacts, repeater.pubkeyFirstByte, searchPoint: selfPoint,