Skip to content

location aware channel_message_path#307

Merged
zjs81 merged 6 commits into
zjs81:mainfrom
ericszimmermann:ez_location_channel_message_path
Mar 24, 2026
Merged

location aware channel_message_path#307
zjs81 merged 6 commits into
zjs81:mainfrom
ericszimmermann:ez_location_channel_message_path

Conversation

@ericszimmermann

Copy link
Copy Markdown
Contributor

Reimplementation of the location aware channel_message_path trace (after alpha7 release)

It searches for the nearest match for the prefix of the next hop to build the Hop path trace.
I tried more complex search algorithm including a full graph search with custom scoring to try to make a more plausible path. But the Results did not improve much, but with a high cost in calculating time.
An implementation for inspection can be seen at my branch ez_channel_message_path2.

It gets more realistic if a lot of Repeaters are discovered (see for that #298) and the hopLength is small.
But the real solution would be multibyte prefixes. But even than collision could occour (even if very unlikely) where it is better to match to the nearest Prefix instead of the first (mostly oldest) entry in the list.

Copilot AI review requested due to automatic review settings March 17, 2026 21:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reimplements the “location aware” hop trace resolution for channel_message_path by selecting hop contacts based on proximity (when location is available) rather than a simple first-match strategy.

Changes:

  • Update hop-building logic to group repeater/room contacts by 1-byte public key prefix and choose the “best” candidate per hop (location-aware when possible).
  • Change _buildPathHops to take a MeshCoreConnector instead of a precomputed contact list.
  • Update .gitignore to ignore macOS GeneratedPluginRegistrant and normalize the .wrangler entry.

Reviewed changes

Copilot reviewed 1 out of 2 changed files in this pull request and generated 2 comments.

File Description
lib/screens/channel_message_path_screen.dart Implements prefix-candidate grouping + distance-based selection for hop resolution and updates call sites accordingly.
.gitignore Ignores a generated macOS Swift file and fixes .wrangler line formatting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread lib/screens/channel_message_path_screen.dart
Comment thread lib/screens/channel_message_path_screen.dart Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 17, 2026 21:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reimplements the channel message path trace UI to resolve hop prefixes using nearby discovered repeaters/rooms (location-aware matching), aiming for more realistic hop paths after alpha7.

Changes:

  • Update hop resolution to pick the best candidate per prefix using proximity to the previous hop (and/or self location) rather than first/oldest match.
  • Refactor _buildPathHops to take a MeshCoreConnector directly (so it can use self location + allContacts) and remove the old _matchContactForPrefix / _hasValidLocation helpers.
  • Ignore macos/Flutter/GeneratedPluginRegistrant.swift via .gitignore.

Reviewed changes

Copilot reviewed 1 out of 2 changed files in this pull request and generated 2 comments.

File Description
lib/screens/channel_message_path_screen.dart Location-aware hop matching based on nearest candidate per prefix and connector self position.
.gitignore Adds macOS GeneratedPluginRegistrant.swift to ignored files (and normalizes .wrangler line).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +821 to +826
final candidate = candidates[j];
if (!candidate.hasLocation) continue;
final currentDistance = distance(
searchPoint,
LatLng(candidate.latitude!, candidate.longitude!),
);
Comment on lines 856 to 860
LatLng? _resolvePosition(Contact? contact) {
if (contact == null) return null;
if (!_hasValidLocation(contact)) return null;
if (!contact.hasLocation) return null;
return LatLng(contact.latitude!, contact.longitude!);
}
@ericszimmermann ericszimmermann marked this pull request as draft March 17, 2026 22:20
@ericszimmermann ericszimmermann marked this pull request as ready for review March 18, 2026 05:53
Copilot AI review requested due to automatic review settings March 18, 2026 05:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reimplements the channel message hop path trace to be location-aware, aiming to produce more realistic hop sequences by selecting the nearest matching next-hop candidate (by prefix) when location data is available.

Changes:

  • Updates hop resolution to group repeaters/rooms by 1-byte prefix, then pick the nearest candidate (or fall back by recency) while avoiding reusing the same candidate multiple times.
  • Enhances the map UI with hop focusing: tapping a hop centers/zooms the map and highlights the selected hop in the legend list.
  • Updates macOS plugin registration (Path Provider) and adjusts .gitignore.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
lib/screens/channel_message_path_screen.dart Implements location-aware hop matching and adds hop focus/selection behavior on the map screen.
macos/Flutter/GeneratedPluginRegistrant.swift Registers the Path Provider macOS plugin (generated file).
.gitignore Adds the macOS generated plugin registrant to ignored files and fixes .wrangler formatting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread lib/screens/channel_message_path_screen.dart Outdated
Comment thread macos/Flutter/GeneratedPluginRegistrant.swift
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 18, 2026 06:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reimplements the “location-aware” channel message hop-path trace so that prefix collisions are resolved by selecting the nearest plausible repeater/room candidate (using available location data), and adds UI interactions to focus the map on a tapped hop.

Changes:

  • Update hop resolution to group candidates by prefix and pick nearest-by-distance (falling back to most-recent by lastSeen).
  • Add hop focusing/selection behavior in the map view (tap a hop to move/zoom the map and highlight the focused row).
  • macOS plugin registrant updated for path_provider_foundation, and generated registrant is added to .gitignore.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
macos/Flutter/GeneratedPluginRegistrant.swift Registers path_provider_foundation on macOS.
lib/screens/channel_message_path_screen.dart Implements new hop-selection algorithm and hop-to-map focus UI.
.gitignore Ignores macOS GeneratedPluginRegistrant and normalizes .wrangler entry.
Comments suppressed due to low confidence (1)

lib/screens/channel_message_path_screen.dart:316

  • A MapController is created and held for the lifetime of the state, but it is never disposed. Other screens in this repo (e.g. MapCacheScreen) call _mapController.dispose() in dispose(). Please add a dispose() override to dispose the controller to avoid leaking listeners/resources.
  final MapController _mapController = MapController();
  Uint8List? _selectedPath;
  double _pathDistance = 0.0;
  bool _showNodeLabels = true;
  bool _didReceivePositionUpdate = false;
  int? _focusedHopIndex;

  @override
  void initState() {
    super.initState();
    _selectedPath = widget.initialPath;
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread lib/screens/channel_message_path_screen.dart Outdated
Comment on lines 815 to +870
List<_PathHop> _buildPathHops(
Uint8List pathBytes,
List<Contact> contacts,
MeshCoreConnector connector,
AppLocalizations l10n,
) {
if (pathBytes.isEmpty) return const [];
final candidatesByPrefix = <int, List<Contact>>{};
for (final contact in connector.allContacts) {
if (contact.publicKey.isEmpty) continue;
if (contact.type != advTypeRepeater && contact.type != advTypeRoom) {
continue;
}
final prefix = contact.publicKey.first;
candidatesByPrefix.putIfAbsent(prefix, () => <Contact>[]).add(contact);
}
for (final candidates in candidatesByPrefix.values) {
candidates.sort((a, b) => b.lastSeen.compareTo(a.lastSeen));
}
final startPoint =
(connector.selfLatitude != null && connector.selfLongitude != null)
? LatLng(connector.selfLatitude!, connector.selfLongitude!)
: null;
var previousPosition = startPoint;
final distance = Distance();

final hops = <_PathHop>[];
for (var i = 0; i < pathBytes.length; i++) {
final prefix = pathBytes[i];
final contact = _matchContactForPrefix(contacts, prefix);
final searchPoint = i == 0 ? startPoint : previousPosition;
final candidates = candidatesByPrefix[pathBytes[i]];
Contact? contact;
if (candidates != null && candidates.isNotEmpty) {
var bestIndex = 0;
if (searchPoint != null) {
var bestDistance = double.infinity;
for (var j = 0; j < candidates.length; j++) {
final candidate = candidates[j];
if (!candidate.hasLocation ||
candidate.latitude == null ||
candidate.longitude == null) {
continue;
}
final currentDistance = distance(
searchPoint,
LatLng(candidate.latitude!, candidate.longitude!),
);
if (currentDistance < bestDistance) {
bestDistance = currentDistance;
bestIndex = j;
}
}
}
contact = candidates.removeAt(bestIndex);
if (candidates.isEmpty) {
candidatesByPrefix.remove(pathBytes[i]);
}
}
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 18, 2026 07:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reimplements the “location aware” channel_message_path hop trace by selecting, for each hop prefix, the nearest matching discovered repeater/room based on the previous hop (or self) location to produce a more realistic path trace and map visualization.

Changes:

  • Update hop resolution to choose nearest candidate per prefix (distance-based) and avoid reusing the same candidate for repeated prefixes.
  • Add map hop focusing via list-tap (centers/zooms the map on the tapped hop and highlights it).
  • Update macOS plugin registrant for path_provider and add the registrant file to .gitignore.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
lib/screens/channel_message_path_screen.dart Implements nearest-prefix hop matching and adds hop focus/highlight behavior in the map UI.
macos/Flutter/GeneratedPluginRegistrant.swift Adds path_provider_foundation registration (generated file).
.gitignore Attempts to ignore the generated macOS plugin registrant file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +305 to +310
final MapController _mapController = MapController();
Uint8List? _selectedPath;
double _pathDistance = 0.0;
bool _showNodeLabels = true;
bool _didReceivePositionUpdate = false;
int? _focusedHopIndex;
Comment on lines 9 to 25
@@ -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"))
@zjs81 zjs81 merged commit 68eeefa into zjs81:main Mar 24, 2026
9 of 10 checks passed
@ericszimmermann ericszimmermann deleted the ez_location_channel_message_path branch March 24, 2026 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants