Messages from phone show on screen

This commit is contained in:
HarukiToreda 2025-09-25 22:44:23 -04:00
parent 46a8a9a89e
commit dd7a5cf31f
3 changed files with 88 additions and 138 deletions

View File

@ -64,16 +64,6 @@ void MessageStore::addFromPacket(const meshtastic_MeshPacket &packet)
} }
addLiveMessage(sm); addLiveMessage(sm);
// === Auto-switch ONLY if we're currently in ALL-mode ===
using graphics::MessageRenderer::getThreadMode;
if (getThreadMode() == ThreadMode::ALL) {
if (sm.type == MessageType::BROADCAST) {
setThreadMode(ThreadMode::CHANNEL, sm.channelIndex);
} else if (sm.type == MessageType::DM_TO_US) {
setThreadMode(ThreadMode::DIRECT, -1, sm.sender);
}
}
} }
// === Outgoing/manual message === // === Outgoing/manual message ===

View File

@ -1272,11 +1272,8 @@ void Screen::hideCurrentFrame()
{ {
uint8_t currentFrame = ui->getUiState()->currentFrame; uint8_t currentFrame = ui->getUiState()->currentFrame;
bool dismissed = false; bool dismissed = false;
if (currentFrame == framesetInfo.positions.textMessage && devicestate.has_rx_text_message) {
LOG_INFO("Hide Text Message"); if (currentFrame == framesetInfo.positions.waypoint && devicestate.has_rx_waypoint) {
devicestate.has_rx_text_message = false;
memset(&devicestate.rx_text_message, 0, sizeof(devicestate.rx_text_message));
} else if (currentFrame == framesetInfo.positions.waypoint && devicestate.has_rx_waypoint) {
LOG_DEBUG("Hide Waypoint"); LOG_DEBUG("Hide Waypoint");
devicestate.has_rx_waypoint = false; devicestate.has_rx_waypoint = false;
hiddenFrames.waypoint = true; hiddenFrames.waypoint = true;
@ -1292,7 +1289,7 @@ void Screen::hideCurrentFrame()
} }
if (dismissed) { if (dismissed) {
setFrames(FOCUS_DEFAULT); // You could also use FOCUS_PRESERVE setFrames(FOCUS_DEFAULT);
} }
} }
@ -1444,100 +1441,88 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
// Handles when message is received; will jump to text message frame. // Handles when message is received; will jump to text message frame.
int Screen::handleTextMessage(const meshtastic_MeshPacket *packet) int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
{ {
if (showingNormalScreen) { if (!showingNormalScreen)
if (packet->from == 0) { return 0;
// === Outgoing message (likely sent from phone) ===
devicestate.has_rx_text_message = false;
memset(&devicestate.rx_text_message, 0, sizeof(devicestate.rx_text_message));
hiddenFrames.textMessage = true;
hasUnreadMessage = false; // Clear unread state when user replies
setFrames(FOCUS_PRESERVE); // Stay on same frame, silently update frame list // === Build stored message ===
StoredMessage sm;
// === Save our own outgoing message to live RAM === // Always use our local time
StoredMessage sm; uint32_t nowSecs = getValidTime(RTCQuality::RTCQualityDevice, true);
if (nowSecs > 0) {
sm.timestamp = nowSecs;
sm.isBootRelative = false;
} else {
sm.timestamp = millis() / 1000;
sm.isBootRelative = true; // mark for later upgrade
}
// Always use our local time sm.channelIndex = packet->channel;
uint32_t nowSecs = getValidTime(RTCQuality::RTCQualityDevice, true); sm.text = std::string(reinterpret_cast<const char *>(packet->decoded.payload.bytes));
if (nowSecs > 0) {
sm.timestamp = nowSecs;
sm.isBootRelative = false;
} else {
sm.timestamp = millis() / 1000;
sm.isBootRelative = true; // mark for later upgrade
}
sm.sender = nodeDB->getNodeNum(); // us if (packet->from == 0) {
sm.channelIndex = packet->channel; // Outgoing message (sent by us, typically via phone)
sm.text = std::string(reinterpret_cast<const char *>(packet->decoded.payload.bytes)); sm.sender = nodeDB->getNodeNum(); // us
if (packet->decoded.dest == 0 || packet->decoded.dest == NODENUM_BROADCAST) {
// Distinguish between broadcast vs DM to peer // Fix: treat 0 as broadcast, not DM:00000000
if (packet->decoded.dest == NODENUM_BROADCAST) { sm.dest = NODENUM_BROADCAST;
sm.dest = NODENUM_BROADCAST; sm.type = MessageType::BROADCAST;
sm.type = MessageType::BROADCAST;
} else {
sm.dest = packet->decoded.dest; // peer node, not us
sm.type = MessageType::DM_TO_US;
}
messageStore.addLiveMessage(sm); // RAM only (flash updated at shutdown)
// 🔹 Auto-switch thread view
if (sm.type == MessageType::BROADCAST) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, sm.channelIndex);
} else if (sm.type == MessageType::DM_TO_US) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1,
sm.dest // use peer node
);
}
// 🔹 Reset scroll so newest message starts from the top
graphics::MessageRenderer::resetScrollState();
} else { } else {
// === Incoming message === sm.dest = packet->decoded.dest;
devicestate.has_rx_text_message = true; // Needed to include the message frame sm.type = MessageType::DM_TO_US;
hasUnreadMessage = true; // Enables mail icon in the header }
setFrames(FOCUS_PRESERVE); // Refresh frame list without switching view
// Only wake/force display if the configuration allows it } else {
if (shouldWakeOnReceivedMessage()) { // === Incoming message ===
setOn(true); // Wake up the screen first sm.sender = packet->from;
forceDisplay(); // Forces screen redraw if (packet->to == NODENUM_BROADCAST || packet->decoded.dest == NODENUM_BROADCAST) {
sm.dest = NODENUM_BROADCAST;
sm.type = MessageType::BROADCAST;
} else {
sm.dest = nodeDB->getNodeNum(); // our node (we are DM target)
sm.type = MessageType::DM_TO_US;
}
hasUnreadMessage = true; // only incoming triggers mail icon
// Wake/force display if configured
if (shouldWakeOnReceivedMessage()) {
setOn(true);
forceDisplay();
}
// Prepare banner
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(packet->from);
const char *longName = (node && node->has_user) ? node->user.long_name : nullptr;
const char *msgRaw = reinterpret_cast<const char *>(packet->decoded.payload.bytes);
char banner[256];
bool isAlert = false;
for (size_t i = 0; i < packet->decoded.payload.size && i < 100; i++) {
if (msgRaw[i] == '\x07') { // bell
isAlert = true;
break;
} }
}
// === Prepare banner content === if (isAlert) {
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(packet->from); if (longName && longName[0]) {
const char *longName = (node && node->has_user) ? node->user.long_name : nullptr; snprintf(banner, sizeof(banner), "Alert Received from\n%s", longName);
const char *msgRaw = reinterpret_cast<const char *>(packet->decoded.payload.bytes);
char banner[256];
// Check for bell character in message to determine alert type
bool isAlert = false;
for (size_t i = 0; i < packet->decoded.payload.size && i < 100; i++) {
if (msgRaw[i] == '\x07') {
isAlert = true;
break;
}
}
if (isAlert) {
if (longName && longName[0]) {
snprintf(banner, sizeof(banner), "Alert Received from\n%s", longName);
} else {
strcpy(banner, "Alert Received");
}
} else { } else {
if (longName && longName[0]) { strcpy(banner, "Alert Received");
}
} else {
if (longName && longName[0]) {
#if defined(M5STACK_UNITC6L) #if defined(M5STACK_UNITC6L)
strcpy(banner, "New Message"); strcpy(banner, "New Message");
#else #else
snprintf(banner, sizeof(banner), "New Message from\n%s", longName); snprintf(banner, sizeof(banner), "New Message from\n%s", longName);
#endif #endif
} else { } else {
strcpy(banner, "New Message"); strcpy(banner, "New Message");
} }
} }
#if defined(M5STACK_UNITC6L) #if defined(M5STACK_UNITC6L)
screen->setOn(true); screen->setOn(true);
@ -1546,49 +1531,25 @@ int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
#else #else
screen->showSimpleBanner(banner, 3000); screen->showSimpleBanner(banner, 3000);
#endif #endif
// === Save this incoming message to live RAM ===
StoredMessage sm;
// Always use our local time
uint32_t nowSecs = getValidTime(RTCQuality::RTCQualityDevice, true);
if (nowSecs > 0) {
sm.timestamp = nowSecs;
sm.isBootRelative = false;
} else {
sm.timestamp = millis() / 1000;
sm.isBootRelative = true; // mark for later upgrade
}
sm.sender = packet->from;
sm.channelIndex = packet->channel;
sm.text = std::string(reinterpret_cast<const char *>(packet->decoded.payload.bytes));
// Distinguish between broadcast vs DM to us
if (packet->to == NODENUM_BROADCAST || packet->decoded.dest == NODENUM_BROADCAST) {
sm.dest = NODENUM_BROADCAST;
sm.type = MessageType::BROADCAST;
} else {
sm.dest = nodeDB->getNodeNum(); // our node (we are DM target)
sm.type = MessageType::DM_TO_US;
}
messageStore.addLiveMessage(sm); // RAM only (flash updated at shutdown)
// Auto-switch thread view
if (sm.type == MessageType::BROADCAST) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, sm.channelIndex);
} else if (sm.type == MessageType::DM_TO_US) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1,
sm.sender // use peer node
);
}
// Reset scroll so newest message starts from the top
graphics::MessageRenderer::resetScrollState();
}
} }
// Save to store (both outgoing + incoming)
messageStore.addLiveMessage(sm);
// Keep frame set active
setFrames(FOCUS_PRESERVE);
// Auto-switch thread view
if (sm.type == MessageType::BROADCAST) {
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, sm.channelIndex);
} else if (sm.type == MessageType::DM_TO_US) {
uint32_t peer = (packet->from == 0) ? sm.dest : sm.sender;
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1, peer);
}
// Reset scroll so newest message starts from the top
graphics::MessageRenderer::resetScrollState();
return 0; return 0;
} }
@ -1680,7 +1641,7 @@ int Screen::handleInputEvent(const InputEvent *event)
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.lora) { } else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.lora) {
menuHandler::loraMenu(); menuHandler::loraMenu();
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.textMessage) { } else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.textMessage) {
if (devicestate.rx_text_message.from) { if (!messageStore.getMessages().empty()) {
menuHandler::messageResponseMenu(); menuHandler::messageResponseMenu();
} else { } else {
#if defined(M5STACK_UNITC6L) #if defined(M5STACK_UNITC6L)

View File

@ -453,7 +453,6 @@ void menuHandler::messageResponseMenu()
LOG_DEBUG("[ReplyCtx] mode=%d ch=%d peer=0x%08x", (int)mode, ch, (unsigned int)peer); LOG_DEBUG("[ReplyCtx] mode=%d ch=%d peer=0x%08x", (int)mode, ch, (unsigned int)peer);
if (selected == ViewMode) { if (selected == ViewMode) {
LOG_DEBUG("Switching to message_viewmode_menu");
menuHandler::menuQueue = menuHandler::message_viewmode_menu; menuHandler::menuQueue = menuHandler::message_viewmode_menu;
screen->runNow(); screen->runNow();
} else if (selected == DismissAll) { } else if (selected == DismissAll) {