fix(meshcore): exclude repeaters from DM peer list; disable send for repeater selection (#3755)#3758
fix(meshcore): exclude repeaters from DM peer list; disable send for repeater selection (#3755)#3758Yeraze wants to merge 1 commit into
Conversation
…repeater selection (#3755) Repeaters (advType=2) cannot receive direct messages, but were included in the DM contact-list sidebar alongside companion nodes. Selecting a repeater via the nodes-view "›" button also left the send bar enabled, producing false "delivered" indicators for messages that were never received. - Exclude advType=2 contacts from the contact-seeded DM peer set, matching the existing room-server (advType=3) exclusion. - Disable the message compose input when the selected DM peer is a repeater, as defence-in-depth for navigation from the nodes view. - Two regression tests: repeater absent from sidebar; send input disabled when repeater is selected via initialSelectedContact. - Expanded makeActions() mock in the DM view test to cover remote-admin actions (getRemoteAdminCapability etc.) so repeater contact-detail panels render cleanly in the JSDOM test environment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TCT8z33322WjjBVSqSXhb5
|
Claude finished @Yeraze's task —— View job PR Review
SummaryThis is a small, focused bug fix that correctly handles repeater nodes ( Code Quality
if (c.publicKey && !isChannelPseudoKey(c.publicKey) && c.advType !== 3 && c.advType !== 2) peers.add(c.publicKey);Minor style note: the line is now quite long. A future reader might appreciate extracting
disabled={!connected || !canSend || contactsByKey.get(selected)?.advType === 2}No issues here. Potential IssuesEdge case: repeater selected via message history — The sidebar exclusion in You may want to apply the same filter after the messages sweep, e.g.: // After building peers from messages, drop repeaters and room servers.
for (const key of Array.from(peers)) {
const c = contactsByKey.get(key);
if (c && (c.advType === 2 || c.advType === 3)) peers.delete(key);
}This is a pre-existing gap for Test CoverageThe two new tests are well-structured:
The expanded One minor gap: there is no test asserting that a repeater arriving via message history (not contacts) is also hidden — but as noted above, that scenario may be considered out of scope for this fix. Security / PerformanceNo security concerns. No performance concerns — the VerdictLooks good to merge. The fix is minimal, correct, and follows the established pattern. The edge-case around repeaters appearing via message history is worth a follow-up issue but is not a regression introduced here. |
…able nodes (#3755) (#3760) * fix(messaging): remove DM UI for MeshCore repeaters & Meshtastic unmessagable nodes (#3755) Repeaters (MeshCore advType=2) and Meshtastic nodes with is_unmessagable set cannot receive direct messages — the firmware acks the relay/packet, which surfaced as a misleading "delivered" (✓✓). Rather than send messages that never arrive, remove the messaging UI for these nodes while keeping them first-class everywhere else: they stay listed in node/contact sidebars and still show full telemetry and other detail. MeshCore (MeshCoreDirectMessagesView): - When the selected contact is a repeater, render the contact detail panel + telemetry as before but drop the MeshCoreMessageStream entirely, replaced by a short "repeaters cannot receive direct messages" notice. - Repeaters remain in the contact sidebar (NOT filtered out). The Nodes view "›" button is already labelled "More details" and now lands on the detail-only pane, so it needs no change. - 4 new render tests: repeater stays in sidebar; composer hidden + notice shown on repeater select; composer still shown for companions; telemetry still mounts for a selected repeater. Meshtastic: - NodesTab: hide the 💬 DM button for is_unmessagable nodes (no DM entry point) — the node stays in the list with all indicators/details. - MessagesTab: reuse the existing read-only mode — effectiveReadOnly = mqttReadOnly || selectedNode.isUnmessagable — so selecting an unmessagable node hides the message log + send composer + mesh-transmit actions and shows only the per-node telemetry, while the node stays selectable in the DM list. Supersedes #3758 (which removed repeaters from the sidebar) and #3759 (which only greyed the send bar with a notice). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JEaCGwY9Wz8jeV4e22GW4 * test(meshcore): stub remote-admin actions so repeater detail panel renders Selecting a repeater mounts the contact-detail panel's remote-admin console, which calls getRemoteAdminCapability() on mount. The DM-view test mock omitted the contact/remote-admin actions (companion contacts never mounted the console), so the new repeater tests threw in CI with "getRemoteAdminCapability is not a function". Add safe vi.fn() stubs for the full contact + remote-admin action set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JEaCGwY9Wz8jeV4e22GW4 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Fixes #3755 — repeaters (
advType=2) cannot receive direct messages, but were showing up in the DM contact sidebar and leaving the send bar enabled. This produced misleading "delivered" indicators for messages that were never actually received.advType=3) exclusion.initialSelectedContact.makeActions()mock in the DM view tests to cover remote-admin actions (getRemoteAdminCapabilityetc.) so repeater contact-detail panels render cleanly in the JSDOM environment.Test plan
mqttBrokerManager.test.ts(unrelated)🤖 Generated with Claude Code
https://claude.ai/code/session_01TCT8z33322WjjBVSqSXhb5
Generated by Claude Code