From 12fb0be2d2b4dfef1b69d78e0d0d0ef7754e2398 Mon Sep 17 00:00:00 2001 From: HarukiToreda Date: Sun, 31 May 2026 16:16:21 -0400 Subject: [PATCH] DM fix --- src/graphics/niche/InkHUD/Events.cpp | 43 ++++++++++-------------- src/graphics/niche/InkHUD/InkHUD.cpp | 8 ++--- src/graphics/niche/InkHUD/docs/README.md | 11 ++++++ 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/graphics/niche/InkHUD/Events.cpp b/src/graphics/niche/InkHUD/Events.cpp index 8a673b8c7..b267bd7e1 100644 --- a/src/graphics/niche/InkHUD/Events.cpp +++ b/src/graphics/niche/InkHUD/Events.cpp @@ -534,32 +534,25 @@ int InkHUD::Events::onReceiveTextMessage(const meshtastic_MeshPacket *packet) if (getFrom(packet) == nodeDB->getNodeNum()) return 0; - // Determine whether the message is broadcast or a DM - // Store this info to prevent confusion after a reboot - // Avoids need to compare timestamps, because of situation where "future" messages block newly received, if time not set - inkhud->persistence->latestMessage.wasBroadcast = isBroadcast(packet->to); + bool isBroadcastMsg = isBroadcast(packet->to); + inkhud->persistence->latestMessage.wasBroadcast = isBroadcastMsg; - // Pick the appropriate variable to store the message in - StoredMessage *storedMessage = inkhud->persistence->latestMessage.wasBroadcast ? &inkhud->persistence->latestMessage.broadcast - : &inkhud->persistence->latestMessage.dm; - - // Store nodenum of the sender - // Applets can use this to fetch user data from nodedb, if they want - storedMessage->sender = packet->from; - - // Store the time (epoch seconds) when message received - storedMessage->timestamp = getValidTime(RTCQuality::RTCQualityDevice, true); // Current RTC time - - // Store the channel - // - (potentially) used to determine whether notification shows - // - (potentially) used to determine which applet to focus - storedMessage->channelIndex = packet->channel; - - // Store the text via the shared pool so getText() works on this StoredMessage - const char *payload = reinterpret_cast(packet->decoded.payload.bytes); - uint16_t payloadLen = packet->decoded.payload.size; - storedMessage->textOffset = MessageStore::storeText(payload, payloadLen); - storedMessage->textLength = payloadLen; + if (!isBroadcastMsg) { + // DMs never pass through ThreadedMessageApplet, so add them to the global store here + // so they survive reboots. Derive the latestMessage cache entry from the stored result. + inkhud->persistence->latestMessage.dm = messageStore.addFromPacket(*packet); + } else { + // Broadcasts are added to the global store by ThreadedMessageApplet::handleReceived(). + // Here we only update the latestMessage cache used by AllMessageApplet / NotificationApplet. + StoredMessage &sm = inkhud->persistence->latestMessage.broadcast; + sm.sender = packet->from; + sm.timestamp = getValidTime(RTCQuality::RTCQualityDevice, true); + sm.channelIndex = packet->channel; + const char *payload = reinterpret_cast(packet->decoded.payload.bytes); + uint16_t payloadLen = packet->decoded.payload.size; + sm.textOffset = MessageStore::storeText(payload, payloadLen); + sm.textLength = payloadLen; + } return 0; // Tell caller to continue notifying other observers. (No reason to abort this event) } diff --git a/src/graphics/niche/InkHUD/InkHUD.cpp b/src/graphics/niche/InkHUD/InkHUD.cpp index 3c323802e..c746c9f2f 100644 --- a/src/graphics/niche/InkHUD/InkHUD.cpp +++ b/src/graphics/niche/InkHUD/InkHUD.cpp @@ -2,10 +2,6 @@ #include "./InkHUD.h" -#include "FSCommon.h" -#include "MessageStore.h" -#include "SPILock.h" -#include "concurrency/LockGuard.h" #include "./Applet.h" #include "./Events.h" #include "./Persistence.h" @@ -13,6 +9,10 @@ #include "./SystemApplet.h" #include "./Tile.h" #include "./WindowManager.h" +#include "FSCommon.h" +#include "MessageStore.h" +#include "SPILock.h" +#include "concurrency/LockGuard.h" using namespace NicheGraphics; diff --git a/src/graphics/niche/InkHUD/docs/README.md b/src/graphics/niche/InkHUD/docs/README.md index 54b4ad426..2ebff37de 100644 --- a/src/graphics/niche/InkHUD/docs/README.md +++ b/src/graphics/niche/InkHUD/docs/README.md @@ -471,6 +471,13 @@ We keep this separate latest-message cache for this purpose, because: - we want to expose both the most recent broadcast and most recent DM independently - applets like `DMApplet` and `NotificationApplet` need quick access without scanning the full message history +#### How messages reach the store + +Broadcasts and DMs take different paths into `messageStore`: + +- **Broadcasts** — `ThreadedMessageApplet::handleReceived()` calls `messageStore.addFromPacket()`. `Events::onReceiveTextMessage()` then updates `latestMessage.broadcast` separately for fast access by `AllMessageApplet` and `NotificationApplet`. +- **DMs** — `ThreadedMessageApplet` skips DMs entirely. `Events::onReceiveTextMessage()` calls `messageStore.addFromPacket()` directly and stores the result in `latestMessage.dm`. + #### Saving / Loading The `LatestMessage` cache is not persisted to its own file. On boot, `InkHUD::begin()` calls `messageStore.loadFromFlash()` first, then `Persistence::loadLatestMessage()` rebuilds the cache by scanning the loaded messages for the most recent broadcast and DM. @@ -580,6 +587,10 @@ Handles events which impact the InkHUD system generally (e.g. shutdown, button p Applets themselves do also listen separately for various events, but for the purpose of gathering information which they would like to display. +#### Text Messages + +`Events::onReceiveTextMessage()` is the central handler for all incoming text messages. It updates the `LatestMessage` cache and, for DMs, also adds the message to `messageStore` (since `ThreadedMessageApplet` only handles broadcasts). See `Persistence::LatestMessage` for details on how the two message types are stored. + #### Buttons Button input is sometimes handled by a system applet. `InkHUD::Events` determines whether the button should be handled by a specific system applet, or should instead trigger a default behavior