feat(meshcore): extend in-tab conversation content filter to MeshCore DMs (#3922)#3935
Conversation
… DMs (#3922) PR #3931 (issue #3922) added an in-tab conversation-list filter that matches message body content, but scoped it to Meshtastic DMs only and excluded MeshCore. This extends the same behavior to the MeshCore Direct Messages view. - Add pure helper getMeshCoreMessageContentMatchKeys() alongside the existing getMessageContentMatchNodeIds() in src/utils/messageContentFilter.ts. It mirrors the MeshCore DM predicate (excludes room_post + channel pseudo-keys, requires a toPublicKey) and accepts optional canonicalize / isChannelKey hooks so match keys line up with the canonicalized peer keys in the DM list. - Wire it into MeshCoreDirectMessagesView's filteredPeers useMemo so the contact-list search also surfaces conversations by what was said, not just the contact name / public key. - Update the search placeholder ("Search contacts…" -> "Search contacts or messages…"), English only (inline default + new en.json key); other locales route through Weblate. - Add Vitest coverage: helper unit tests mirroring messageContentFilter.test.ts plus a DM-view integration test asserting a content match surfaces the right contact. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AphLfgUJWaFNAgU5UXdJ4n
|
Claude finished @Yeraze's task —— View job PR Review — feat(meshcore): extend in-tab conversation content filter to MeshCore DMs (#3922)Summary: This PR extends the Meshtastic DM content filter (from PR #3931) to the MeshCore Direct Messages view, enabling users to search conversations by message body text in addition to contact names/keys. Review Checklist
Code Quality & Best Practices ✅The implementation is clean and well-structured. A few observations:
One minor style note: the
Potential edge case — Potential Bugs 🔍No outright bugs found. One correctness note:
if (isChannelKey(msg.toPublicKey) || isChannelKey(msg.fromPublicKey)) continue;This is correct and matches the Test line 592 ( Performance ✅
Security ✅
Test Coverage ✅Test coverage is thorough: Unit tests (
Integration test (
One gap worth noting: There's no test for the scenario where a contact appears via both content match AND name match simultaneously (double-add to Minor Suggestions (Non-blocking)
VerdictLGTM. The implementation is correct, consistent with the existing Meshtastic DM filter pattern, well-tested, and has no security or performance concerns. The PR description accurately describes the changes and design tradeoffs. The minor items above are cosmetic and non-blocking. |
Summary
Extends the in-tab conversation-list content filter — merged for Meshtastic in PR #3931 (issue #3922) — to the MeshCore Direct Messages view.
Before #3931, the Messages conversation-list filter matched only on the partner's name / node ID. #3931 made the Meshtastic DM filter also match on what was said (message body), but scoped it to the active Meshtastic source and excluded MeshCore. This PR brings the same behavior to MeshCore conversations so filtering the MeshCore DM list by content works the same way.
What changed
getMeshCoreMessageContentMatchKeys()added alongside the existinggetMessageContentMatchNodeIds()insrc/utils/messageContentFilter.ts. It mirrors the MeshCore DM predicate used bydmPeers/filteredinMeshCoreDirectMessagesView(skipsmessageType === 'room_post', skips channel pseudo-keys, requires atoPublicKey) and does a case-insensitive substring match over the in-memory message list. It accepts optionalcanonicalizeandisChannelKeyhooks so the returned match keys align with the canonicalized peer keys the DM list already uses (inbound messages arrive with a short pubkey prefix).MeshCoreDirectMessagesView.tsx: amessageContentMatchKeysuseMemo(passing the view's existingcanonicalize+isChannelPseudoKey) feeds thefilteredPeersfilter, which now also surfaces a peer when a DM body matches — in addition to the existing contact-name / public-key match.minLengthdefault of 2 avoids matching nearly every conversation on a single character (mirrors the Meshtastic helper)."Search contacts…"→"Search contacts or messages…"(English only: inlinedefaultValue+ a newmeshcore.search_contactskey inpublic/locales/en.json). Other locales route through Weblate.Design notes
fromPublicKey/toPublicKey/text/messageTypevsfrom/to/channel/portnum), so rather than force one signature, the helper is a sibling pure function in the same module, keeping both DM predicates faithful to their respective views.Tests
messageContentFilter.test.ts(case-insensitivity, both-parties, substrings, room_post/channel/no-toPublicKey exclusion, empty text, aggregation, prefix canonicalization, customminLength).MeshCoreDirectMessagesViewintegration test asserting a "pizza" body match surfaces the right contact while unrelated peers stay hidden.vite buildsucceeds. Servertscshows only pre-existingTelemetryChart.tsxerrors (byte-identical onorigin/main), none from this change.Extends #3922 / follows up #3931.
🤖 Generated with Claude Code
https://claude.ai/code/session_01AphLfgUJWaFNAgU5UXdJ4n