Fix for DM threading

This commit is contained in:
HarukiToreda 2025-09-22 21:07:52 -04:00
parent 8040bb20b4
commit 4e61016a44
4 changed files with 41 additions and 36 deletions

View File

@ -1446,12 +1446,12 @@ int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
sm.channelIndex = packet->channel; sm.channelIndex = packet->channel;
sm.text = std::string(reinterpret_cast<const char *>(packet->decoded.payload.bytes)); sm.text = std::string(reinterpret_cast<const char *>(packet->decoded.payload.bytes));
// Distinguish between broadcast vs DM to us // Distinguish between broadcast vs DM to peer
if (packet->decoded.dest == NODENUM_BROADCAST) { if (packet->decoded.dest == NODENUM_BROADCAST) {
sm.dest = NODENUM_BROADCAST; sm.dest = NODENUM_BROADCAST;
sm.type = MessageType::BROADCAST; sm.type = MessageType::BROADCAST;
} else { } else {
sm.dest = nodeDB->getNodeNum(); sm.dest = packet->decoded.dest; // peer node, not us
sm.type = MessageType::DM_TO_US; sm.type = MessageType::DM_TO_US;
} }
@ -1461,7 +1461,9 @@ int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
if (sm.type == MessageType::BROADCAST) { if (sm.type == MessageType::BROADCAST) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, sm.channelIndex); graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, sm.channelIndex);
} else if (sm.type == MessageType::DM_TO_US) { } else if (sm.type == MessageType::DM_TO_US) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1, sm.sender); graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1,
sm.dest // use peer node
);
} }
// 🔹 Reset scroll so newest message starts from the top // 🔹 Reset scroll so newest message starts from the top
@ -1532,7 +1534,7 @@ int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
sm.dest = NODENUM_BROADCAST; sm.dest = NODENUM_BROADCAST;
sm.type = MessageType::BROADCAST; sm.type = MessageType::BROADCAST;
} else { } else {
sm.dest = nodeDB->getNodeNum(); // DM to us sm.dest = nodeDB->getNodeNum(); // our node (we are DM target)
sm.type = MessageType::DM_TO_US; sm.type = MessageType::DM_TO_US;
} }
@ -1542,7 +1544,9 @@ int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
if (sm.type == MessageType::BROADCAST) { if (sm.type == MessageType::BROADCAST) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, sm.channelIndex); graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, sm.channelIndex);
} else if (sm.type == MessageType::DM_TO_US) { } else if (sm.type == MessageType::DM_TO_US) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1, sm.sender); graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1,
sm.sender // use peer node
);
} }
// Reset scroll so newest message starts from the top // Reset scroll so newest message starts from the top

View File

