fix(meshcore): block DMs to repeaters with explanatory notice (#3755)#3759
fix(meshcore): block DMs to repeaters with explanatory notice (#3755)#3759Yeraze wants to merge 1 commit into
Conversation
Repeaters (advType=2) cannot receive direct messages, but the DM view offered a full send bar anyway and showed false "delivered" (✓✓) status when the firmware acknowledged the packet. Now when the selected contact is a repeater, the send bar is replaced with a read-only notice: "Repeaters cannot receive direct messages." Historical messages remain visible. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H3wti3yXS1pcga9NEsg1sM
|
Claude finished @Yeraze's task —— View job PR Review: fix(meshcore): block DMs to repeaters with explanatory notice (#3755)Tasks:
SummaryThis is a clean, well-scoped fix. The approach — replacing the send bar with an informational notice rather than disabling it or hiding the conversation — is the right UX choice. The implementation is minimal and doesn't regress existing behavior. A few observations below. Code Quality
const isRepeater = (selectedContact?.advType ?? 0) === 2;The magic number import { MeshCoreDeviceType } from '...';
const isRepeater = selectedContact?.advType === MeshCoreDeviceType.REPEATER;
readOnlyNotice={isRepeater
? t('meshcore.repeater_no_dm', 'Repeaters cannot receive direct messages.')
: undefined}Passing Potential IssuesRoom servers ( Historical messages remain visible for repeaters — this is called out in the PR description and is intentional. It's the right decision. Test Coverage GapThe PR description claims "15 targeted tests pass (
The "15 tests" appear to be pre-existing tests that continue to pass, not new tests covering this feature. The following test cases are missing:
CSS
VerdictThe logic is correct and the UX improvement is real. The only actionable feedback is:
|
…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 — MeshCore repeaters (
advType=2) cannot receive direct messages, but the DM view offered a full send bar and showed a false "delivered" (✓✓) status when the firmware acknowledged the relay packet.MeshCoreMessageStream: add optionalreadOnlyNoticeprop — when set, the send bar is replaced with a styled notice div (italic, muted, same bar height). No behaviour change when prop is absent.MeshCoreDirectMessagesView: detect when the selected contact is a repeater (advType === 2) and passreadOnlyNotice="Repeaters cannot receive direct messages."to the stream.MeshCorePage.css: add.meshcore-readonly-noticerule matching the send-bar dimensions and colour.Historical messages (if any) remain visible; only the ability to send new ones is removed.
Test plan
MeshCoreDirectMessagesView.test.tsx+MeshCoreMessageStream.test.tsx)mqttBrokerManager.test.ts(unrelated)🤖 Generated with Claude Code
https://claude.ai/code/session_01H3wti3yXS1pcga9NEsg1sM
Generated by Claude Code