feat: enhance device info display and Messages UI improvements#8
Conversation
…ator - Preload all known nodes in Messages sidebar (similar to Node Info tab) - Improve sorting to prioritize nodes with unread messages, then recent messages, then last seen time - Add "Last seen" timestamp in conversation header - Update sidebar to show total node count instead of just nodes with messages 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Implement firmware version and node name retrieval matching the official Meshtastic web UI approach. Changes: - Switch from ?all=true to ?all=false for fromradio polling - Each request now returns one FromRadio message at a time - Add DeviceMetadata message parsing for full firmware version - Update local node info with names from NodeInfo messages - Add fallback minAppVersion decoder for older firmware Results: - Firmware version now shows full string (e.g., "2.5.7.f77c87d") - Node name displays correctly (e.g., "Yeraze StationG2 🚉") - More reliable message parsing with less complexity 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add frontend components and styling to display firmware version, node information, and system status. Changes: - Add system status modal showing version, uptime, and memory usage - Display node ID, name, and firmware version in Info panel - Add application version display from package.json - Add popup support for selected traceroute lines - Add full-width section styling for telemetry - Add /api/system/status endpoint for server metrics Results: - Connection status shows device firmware version - Clickable connection indicator shows system info - Red traceroute lines show popup on hover - Application version displayed in footer and settings 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add fallback initialization of localNodeInfo from database when MyNodeInfo message isn't received during initial configuration - Remove hop count indicator from Messages tab as it was not working reliably - Add manual Data message decoding in parseIncomingData to ensure reply_id and emoji fields are properly accessible - Improve error logging for firmware version updates This ensures firmware version and node name are consistently available in the Info tab, even when the device doesn't send MyNodeInfo during startup. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job Code Review Complete ✅After thoroughly analyzing this PR, here's my comprehensive feedback: Review Checklist:
✅ Overall Assessment: Excellent ImplementationThis PR demonstrates high-quality code with significant improvements to both device information handling and UI. The implementation is well-structured, follows TypeScript best practices, and includes proper error handling. 🔍 Code Quality HighlightsBackend Changes (meshtasticManager.ts)
Protobuf Service (meshtasticProtobufService.ts)
Frontend Changes (App.tsx)
Styling (App.css)
📋 Detailed Findings✅ Security - No Concerns
✅ Performance - Well Optimized
|
Remove all user-specific hard-coded constants to make the application
work universally for any user's configuration:
- Remove hard-coded nodeNum (2732916556) and nodeId (!a2e4ff4c) from
message sending fallback in server.ts
- Remove user-specific search patterns ("Station", role 0, specific nodeId)
from database fallback initialization
- Simplify to generic fallback: first node with complete longName and shortName
- Make sent message database save conditional on localNodeInfo availability
- Messages will still be saved when they arrive back from mesh network
This addresses PR feedback and ensures the application works for any user
without requiring code modifications.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job Code Review Complete ✅After thoroughly analyzing this PR, here's my comprehensive feedback: Review Checklist:
✅ Overall Assessment: Excellent ImplementationThis PR demonstrates high-quality code with significant improvements to both device information handling and UI. The implementation is well-structured, follows TypeScript best practices, and includes proper error handling. 🔍 Code Quality HighlightsBackend Changes (meshtasticManager.ts)
Protobuf Service (meshtasticProtobufService.ts)
Frontend Changes (App.tsx)
Styling (App.css)
📋 Detailed Findings✅ Security - No Concerns
✅ Performance - Well Optimized
|
- Mark messages played from the delivery-success callback, not at enqueue:
handleCommand returns { responses, playOnDelivery }; a dropped body DM now
leaves the message pending instead of losing it. (Yeraze#1)
- Wire purgeExpired into databaseMaintenanceService so expired rows are
reclaimed daily (purgeExpired returns a count). (Yeraze#2)
- Count the per-recipient cap across the recipient's identity forms via an
injected node resolver, so it can't be bypassed by addressing one node by
several name forms. (Yeraze#3)
- Mailbox bypasses the per-node cooldown (interactive flow). (Yeraze#4)
- inbox play <sender> filter matches !hex/node-num forms too. (Yeraze#5)
- Non-DM commands return [] (no unsolicited DM). (Yeraze#6)
- inbox delete returns the same response for not-yours vs non-existent ids
(no id enumeration). (Yeraze#7)
- Wrap the mailbox dispatch in try/catch like the script branch. (Yeraze#8)
- Remove the command-prefix tolerance: canonical msg/inbox only. (Yeraze#9)
- Use shared nodeIdHex (unsigned coerce) for the mailbox log target. (Yeraze#10)
Docs + tests updated to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Mark messages played from the delivery-success callback, not at enqueue:
handleCommand returns { responses, playOnDelivery }; a dropped body DM now
leaves the message pending instead of losing it. (Yeraze#1)
- Wire purgeExpired into databaseMaintenanceService so expired rows are
reclaimed daily (purgeExpired returns a count). (Yeraze#2)
- Count the per-recipient cap across the recipient's identity forms via an
injected node resolver, so it can't be bypassed by addressing one node by
several name forms. (Yeraze#3)
- Mailbox bypasses the per-node cooldown (interactive flow). (Yeraze#4)
- inbox play <sender> filter matches !hex/node-num forms too. (Yeraze#5)
- Non-DM commands return [] (no unsolicited DM). (Yeraze#6)
- inbox delete returns the same response for not-yours vs non-existent ids
(no id enumeration). (Yeraze#7)
- Wrap the mailbox dispatch in try/catch like the script branch. (Yeraze#8)
- Remove the command-prefix tolerance: canonical msg/inbox only. (Yeraze#9)
- Use shared nodeIdHex (unsigned coerce) for the mailbox log target. (Yeraze#10)
Docs + tests updated to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ore) (#3538) * feat: add Dead Drop / Mailbox auto-responder (async message store) A per-source 'mesh voicemail': a node DMs the radio `msg <name> <text>` and the message is held until the named recipient retrieves it via `inbox` / `inbox play`. Implemented as a new auto-responder responseType ('mailbox'), reusing the existing DM-gating, per-node cooldown, param extraction, and per-source scoping. - DB: dead_drop_messages table (SQLite/PostgreSQL/MySQL) + migration 092 - Repository (Drizzle-only) + DatabaseService.deadDrop accessor - DeadDropService: command brain (store/inbox/play[/sender]/delete/clear, 180-byte cap, per-recipient & per-sender caps, 7-day expiry, batch play) - meshtasticManager: 'mailbox' responseType dispatch branch - UI: 'Mailbox' response type option + guidance in the auto-responder editor - Tests: 34 (migration registry, repository perSource, service) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(dead-drop): add Mailbox option to the Add-Trigger form select The Mailbox response type was only added to the per-trigger edit view (TriggerItem); the separate Add-Trigger form in AutoResponderSection had its own type <select> (Text/HTTP/Script) that was missed, so new mailbox triggers couldn't be created from the UI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(dead-drop): don't require response text to add a Mailbox trigger The Add button's disabled gate required a non-empty response field for all types; Mailbox has no response, so the button stayed greyed out. Exempt mailbox from the response-required check (matches validateResponse). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(dead-drop): accept mailbox responseType in settings save validation The settings-save validator required a non-empty response for every trigger and only allowed text/http/script responseTypes, so saving a Mailbox trigger failed with a generic 400. Exempt mailbox from the response-required check and add it to the responseType allowlist. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(dead-drop): settings-save accepts mailbox triggers without response text Regression coverage for the mailbox responseType in the autoResponderTriggers validator: a mailbox trigger with empty response now saves (200), while non-mailbox empty responses and unknown responseTypes still 400. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(dead-drop): tolerate optional command keyword prefix The mailbox service parsed hardcoded msg/inbox, but a trigger configured with prefixed keywords (e.g. betamsg/betainbox, to coexist with another responder already using msg/inbox) would fire the handler yet fall through to help. Strip an optional non-space prefix from the leading verb so prefixed keywords parse correctly; no-op for plain msg/inbox. Caught by live over-the-air testing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(dead-drop): add Mailbox feature docs + live testing brief - automation.md: Mailbox response type + 'Mailbox (Dead Drop)' section (commands, recipient matching, delivery format, limits, command-prefix coexistence, configuration). - dev-notes/DEAD_DROP_TESTING.md: architecture, automated coverage, and the over-the-air validation results (ALTO MF / ALTO LF / ZN Office). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(dead-drop): register dead_drop_messages in migrate-db table lists The cross-database migrate-db CLI tracks every schema table in TABLE_ORDER / SKIP_TABLES; migrationTables.test.ts fails if a new schema table isn't listed. Add dead_drop_messages to TABLE_ORDER and SOURCE_SCOPED_TABLES (it carries a sourceId, like auto_favorite_targets). Caught by the full Vitest suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(dead-drop): address PR review feedback - Mark messages played from the delivery-success callback, not at enqueue: handleCommand returns { responses, playOnDelivery }; a dropped body DM now leaves the message pending instead of losing it. (#1) - Wire purgeExpired into databaseMaintenanceService so expired rows are reclaimed daily (purgeExpired returns a count). (#2) - Count the per-recipient cap across the recipient's identity forms via an injected node resolver, so it can't be bypassed by addressing one node by several name forms. (#3) - Mailbox bypasses the per-node cooldown (interactive flow). (#4) - inbox play <sender> filter matches !hex/node-num forms too. (#5) - Non-DM commands return [] (no unsolicited DM). (#6) - inbox delete returns the same response for not-yours vs non-existent ids (no id enumeration). (#7) - Wrap the mailbox dispatch in try/catch like the script branch. (#8) - Remove the command-prefix tolerance: canonical msg/inbox only. (#9) - Use shared nodeIdHex (unsigned coerce) for the mailbox log target. (#10) Docs + tests updated to match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(dead-drop): recommend enabling Verify response on the mailbox trigger Played-state is committed from the delivery-success callback; with Verify response off (maxAttempts=1) a single unacked send could mark a voicemail played on transmit. Document enabling Verify response so undelivered bodies resurface. (PR #3538 review follow-up) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: chrisn <chrisn@DebDev1.corp.tlclocal.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Randall Hand <randall.hand@gmail.com>
Summary
This PR enhances device information handling and improves the Messages tab UI with several key features:
Device Information Improvements
Messages Tab Enhancements
System Status
/api/system/statusfor server metricsTechnical Details
Backend Changes:
?all=trueto?all=falsefor sequential message polling (matching official UI)initializeLocalNodeInfoFromDatabase()fallback method with multiple search strategiesparseIncomingData()Frontend Changes:
Test Plan
🤖 Generated with Claude Code