mirror of
https://github.com/meshtastic/firmware.git
synced 2025-10-29 15:46:46 +00:00
Reply in thread feature
This commit is contained in:
parent
3780290581
commit
ea7638b4ec
@ -65,11 +65,14 @@ void MessageStore::addFromPacket(const meshtastic_MeshPacket &packet)
|
|||||||
|
|
||||||
addLiveMessage(sm);
|
addLiveMessage(sm);
|
||||||
|
|
||||||
// === Auto-switch thread view on new message ===
|
// === Auto-switch ONLY if we're currently in ALL-mode ===
|
||||||
if (sm.type == MessageType::BROADCAST) {
|
using graphics::MessageRenderer::getThreadMode;
|
||||||
setThreadMode(ThreadMode::CHANNEL, sm.channelIndex);
|
if (getThreadMode() == ThreadMode::ALL) {
|
||||||
} else if (sm.type == MessageType::DM_TO_US) {
|
if (sm.type == MessageType::BROADCAST) {
|
||||||
setThreadMode(ThreadMode::DIRECT, -1, sm.sender);
|
setThreadMode(ThreadMode::CHANNEL, sm.channelIndex);
|
||||||
|
} else if (sm.type == MessageType::DM_TO_US) {
|
||||||
|
setThreadMode(ThreadMode::DIRECT, -1, sm.sender);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -396,6 +396,13 @@ void menuHandler::messageResponseMenu()
|
|||||||
bannerOptions.optionsCount = options;
|
bannerOptions.optionsCount = options;
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
LOG_DEBUG("messageResponseMenu: selected %d", selected);
|
LOG_DEBUG("messageResponseMenu: selected %d", selected);
|
||||||
|
|
||||||
|
auto mode = graphics::MessageRenderer::getThreadMode();
|
||||||
|
int ch = graphics::MessageRenderer::getThreadChannel();
|
||||||
|
uint32_t peer = graphics::MessageRenderer::getThreadPeer();
|
||||||
|
|
||||||
|
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");
|
LOG_DEBUG("Switching to message_viewmode_menu");
|
||||||
menuHandler::menuQueue = menuHandler::message_viewmode_menu;
|
menuHandler::menuQueue = menuHandler::message_viewmode_menu;
|
||||||
@ -404,17 +411,33 @@ void menuHandler::messageResponseMenu()
|
|||||||
messageStore.clearAllMessages();
|
messageStore.clearAllMessages();
|
||||||
} else if (selected == DismissOldest) {
|
} else if (selected == DismissOldest) {
|
||||||
messageStore.dismissOldestMessage();
|
messageStore.dismissOldestMessage();
|
||||||
} else if (selected == Preset) {
|
} else if (selected == Preset || selected == Freetext) {
|
||||||
if (devicestate.rx_text_message.to == NODENUM_BROADCAST) {
|
if (mode == graphics::MessageRenderer::ThreadMode::CHANNEL) {
|
||||||
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST, devicestate.rx_text_message.channel);
|
LOG_DEBUG("Replying to CHANNEL %d", ch);
|
||||||
|
if (selected == Preset)
|
||||||
|
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST, ch);
|
||||||
|
else
|
||||||
|
cannedMessageModule->LaunchFreetextWithDestination(NODENUM_BROADCAST, ch);
|
||||||
|
} else if (mode == graphics::MessageRenderer::ThreadMode::DIRECT) {
|
||||||
|
LOG_DEBUG("Replying to DIRECT peer=0x%08x", peer);
|
||||||
|
if (selected == Preset)
|
||||||
|
cannedMessageModule->LaunchWithDestination(peer);
|
||||||
|
else
|
||||||
|
cannedMessageModule->LaunchFreetextWithDestination(peer);
|
||||||
} else {
|
} else {
|
||||||
cannedMessageModule->LaunchWithDestination(devicestate.rx_text_message.from);
|
LOG_DEBUG("Fallback reply using last rx_text_message");
|
||||||
}
|
if (devicestate.rx_text_message.to == NODENUM_BROADCAST) {
|
||||||
} else if (selected == Freetext) {
|
if (selected == Preset)
|
||||||
if (devicestate.rx_text_message.to == NODENUM_BROADCAST) {
|
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST, devicestate.rx_text_message.channel);
|
||||||
cannedMessageModule->LaunchFreetextWithDestination(NODENUM_BROADCAST, devicestate.rx_text_message.channel);
|
else
|
||||||
} else {
|
cannedMessageModule->LaunchFreetextWithDestination(NODENUM_BROADCAST,
|
||||||
cannedMessageModule->LaunchFreetextWithDestination(devicestate.rx_text_message.from);
|
devicestate.rx_text_message.channel);
|
||||||
|
} else {
|
||||||
|
if (selected == Preset)
|
||||||
|
cannedMessageModule->LaunchWithDestination(devicestate.rx_text_message.from);
|
||||||
|
else
|
||||||
|
cannedMessageModule->LaunchFreetextWithDestination(devicestate.rx_text_message.from);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef HAS_I2S
|
#ifdef HAS_I2S
|
||||||
} else if (selected == Aloud) {
|
} else if (selected == Aloud) {
|
||||||
@ -429,97 +452,103 @@ void menuHandler::messageResponseMenu()
|
|||||||
|
|
||||||
void menuHandler::messageViewModeMenu()
|
void menuHandler::messageViewModeMenu()
|
||||||
{
|
{
|
||||||
// Collect menu entries
|
auto encodeChannelId = [](int ch) -> int { return 100 + ch; };
|
||||||
|
auto isChannelSel = [](int id) -> bool { return id >= 100 && id < 200; };
|
||||||
|
|
||||||
static std::vector<std::string> labels;
|
static std::vector<std::string> labels;
|
||||||
static std::vector<int> ids;
|
static std::vector<int> ids;
|
||||||
|
static std::vector<uint32_t> idToPeer; // DM lookup
|
||||||
|
|
||||||
labels.clear();
|
labels.clear();
|
||||||
ids.clear();
|
ids.clear();
|
||||||
|
idToPeer.clear();
|
||||||
|
|
||||||
// Back
|
|
||||||
labels.push_back("Back");
|
labels.push_back("Back");
|
||||||
ids.push_back(-1);
|
ids.push_back(-1);
|
||||||
|
|
||||||
// View All
|
|
||||||
labels.push_back("View All");
|
labels.push_back("View All");
|
||||||
ids.push_back(-2);
|
ids.push_back(-2);
|
||||||
|
|
||||||
// Add channels with live messages
|
// Channels with messages
|
||||||
for (int ch = 0; ch < 8; ++ch) {
|
for (int ch = 0; ch < 8; ++ch) {
|
||||||
auto msgs = messageStore.getChannelMessages(ch);
|
auto msgs = messageStore.getChannelMessages((uint8_t)ch);
|
||||||
if (!msgs.empty()) {
|
if (!msgs.empty()) {
|
||||||
char buf[40];
|
char buf[40];
|
||||||
const char *cname = channels.getName(ch);
|
const char *cname = channels.getName(ch);
|
||||||
if (cname && cname[0]) {
|
snprintf(buf, sizeof(buf), cname && cname[0] ? "#%s" : "#Ch%d", cname ? cname : "", ch);
|
||||||
snprintf(buf, sizeof(buf), "#%s", cname);
|
|
||||||
} else {
|
|
||||||
snprintf(buf, sizeof(buf), "#Ch%d", ch);
|
|
||||||
}
|
|
||||||
labels.push_back(buf);
|
labels.push_back(buf);
|
||||||
ids.push_back(100 + ch);
|
ids.push_back(encodeChannelId(ch));
|
||||||
|
LOG_DEBUG("messageViewModeMenu: Added live channel %s (id=%d)", buf, encodeChannelId(ch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add channels from registry
|
// Registry channels
|
||||||
for (int ch : graphics::MessageRenderer::getSeenChannels()) {
|
for (int ch : graphics::MessageRenderer::getSeenChannels()) {
|
||||||
if (std::find(ids.begin(), ids.end(), 100 + ch) == ids.end()) {
|
if (ch < 0 || ch >= 8)
|
||||||
|
continue;
|
||||||
|
auto msgs = messageStore.getChannelMessages((uint8_t)ch);
|
||||||
|
if (msgs.empty())
|
||||||
|
continue;
|
||||||
|
int enc = encodeChannelId(ch);
|
||||||
|
if (std::find(ids.begin(), ids.end(), enc) == ids.end()) {
|
||||||
char buf[40];
|
char buf[40];
|
||||||
const char *cname = channels.getName(ch);
|
const char *cname = channels.getName(ch);
|
||||||
if (cname && cname[0]) {
|
snprintf(buf, sizeof(buf), cname && cname[0] ? "#%s" : "#Ch%d", cname ? cname : "", ch);
|
||||||
snprintf(buf, sizeof(buf), "#%s", cname);
|
|
||||||
} else {
|
|
||||||
snprintf(buf, sizeof(buf), "#Ch%d", ch);
|
|
||||||
}
|
|
||||||
labels.push_back(buf);
|
labels.push_back(buf);
|
||||||
ids.push_back(100 + ch);
|
ids.push_back(enc);
|
||||||
|
LOG_DEBUG("messageViewModeMenu: Added registry channel %s (id=%d)", buf, enc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add DMs from live store
|
// Gather unique peers
|
||||||
auto dms = messageStore.getDirectMessages();
|
auto dms = messageStore.getDirectMessages();
|
||||||
std::vector<uint32_t> uniquePeers;
|
std::vector<uint32_t> uniquePeers;
|
||||||
for (auto &m : dms) {
|
for (auto &m : dms) {
|
||||||
uint32_t peer = (m.sender == nodeDB->getNodeNum()) ? m.dest : m.sender;
|
uint32_t peer = (m.sender == nodeDB->getNodeNum()) ? m.dest : m.sender;
|
||||||
if (peer != nodeDB->getNodeNum() && std::find(uniquePeers.begin(), uniquePeers.end(), peer) == uniquePeers.end()) {
|
if (peer != nodeDB->getNodeNum() && std::find(uniquePeers.begin(), uniquePeers.end(), peer) == uniquePeers.end())
|
||||||
uniquePeers.push_back(peer);
|
uniquePeers.push_back(peer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add DMs from registry
|
|
||||||
for (uint32_t peer : graphics::MessageRenderer::getSeenPeers()) {
|
for (uint32_t peer : graphics::MessageRenderer::getSeenPeers()) {
|
||||||
if (peer != nodeDB->getNodeNum() && std::find(uniquePeers.begin(), uniquePeers.end(), peer) == uniquePeers.end()) {
|
if (peer != nodeDB->getNodeNum() && std::find(uniquePeers.begin(), uniquePeers.end(), peer) == uniquePeers.end())
|
||||||
uniquePeers.push_back(peer);
|
uniquePeers.push_back(peer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(uniquePeers.begin(), uniquePeers.end());
|
std::sort(uniquePeers.begin(), uniquePeers.end());
|
||||||
|
|
||||||
for (auto peer : uniquePeers) {
|
// Encode peers
|
||||||
|
for (size_t i = 0; i < uniquePeers.size(); ++i) {
|
||||||
|
uint32_t peer = uniquePeers[i];
|
||||||
auto node = nodeDB->getMeshNode(peer);
|
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", peer);
|
snprintf(buf, sizeof(buf), "Node %08X", peer);
|
||||||
name = buf;
|
name = buf;
|
||||||
}
|
}
|
||||||
labels.push_back("DM: " + name);
|
labels.push_back("DM: " + name);
|
||||||
ids.push_back(peer);
|
int encPeer = 1000 + (int)idToPeer.size();
|
||||||
|
ids.push_back(encPeer);
|
||||||
|
idToPeer.push_back(peer);
|
||||||
|
LOG_DEBUG("messageViewModeMenu: Added DM %s peer=0x%08x id=%d", name.c_str(), (unsigned int)peer, encPeer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine active ID
|
// 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::CHANNEL)
|
||||||
activeId = -2;
|
activeId = encodeChannelId(graphics::MessageRenderer::getThreadChannel());
|
||||||
} else if (mode == graphics::MessageRenderer::ThreadMode::CHANNEL) {
|
else if (mode == graphics::MessageRenderer::ThreadMode::DIRECT) {
|
||||||
activeId = 100 + graphics::MessageRenderer::getThreadChannel();
|
uint32_t cur = graphics::MessageRenderer::getThreadPeer();
|
||||||
} else if (mode == graphics::MessageRenderer::ThreadMode::DIRECT) {
|
for (size_t i = 0; i < idToPeer.size(); ++i)
|
||||||
activeId = (int)graphics::MessageRenderer::getThreadPeer();
|
if (idToPeer[i] == cur) {
|
||||||
|
activeId = 1000 + (int)i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare arrays for banner
|
LOG_DEBUG("messageViewModeMenu: Active thread id=%d", activeId);
|
||||||
|
|
||||||
|
// Build banner
|
||||||
static std::vector<const char *> options;
|
static std::vector<const char *> options;
|
||||||
static std::vector<int> optionIds;
|
static std::vector<int> optionIds;
|
||||||
options.clear();
|
options.clear();
|
||||||
@ -529,9 +558,8 @@ void menuHandler::messageViewModeMenu()
|
|||||||
for (size_t i = 0; i < labels.size(); i++) {
|
for (size_t i = 0; i < labels.size(); i++) {
|
||||||
options.push_back(labels[i].c_str());
|
options.push_back(labels[i].c_str());
|
||||||
optionIds.push_back(ids[i]);
|
optionIds.push_back(ids[i]);
|
||||||
if (ids[i] == activeId) {
|
if (ids[i] == activeId)
|
||||||
initialIndex = i;
|
initialIndex = (int)i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BannerOverlayOptions bannerOptions;
|
BannerOverlayOptions bannerOptions;
|
||||||
@ -541,20 +569,24 @@ void menuHandler::messageViewModeMenu()
|
|||||||
bannerOptions.optionsCount = options.size();
|
bannerOptions.optionsCount = options.size();
|
||||||
bannerOptions.InitialSelected = initialIndex;
|
bannerOptions.InitialSelected = initialIndex;
|
||||||
|
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
bannerOptions.bannerCallback = [=](int selected) -> void {
|
||||||
|
LOG_DEBUG("messageViewModeMenu: selected=%d", selected);
|
||||||
if (selected == -1) {
|
if (selected == -1) {
|
||||||
menuHandler::menuQueue = menuHandler::message_response_menu;
|
menuHandler::menuQueue = menuHandler::message_response_menu;
|
||||||
screen->runNow();
|
screen->runNow();
|
||||||
} else if (selected == -2) {
|
} else if (selected == -2) {
|
||||||
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::ALL);
|
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::ALL);
|
||||||
} else if (selected >= 100) {
|
} else if (isChannelSel(selected)) {
|
||||||
int ch = selected - 100;
|
int ch = selected - 100;
|
||||||
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, ch);
|
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::CHANNEL, ch);
|
||||||
} else {
|
} else if (selected >= 1000) {
|
||||||
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1, selected);
|
int idx = selected - 1000;
|
||||||
|
if (idx >= 0 && (size_t)idx < idToPeer.size()) {
|
||||||
|
uint32_t peer = idToPeer[idx];
|
||||||
|
graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1, peer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
screen->showOverlayBanner(bannerOptions);
|
screen->showOverlayBanner(bannerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -199,9 +199,18 @@ static uint32_t currentPeer = 0;
|
|||||||
static std::vector<int> seenChannels;
|
static std::vector<int> seenChannels;
|
||||||
static std::vector<uint32_t> seenPeers;
|
static std::vector<uint32_t> seenPeers;
|
||||||
|
|
||||||
|
// Public helper so menus / store can clear stale registries
|
||||||
|
void clearThreadRegistries()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("[MessageRenderer] Clearing thread registries (seenChannels/seenPeers)");
|
||||||
|
seenChannels.clear();
|
||||||
|
seenPeers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Setter so other code can switch threads
|
// Setter so other code can switch threads
|
||||||
void setThreadMode(ThreadMode mode, int channel /* = -1 */, uint32_t peer /* = 0 */)
|
void setThreadMode(ThreadMode mode, int channel /* = -1 */, uint32_t peer /* = 0 */)
|
||||||
{
|
{
|
||||||
|
LOG_DEBUG("[MessageRenderer] setThreadMode(mode=%d, ch=%d, peer=0x%08x)", (int)mode, channel, (unsigned int)peer);
|
||||||
currentMode = mode;
|
currentMode = mode;
|
||||||
currentChannel = channel;
|
currentChannel = channel;
|
||||||
currentPeer = peer;
|
currentPeer = peer;
|
||||||
@ -209,14 +218,18 @@ void setThreadMode(ThreadMode mode, int channel /* = -1 */, uint32_t peer /* = 0
|
|||||||
|
|
||||||
// Track channels we’ve seen
|
// Track channels we’ve seen
|
||||||
if (mode == ThreadMode::CHANNEL && channel >= 0) {
|
if (mode == ThreadMode::CHANNEL && channel >= 0) {
|
||||||
if (std::find(seenChannels.begin(), seenChannels.end(), channel) == seenChannels.end())
|
if (std::find(seenChannels.begin(), seenChannels.end(), channel) == seenChannels.end()) {
|
||||||
|
LOG_DEBUG("[MessageRenderer] Track seen channel: %d", channel);
|
||||||
seenChannels.push_back(channel);
|
seenChannels.push_back(channel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track DMs we’ve seen
|
// Track DMs we’ve seen
|
||||||
if (mode == ThreadMode::DIRECT && peer != 0) {
|
if (mode == ThreadMode::DIRECT && peer != 0) {
|
||||||
if (std::find(seenPeers.begin(), seenPeers.end(), peer) == seenPeers.end())
|
if (std::find(seenPeers.begin(), seenPeers.end(), peer) == seenPeers.end()) {
|
||||||
|
LOG_DEBUG("[MessageRenderer] Track seen peer: 0x%08x", (unsigned int)peer);
|
||||||
seenPeers.push_back(peer);
|
seenPeers.push_back(peer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,8 @@ uint32_t getThreadPeer();
|
|||||||
const std::vector<int> &getSeenChannels();
|
const std::vector<int> &getSeenChannels();
|
||||||
const std::vector<uint32_t> &getSeenPeers();
|
const std::vector<uint32_t> &getSeenPeers();
|
||||||
|
|
||||||
|
void clearThreadRegistries();
|
||||||
|
|
||||||
// Text and emote rendering
|
// Text and emote rendering
|
||||||
void drawStringWithEmotes(OLEDDisplay *display, int x, int y, const std::string &line, const Emote *emotes, int emoteCount);
|
void drawStringWithEmotes(OLEDDisplay *display, int x, int y, const std::string &line, const Emote *emotes, int emoteCount);
|
||||||
|
|
||||||
@ -49,4 +51,4 @@ void renderMessageContent(OLEDDisplay *display, const std::vector<std::string> &
|
|||||||
void resetScrollState();
|
void resetScrollState();
|
||||||
|
|
||||||
} // namespace MessageRenderer
|
} // namespace MessageRenderer
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
@ -75,18 +75,16 @@ CannedMessageModule::CannedMessageModule()
|
|||||||
|
|
||||||
void CannedMessageModule::LaunchWithDestination(NodeNum newDest, uint8_t newChannel)
|
void CannedMessageModule::LaunchWithDestination(NodeNum newDest, uint8_t newChannel)
|
||||||
{
|
{
|
||||||
// Use the requested destination, unless it's "broadcast" and we have a previous node/channel
|
// 🚫 Do NOT override explicit broadcast replies
|
||||||
if (newDest == NODENUM_BROADCAST && lastDestSet) {
|
// Only reuse lastDest in LaunchRepeatDestination()
|
||||||
newDest = lastDest;
|
|
||||||
newChannel = lastChannel;
|
|
||||||
}
|
|
||||||
dest = newDest;
|
dest = newDest;
|
||||||
channel = newChannel;
|
channel = newChannel;
|
||||||
|
|
||||||
lastDest = dest;
|
lastDest = dest;
|
||||||
lastChannel = channel;
|
lastChannel = channel;
|
||||||
lastDestSet = true;
|
lastDestSet = true;
|
||||||
|
|
||||||
// Rest of function unchanged...
|
|
||||||
// Upon activation, highlight "[Select Destination]"
|
// Upon activation, highlight "[Select Destination]"
|
||||||
int selectDestination = 0;
|
int selectDestination = 0;
|
||||||
for (int i = 0; i < messagesCount; ++i) {
|
for (int i = 0; i < messagesCount; ++i) {
|
||||||
@ -103,6 +101,8 @@ void CannedMessageModule::LaunchWithDestination(NodeNum newDest, uint8_t newChan
|
|||||||
UIFrameEvent e;
|
UIFrameEvent e;
|
||||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET;
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET;
|
||||||
notifyObservers(&e);
|
notifyObservers(&e);
|
||||||
|
|
||||||
|
LOG_DEBUG("[CannedMessage] LaunchWithDestination dest=0x%08x ch=%d", dest, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CannedMessageModule::LaunchRepeatDestination()
|
void CannedMessageModule::LaunchRepeatDestination()
|
||||||
@ -116,13 +116,12 @@ void CannedMessageModule::LaunchRepeatDestination()
|
|||||||
|
|
||||||
void CannedMessageModule::LaunchFreetextWithDestination(NodeNum newDest, uint8_t newChannel)
|
void CannedMessageModule::LaunchFreetextWithDestination(NodeNum newDest, uint8_t newChannel)
|
||||||
{
|
{
|
||||||
// Use the requested destination, unless it's "broadcast" and we have a previous node/channel
|
// 🚫 Do NOT override explicit broadcast replies
|
||||||
if (newDest == NODENUM_BROADCAST && lastDestSet) {
|
// Only reuse lastDest in LaunchRepeatDestination()
|
||||||
newDest = lastDest;
|
|
||||||
newChannel = lastChannel;
|
|
||||||
}
|
|
||||||
dest = newDest;
|
dest = newDest;
|
||||||
channel = newChannel;
|
channel = newChannel;
|
||||||
|
|
||||||
lastDest = dest;
|
lastDest = dest;
|
||||||
lastChannel = channel;
|
lastChannel = channel;
|
||||||
lastDestSet = true;
|
lastDestSet = true;
|
||||||
@ -132,6 +131,8 @@ void CannedMessageModule::LaunchFreetextWithDestination(NodeNum newDest, uint8_t
|
|||||||
UIFrameEvent e;
|
UIFrameEvent e;
|
||||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET;
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET;
|
||||||
notifyObservers(&e);
|
notifyObservers(&e);
|
||||||
|
|
||||||
|
LOG_DEBUG("[CannedMessage] LaunchFreetextWithDestination dest=0x%08x ch=%d", dest, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool returnToCannedList = false;
|
static bool returnToCannedList = false;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user