Improvements to path tracing and location handling #297
Conversation
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Pull request overview
This PR refines path tracing/map behavior and location handling across the app, while also centralizing “all contacts” lookup and persisting TCP connection settings.
Changes:
- Introduces
MeshCoreConnector.allContactsand updates multiple screens/widgets to use it instead of manually merging contacts + discovered contacts. - Improves path tracing UI/logic (renamed flags, round-trip handling, target placement) and standardizes contact path display via
Contact.pathBytesForDisplay. - Adds TCP server address/port to settings and persists them on successful TCP connect; adds
noNotifysupport to debug logging.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/widgets/snr_indicator.dart | Uses connector.allContacts for repeater name lookup. |
| lib/widgets/path_selection_dialog.dart | Replaces magic contact-type numbers with protocol constants. |
| lib/widgets/path_management_dialog.dart | Updates renamed path-trace flag and uses allContacts for selection list. |
| lib/utils/app_logger.dart | Adds noNotify passthrough to debug log service. |
| lib/services/app_settings_service.dart | Adds setters for persisted TCP host/port settings. |
| lib/services/app_debug_log_service.dart | Adds noNotify to suppress notifyListeners() on log append. |
| lib/screens/tcp_screen.dart | Initializes host/port from settings and saves them on connect. |
| lib/screens/path_trace_map.dart | Renames flags, tweaks path/marker building, and target placement logic. |
| lib/screens/neighbors_screen.dart | Uses connector.allContacts when parsing neighbors. |
| lib/screens/map_screen.dart | Uses allContacts and simplifies location filtering via Contact.hasLocation. |
| lib/screens/contacts_screen.dart | Switches to pathBytesForDisplay and wires new path-trace flags/target. |
| lib/screens/chat_screen.dart | Updates renamed path-trace flag and uses allContacts for path selection. |
| lib/screens/channel_message_path_screen.dart | Uses allContacts and updates renamed path-trace flags. |
| lib/models/contact.dart | Tightens hasLocation and replaces traceRouteBytes with pathBytesForDisplay. |
| lib/models/app_settings.dart | Adds tcpServerAddress/tcpServerPort to persisted settings model. |
| lib/connector/meshcore_connector.dart | Adds allContacts; updates discovery handling and location update gating. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| flipPathAround: true, | ||
| reversePathAround: | ||
| !(!channelMessage && !message.isOutgoing), | ||
| ), |
| latitude.abs() <= 90 && | ||
| longitude != 0 | ||
| ? latitude | ||
| : existing.latitude, | ||
| longitude: | ||
| hasLocation && | ||
| longitude != null && | ||
| longitude.abs() <= 180 && | ||
| longitude != 0 |
| flags: 0, | ||
| isActive: false, | ||
| isActive: addActive, | ||
| ); | ||
| notifyListeners(); | ||
| unawaited(_persistDiscoveredContacts()); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- 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>
There was a problem hiding this comment.
Pull request overview
This PR improves path tracing and location handling across the app by centralizing “all contacts” selection (known + inactive discovered), refining how trace paths are built/displayed, and persisting TCP connection endpoints in settings.
Changes:
- Introduces
MeshCoreConnector.allContactsand updates multiple screens/widgets to use it instead of manually merging contact lists. - Refactors path tracing UI/logic (rename
flipPathRound→flipPathAround, usepathBytesForDisplay, enhance endpoint placement). - Adds persisted TCP server address/port to
AppSettingsand wiresTcpScreento read/write these values.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/widgets/snr_indicator.dart | Uses centralized connector.allContacts for name resolution. |
| lib/widgets/path_selection_dialog.dart | Replaces magic type numbers with protocol constants for repeaters/rooms. |
| lib/widgets/path_management_dialog.dart | Updates path-trace parameter rename and uses allContacts. |
| lib/utils/app_logger.dart | Adds noNotify plumbing to logger methods. |
| lib/services/app_settings_service.dart | Adds setters for persisted TCP endpoint fields. |
| lib/services/app_debug_log_service.dart | Adds noNotify option to suppress listener notifications for some logs. |
| lib/screens/tcp_screen.dart | Initializes host/port from settings and persists them after successful TCP connect. |
| lib/screens/path_trace_map.dart | Renames flags, changes contact sourcing, adjusts target endpoint inference, and map marker/path building. |
| lib/screens/neighbors_screen.dart | Uses allContacts instead of manual merge. |
| lib/screens/map_screen.dart | Switches contact aggregation to allContacts and simplifies location filtering using hasLocation. |
| lib/screens/contacts_screen.dart | Uses pathBytesForDisplay and new flip/target parameters when opening path trace maps. |
| lib/screens/chat_screen.dart | Updates path-trace flag rename and uses allContacts for selection dialogs. |
| lib/screens/channel_message_path_screen.dart | Updates path-trace flag rename and changes reverse behavior wiring. |
| lib/models/contact.dart | Strengthens hasLocation and introduces pathBytesForDisplay API. |
| lib/models/app_settings.dart | Persists TCP server address/port in settings serialization and copyWith. |
| lib/connector/meshcore_connector.dart | Adds allContacts, updates discovery handling, and tightens location refresh logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| path: primaryPath, | ||
| flipPathRound: true, | ||
| reversePathRound: !message.isOutgoing && !channelMessage, | ||
| flipPathAround: true, | ||
| reversePathAround: | ||
| !(!channelMessage && !message.isOutgoing), | ||
| ), |
| void _handleContact(Uint8List frame, {bool isContact = true}) { | ||
| final contact = Contact.fromFrame(frame); | ||
| if (contact != null) { | ||
| _handleDiscovery(contact, frame, noNotify: true, addActive: true); |
| title: contact.pathLength > 0 | ||
| ? Text(context.l10n.contacts_pathTrace) | ||
| : Text(context.l10n.contacts_ping), | ||
| onTap: () { | ||
| Navigator.push( | ||
| context, | ||
| MaterialPageRoute( | ||
| builder: (context) => PathTraceMapScreen( | ||
| title: contact.pathLength > 0 | ||
| title: contact.pathBytesForDisplay.isNotEmpty | ||
| ? context.l10n.contacts_roomPathTrace | ||
| : context.l10n.contacts_roomPing, | ||
| path: contact.traceRouteBytes ?? Uint8List(0), | ||
| path: contact.pathBytesForDisplay, | ||
| flipPathAround: contact.pathBytesForDisplay.isNotEmpty, | ||
| targetContact: contact, |
| int hopLast = 0; | ||
| int hopLastLast = 0; | ||
| for (final hop in _traceData!.pathData) { | ||
| if (hop == hopLastLast && widget.flipPathAround) { | ||
| break; //skip duplicate hops in round-trip paths | ||
| } |
| text: context.read<AppSettingsService>().settings.tcpServerAddress, | ||
| ); | ||
| _portController = TextEditingController( | ||
| text: context.read<AppSettingsService>().settings.tcpServerPort > 0 | ||
| ? context.read<AppSettingsService>().settings.tcpServerPort.toString() | ||
| : '', | ||
| ); |
| ? pathData[(pathData.length - 1) ~/ 2] | ||
| : pathData.last; | ||
| final peers = connector.contacts | ||
| // For a round-trip path (flipPathAround/reversePathAround), the target-side hop |
| latitude: | ||
| hasLocation && | ||
| latitude != null && | ||
| latitude.abs() <= 90 && | ||
| (latitude != 0 || longitude != 0) | ||
| ? latitude | ||
| : existing.latitude, | ||
| longitude: | ||
| hasLocation && | ||
| longitude != null && | ||
| longitude.abs() <= 180 && | ||
| (latitude != 0 || longitude != 0) | ||
| ? longitude | ||
| : existing.longitude, |
| final markers = <Marker>[]; | ||
| int hopLast = 0; | ||
| int hopLastLast = 0; | ||
| for (final hop in pathData) { | ||
| final contact = _traceData!.pathContacts[hop]; | ||
| final inferred = _inferredHopPositions[hop]; | ||
| final hasGps = contact != null && contact.hasLocation; | ||
| if (!hasGps && inferred == null) continue; | ||
| if (hop == hopLastLast && widget.flipPathAround) { | ||
| continue; //skip duplicate hops in round-trip paths |
| final angle = (tc.publicKey[1] / 255.0) * 2 * pi; | ||
| targetPos = LatLng( | ||
| contact.latitude! + offsetDeg * cos(angle), | ||
| contact.longitude! + offsetDeg * sin(angle), | ||
| ); | ||
| targetGuessed = true; | ||
| } |
- Fix operator precedence bug in _handleAutoAddConfig where `flags & flag != 0` was parsed as `flags & (flag != 0)`, always checking bit 0 instead of the correct flag bit - Populate _contacts from cache in loadContactCache() so contacts persist across app restarts - Toggle DTR low→high on USB connect to force device to see a fresh connection - Add 10ms inter-frame delay for USB sends to prevent missed responses - Deassert DTR before closing USB port on disconnect/dispose Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Improvements to path tracing and location handling.