@ -444,7 +444,7 @@ void menuHandler::messageViewModeMenu()
labels.push_back("View All"); labels.push_back("View All");
ids.push_back(-2); ids.push_back(-2);
// --- Add channels with live messages --- // Add channels with live messages
for (int ch = 0; ch < 8; ++ch) { for (int ch = 0; ch < 8; ++ch) {
auto msgs = messageStore.getChannelMessages(ch); auto msgs = messageStore.getChannelMessages(ch);
if (!msgs.empty()) { if (!msgs.empty()) {
@ -460,7 +460,7 @@ void menuHandler::messageViewModeMenu()
} }
} }
// --- Add channels from registry --- // Add channels from registry
for (int ch : graphics::MessageRenderer::getSeenChannels()) { for (int ch : graphics::MessageRenderer::getSeenChannels()) {
if (std::find(ids.begin(), ids.end(), 100 + ch) == ids.end()) { if (std::find(ids.begin(), ids.end(), 100 + ch) == ids.end()) {
char buf[40]; char buf[40];
@ -475,39 +475,40 @@ void menuHandler::messageViewModeMenu()
} }
} }
// --- Add DMs from live store --- // Add DMs from live store
auto dms = messageStore.getDirectMessages(); auto dms = messageStore.getDirectMessages();
std::vector<uint32_t> uniqueSenders; std::vector<uint32_t> uniquePeers;
for (auto &m : dms) { for (auto &m : dms) {
if (std::find(uniqueSenders.begin(), uniqueSenders.end(), m.sender) == uniqueSenders.end()) { uint32_t peer = (m.sender == nodeDB->getNodeNum()) ? m.dest : m.sender;
uniqueSenders.push_back(m.sender); if (peer != nodeDB->getNodeNum() && std::find(uniquePeers.begin(), uniquePeers.end(), peer) == uniquePeers.end()) {
uniquePeers.push_back(peer);
} }
} }
// --- Add DMs from registry --- // Add DMs from registry
for (uint32_t peer : graphics::MessageRenderer::getSeenPeers()) { for (uint32_t peer : graphics::MessageRenderer::getSeenPeers()) {
if (std::find(uniqueSenders.begin(), uniqueSenders.end(), peer) == uniqueSenders.end()) { if (peer != nodeDB->getNodeNum() && std::find(uniquePeers.begin(), uniquePeers.end(), peer) == uniquePeers.end()) {
uniqueSenders.push_back(peer); uniquePeers.push_back(peer);
} }
} }
std::sort(uniqueSenders.begin(), uniqueSenders.end()); std::sort(uniquePeers.begin(), uniquePeers.end());
for (auto sender : uniqueSenders) { for (auto peer : uniquePeers) {
auto node = nodeDB->getMeshNode(sender); auto node = nodeDB->getMeshNode(peer);
std::string name; std::string name;
if (node && node->has_user) { if (node && node->has_user) {
name = sanitizeString(node->user.long_name).substr(0, 15); name = sanitizeString(node->user.long_name).substr(0, 15);
} else { } else {
char buf[20]; char buf[20];
snprintf(buf, sizeof(buf), "Node %08X", sender); snprintf(buf, sizeof(buf), "Node %08X", peer);
name = buf; name = buf;
} }
labels.push_back("DM: " + name); labels.push_back("DM: " + name);
ids.push_back(sender); ids.push_back(peer);
} }
// --- Determine active ID --- // Determine active ID
int activeId = -2; int activeId = -2;
auto mode = graphics::MessageRenderer::getThreadMode(); auto mode = graphics::MessageRenderer::getThreadMode();
if (mode == graphics::MessageRenderer::ThreadMode::ALL) { if (mode == graphics::MessageRenderer::ThreadMode::ALL) {

View File

@ -192,12 +192,12 @@ void resetScrollState()
didReset = false; // <-- now valid didReset = false; // <-- now valid
} }
// --- Current thread state --- // Current thread state
static ThreadMode currentMode = ThreadMode::ALL; static ThreadMode currentMode = ThreadMode::ALL;
static int currentChannel = -1; static int currentChannel = -1;
static uint32_t currentPeer = 0; static uint32_t currentPeer = 0;
// --- Registry of seen threads for manual toggle --- // Registry of seen threads for manual toggle
static std::vector<int> seenChannels; static std::vector<int> seenChannels;
static std::vector<uint32_t> seenPeers; static std::vector<uint32_t> seenPeers;
@ -270,7 +270,7 @@ void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
include = true; include = true;
break; break;
case ThreadMode::DIRECT: case ThreadMode::DIRECT:
if (m.type == MessageType::DM_TO_US && m.sender == currentPeer) if (m.type == MessageType::DM_TO_US && (m.sender == currentPeer || m.dest == currentPeer))
include = true; include = true;
break; break;
} }
@ -344,7 +344,7 @@ void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
for (auto it = filtered.rbegin(); it != filtered.rend(); ++it) { for (auto it = filtered.rbegin(); it != filtered.rend(); ++it) {
const auto &m = *it; const auto &m = *it;
// --- Build header line for this message --- // Build header line for this message
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(m.sender); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(m.sender);
const char *sender = "???"; const char *sender = "???";
#if defined(M5STACK_UNITC6L) #if defined(M5STACK_UNITC6L)
@ -408,7 +408,7 @@ void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
isMine.push_back(mine); isMine.push_back(mine);
isHeader.push_back(true); isHeader.push_back(true);
// --- Split message text into wrapped lines --- // Split message text into wrapped lines
std::vector<std::string> wrapped = generateLines(display, "", m.text.c_str(), textWidth); std::vector<std::string> wrapped = generateLines(display, "", m.text.c_str(), textWidth);
for (auto &ln : wrapped) { for (auto &ln : wrapped) {
allLines.push_back(ln); allLines.push_back(ln);

View File

@ -808,7 +808,7 @@ bool CannedMessageModule::handleFreeTextInput(const InputEvent *event)
} }
#endif // USE_VIRTUAL_KEYBOARD #endif // USE_VIRTUAL_KEYBOARD
// ---- All hardware keys fall through to here (CardKB, physical, etc.) ---- // All hardware keys fall through to here (CardKB, physical, etc.)
if (event->kbchar == INPUT_BROKER_MSG_EMOTE_LIST) { if (event->kbchar == INPUT_BROKER_MSG_EMOTE_LIST) {
runState = CANNED_MESSAGE_RUN_STATE_EMOTE_PICKER; runState = CANNED_MESSAGE_RUN_STATE_EMOTE_PICKER;
@ -975,7 +975,7 @@ void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const cha
// Save outgoing message // Save outgoing message
StoredMessage sm; StoredMessage sm;
sm.timestamp = millis() / 1000; sm.timestamp = millis() / 1000;
sm.sender = nodeDB->getNodeNum(); sm.sender = nodeDB->getNodeNum(); // us
sm.channelIndex = channel; sm.channelIndex = channel;
sm.text = std::string(message); sm.text = std::string(message);
@ -1759,7 +1759,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
#endif #endif
#endif #endif
// --- Delivery Status Message --- // Delivery Status Message
if (this->ack) { if (this->ack) {
if (this->lastSentNode == NODENUM_BROADCAST) { if (this->lastSentNode == NODENUM_BROADCAST) {
snprintf(buffer, sizeof(buffer), "Broadcast Sent to\n%s", channels.getName(this->channel)); snprintf(buffer, sizeof(buffer), "Broadcast Sent to\n%s", channels.getName(this->channel));
@ -1787,7 +1787,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
yOffset += lineCount * FONT_HEIGHT_MEDIUM; // only 1 line gap, no extra padding yOffset += lineCount * FONT_HEIGHT_MEDIUM; // only 1 line gap, no extra padding
#endif #endif
#ifndef USE_EINK #ifndef USE_EINK
// --- SNR + RSSI Compact Line --- // SNR + RSSI Compact Line
if (this->ack) { if (this->ack) {
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
#if defined(M5STACK_UNITC6L) #if defined(M5STACK_UNITC6L)
@ -1837,10 +1837,10 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
// --- Draw node/channel header at the top --- // Draw node/channel header at the top
drawHeader(display, x, y, buffer); drawHeader(display, x, y, buffer);
// --- Char count right-aligned --- // Char count right-aligned
if (runState != CANNED_MESSAGE_RUN_STATE_DESTINATION_SELECTION) { if (runState != CANNED_MESSAGE_RUN_STATE_DESTINATION_SELECTION) {
uint16_t charsLeft = uint16_t charsLeft =
meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length() - (moduleConfig.canned_message.send_bell ? 1 : 0); meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length() - (moduleConfig.canned_message.send_bell ? 1 : 0);
@ -1848,7 +1848,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer); display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
} }
// --- Draw Free Text input with multi-emote support and proper line wrapping --- // Draw Free Text input with multi-emote support and proper line wrapping
display->setColor(WHITE); display->setColor(WHITE);
{ {
int inputY = 0 + y + FONT_HEIGHT_SMALL; int inputY = 0 + y + FONT_HEIGHT_SMALL;
@ -2019,7 +2019,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
: 0; : 0;
int countRows = std::min(messagesCount, _visibleRows); int countRows = std::min(messagesCount, _visibleRows);
// --- Build per-row max height based on all emotes in line --- // Build per-row max height based on all emotes in line
for (int i = 0; i < countRows; i++) { for (int i = 0; i < countRows; i++) {
const char *msg = getMessageByIndex(topMsg + i); const char *msg = getMessageByIndex(topMsg + i);
int maxEmoteHeight = 0; int maxEmoteHeight = 0;
@ -2037,7 +2037,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
rowHeights.push_back(std::max(baseRowSpacing, maxEmoteHeight + 2)); rowHeights.push_back(std::max(baseRowSpacing, maxEmoteHeight + 2));
} }
// --- Draw all message rows with multi-emote support --- // Draw all message rows with multi-emote support
int yCursor = listYOffset; int yCursor = listYOffset;
for (int vis = 0; vis < countRows; vis++) { for (int vis = 0; vis < countRows; vis++) {
int msgIdx = topMsg + vis; int msgIdx = topMsg + vis;
@ -2046,7 +2046,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
int rowHeight = rowHeights[vis]; int rowHeight = rowHeights[vis];
bool _highlight = (msgIdx == currentMessageIndex); bool _highlight = (msgIdx == currentMessageIndex);
// --- Multi-emote tokenization --- // Multi-emote tokenization
std::vector<std::pair<bool, String>> tokens; // (isEmote, token) std::vector<std::pair<bool, String>> tokens; // (isEmote, token)
int pos = 0; int pos = 0;
int msgLen = strlen(msg); int msgLen = strlen(msg);
@ -2091,7 +2091,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
} }
} }
} }
// --- End multi-emote tokenization --- // End multi-emote tokenization
// Vertically center based on rowHeight // Vertically center based on rowHeight
int textYOffset = (rowHeight - FONT_HEIGHT_SMALL) / 2; int textYOffset = (rowHeight - FONT_HEIGHT_SMALL) / 2;