Files
Meshtastic-Android/feature/node
James RichandClaude Sonnet 5 59fc12b4a8 fix(node): stop rendering saved-on-phone nodes as freshly heard
Root-caused via #6682/#6693: Node.hopsAway defaults to the sentinel -1
instead of null, and nothing distinguished a locally-retained node from
one the connected radio just reported this session. Together that made
a legitimately cached row (multi-radio use, or a radio with a smaller
NodeDB than the phone) render as if it were freshly heard with 0 hops,
0 SNR, 0 RSSI.

- Add Node.hopsAwayOrNull, extending the existing snrOrNull/rssiOrNull
  pattern, and fix both copies of getRelayNode (the live one in
  Packet.kt and the unused one in Node.kt) whose plain
  minByOrNull { it.hopsAway } let the unresolved -1 sentinel look
  closer than a real hop count.
- Track the current connection session's exact NodeDB membership via
  NodeManager.currentSessionNodeNums, published right after each Stage
  2 handshake and reconciled against the same generation-race window
  already used for connectionIdentity.
- Add a "Saved on phone" badge (node list rows + detail screen) for any
  node retained locally but absent from that snapshot, and stop those
  rows from claiming "online" from a cached, no-longer-current
  lastHeard (list rows, a11y description).

New/updated tests across core:model, core:data, core:ui, core:database
and feature:node; screenshot goldens regenerated for the new "Saved on
phone" previews. Full baseline
(spotlessApply/spotlessCheck/detekt/assembleDebug/test/allTests) and
:screenshot-tests:validateDebugScreenshotTest are green.

Fixes #6263

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 18:31:45 -05:00
..

:feature:node

Overview

Targets: Android · JVM (Desktop) · iOS

The :feature:node module handles node-centric features, including the node list, detailed node information, telemetry charts, and the compass.

Key Components

1. NodeListScreen

Displays all nodes currently known to the application.

2. NodeDetailScreen

Shows exhaustive details for a specific node, including hardware info, position history, and last heard status.

3. MetricsViewModel

Manages the retrieval and display of telemetry data (e.g., battery, SNR, environment metrics) using charts.

4. CompassViewModel

Provides a compass interface to show the relative direction and distance to other nodes.

Dependency Graph

graph TB
  :feature:node[node]:::kmp-feature
  :feature:node -.-> :core:common
  :feature:node -.-> :core:data
  :feature:node -.-> :core:database
  :feature:node -.-> :core:datastore
  :feature:node -.-> :core:domain
  :feature:node -.-> :core:model
  :feature:node -.-> :core:navigation
  :feature:node -.-> :core:repository
  :feature:node -.-> :core:resources
  :feature:node -.-> :core:service
  :feature:node -.-> :core:ui
  :feature:node -.-> :core:di
  :feature:node -.-> :feature:map
  :feature:node -.-> :core:testing

classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef compose-desktop-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-library-compose fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library-compose fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;