From 3664ae34cd32e9cf89b6474f277db33420c7132e Mon Sep 17 00:00:00 2001 From: ericz Date: Sun, 15 Mar 2026 11:42:46 +0100 Subject: [PATCH] reimplement location aware snr-indikator after alpha7 --- lib/utils/contact_search.dart | 55 +++++++++++++++++++ lib/widgets/snr_indicator.dart | 24 ++++++-- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/lib/utils/contact_search.dart b/lib/utils/contact_search.dart index 7a82c53..8aa75b0 100644 --- a/lib/utils/contact_search.dart +++ b/lib/utils/contact_search.dart @@ -1,3 +1,6 @@ +import 'package:latlong2/latlong.dart'; + +import '../connector/meshcore_protocol.dart'; import '../models/contact.dart'; export 'contact_filter_types.dart'; @@ -43,3 +46,55 @@ 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) { + 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 30956e2..cf3c275 100644 --- a/lib/widgets/snr_indicator.dart +++ b/lib/widgets/snr_indicator.dart @@ -1,5 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:latlong2/latlong.dart'; + import '../connector/meshcore_connector.dart'; +import '../utils/contact_search.dart'; import '../l10n/l10n.dart'; import 'signal_ui.dart'; @@ -158,10 +161,23 @@ class _SNRIndicatorState extends State { widget.connector.currentSf, ); final allContacts = widget.connector.allContacts; - final name = allContacts - .where((c) => c.publicKey.first == repeater.pubkeyFirstByte) - .map((c) => c.name) - .firstOrNull; + + final selfLat = widget.connector.selfLatitude; + final selfLon = widget.connector.selfLongitude; + + LatLng? selfPoint; + if (selfLat != null && selfLon != null) { + selfPoint = LatLng(selfLat, selfLon); + } + + final contact = getRepeaterPrefixMatchNearLocation( + allContacts, + repeater.pubkeyFirstByte, + searchPoint: selfPoint, + preferFavorites: true, + ); + + final name = contact?.name; return Column( children: [ diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index d2ea57e..4084d9b 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import flutter_blue_plus_darwin import flutter_local_notifications import mobile_scanner import package_info_plus +import path_provider_foundation import share_plus import shared_preferences_foundation import sqflite_darwin @@ -20,6 +21,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))