mirror of
https://github.com/meshtastic/firmware.git
synced 2025-10-28 07:13:25 +00:00
Fix for DM threading
This commit is contained in:
parent
8040bb20b4
commit
4e61016a44
@ -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
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user