Separate Companion message history from pending inbox
Default to retained history with a separate pending count, and add persistent display.inbox CLI modes for history, pending, and unread. Preserve browsing while clients are connected and show the active USB or Bluetooth connection. Fixes #5
This commit is contained in:
1 parent
96ef0ae905
commit
bbfe26b01d
26 files changed
+1178
-666
No files matched your search
@@ -54,17 +54,35 @@ protected:
|
||||
public:
|
||||
void setShutdownGuard(UIShutdownGuard* guard) { _shutdownGuard = guard; }
|
||||
void setHasConnection(bool connected) { _connected = connected; }
|
||||
bool hasConnection() const { return _connected; }
|
||||
bool hasConnection() const { return _interfaceManager->isConnected(); }
|
||||
bool hasBluetoothConnection() const { return _interfaceManager->isBluetoothConnected(); }
|
||||
const char* connectedClientLabel() const {
|
||||
const bool ble = hasBluetoothConnection();
|
||||
const bool usb = _interfaceManager->isInterfaceConnected(InterfaceType::USB);
|
||||
if (ble && usb) return "BLE + USB";
|
||||
if (ble) return "BLUETOOTH";
|
||||
if (usb) return "USB";
|
||||
if (_interfaceManager->isInterfaceConnected(InterfaceType::WiFi)) return "TCP";
|
||||
if (_interfaceManager->isInterfaceConnected(InterfaceType::Ethernet)) return "ETHERNET";
|
||||
if (_interfaceManager->isInterfaceConnected(InterfaceType::HardwareSerial)) return "SERIAL";
|
||||
return nullptr;
|
||||
}
|
||||
uint16_t getBattMilliVolts() const { return _board->getBattMilliVolts(); }
|
||||
bool isBluetoothEnabled() const { return _interfaceManager->isBluetoothEnabled(); }
|
||||
void enableBluetooth() { _interfaceManager->enableBluetooth(); }
|
||||
void disableBluetooth() { _interfaceManager->disableBluetooth(); }
|
||||
virtual void msgRead(int msgcount) = 0;
|
||||
virtual void syncMessageQueue(int msgcount, int removed_index = -1) {
|
||||
(void)removed_index;
|
||||
msgRead(msgcount);
|
||||
}
|
||||
virtual bool supportsInboxModes() const { return false; }
|
||||
virtual void inboxModeChanged() {}
|
||||
virtual void newMsg(uint8_t path_len, const char* from_name,
|
||||
const char* text, int msgcount,
|
||||
int channel_idx = -1,
|
||||
const char* channel_name = nullptr) = 0;
|
||||
const char* channel_name = nullptr,
|
||||
int queue_index = -1) = 0;
|
||||
virtual void notify(UIEventType t = UIEventType::none) = 0;
|
||||
virtual bool supportsDisplayRotation() const { return false; }
|
||||
virtual bool setDisplayRotationDegrees(uint16_t degrees) {
|
||||
|
||||
@@ -470,11 +470,11 @@ void MyMesh::initializeOfflineQueue() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyMesh::addToOfflineQueue(const uint8_t frame[], int len) {
|
||||
bool MyMesh::addToOfflineQueue(const uint8_t frame[], int len) {
|
||||
const int capacity = getOfflineQueueCapacity();
|
||||
if (!frame || len <= 0 || len > MAX_FRAME_SIZE || capacity <= 0) {
|
||||
MESH_DEBUG_PRINTLN("WARN: invalid offline queue frame length: %d", len);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offline_queue_len >= capacity) {
|
||||
@@ -489,7 +489,10 @@ void MyMesh::addToOfflineQueue(const uint8_t frame[], int len) {
|
||||
Frame& tail = offlineQueueFrameAt(offline_queue_len - 1);
|
||||
tail.len = len;
|
||||
memcpy(tail.buf, frame, len);
|
||||
return;
|
||||
#ifdef DISPLAY_CLASS
|
||||
if (_ui) _ui->syncMessageQueue(offline_queue_len, pos);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
@@ -499,7 +502,12 @@ void MyMesh::addToOfflineQueue(const uint8_t frame[], int len) {
|
||||
tail.len = len;
|
||||
memcpy(tail.buf, frame, len);
|
||||
offline_queue_len++;
|
||||
#ifdef DISPLAY_CLASS
|
||||
if (_ui) _ui->syncMessageQueue(offline_queue_len);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int MyMesh::getFromOfflineQueue(uint8_t frame[]) {
|
||||
@@ -514,6 +522,9 @@ int MyMesh::getFromOfflineQueue(uint8_t frame[]) {
|
||||
} else {
|
||||
offline_queue_head = (offline_queue_head + 1) % getOfflineQueueCapacity();
|
||||
}
|
||||
#ifdef DISPLAY_CLASS
|
||||
if (_ui) _ui->syncMessageQueue(offline_queue_len, 0);
|
||||
#endif
|
||||
return len;
|
||||
}
|
||||
return 0; // queue is empty
|
||||
@@ -923,7 +934,7 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
|
||||
}
|
||||
memcpy(&out_frame[i], text, tlen);
|
||||
i += tlen;
|
||||
addToOfflineQueue(out_frame, i);
|
||||
const bool queued = addToOfflineQueue(out_frame, i);
|
||||
|
||||
if (_serial->isConnected()) {
|
||||
uint8_t frame[1];
|
||||
@@ -950,7 +961,8 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
|
||||
// we only want to show text messages on display, not cli data
|
||||
bool should_display = txt_type == TXT_TYPE_PLAIN || txt_type == TXT_TYPE_SIGNED_PLAIN;
|
||||
if (should_display && _ui) {
|
||||
_ui->newMsg(path_len, from.name, text, offline_queue_len);
|
||||
_ui->newMsg(path_len, from.name, text, offline_queue_len,
|
||||
-1, nullptr, queued ? offline_queue_len - 1 : -1);
|
||||
if (!_serial->isConnected()) {
|
||||
_ui->notify(UIEventType::contactMessage);
|
||||
}
|
||||
@@ -1120,7 +1132,7 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe
|
||||
}
|
||||
memcpy(&out_frame[i], text, tlen);
|
||||
i += tlen;
|
||||
addToOfflineQueue(out_frame, i);
|
||||
const bool queued = addToOfflineQueue(out_frame, i);
|
||||
|
||||
if (_serial->isConnected()) {
|
||||
uint8_t frame[1];
|
||||
@@ -1154,7 +1166,7 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe
|
||||
(unsigned int)channel_idx, channel_name);
|
||||
if (_ui) {
|
||||
_ui->newMsg(path_len, channel_label, text, offline_queue_len,
|
||||
channel_idx, channel_name);
|
||||
channel_idx, channel_name, queued ? offline_queue_len - 1 : -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2555,7 +2567,11 @@ bool MyMesh::handleLocalControlCommand(const char* command, char* reply,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mesh::ui::handleDisplayPowerCommand(command, reply, reply_size)) return true;
|
||||
if (mesh::ui::handleDisplayPowerCommand(command, reply, reply_size,
|
||||
_ui != nullptr && _ui->supportsInboxModes())) {
|
||||
if (_ui) _ui->inboxModeChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "get display.touch") == 0) {
|
||||
if (_ui == NULL || !_ui->supportsTouchDebug()) {
|
||||
@@ -4573,9 +4589,6 @@ void MyMesh::handleCmdFrame(size_t len) {
|
||||
int out_len;
|
||||
if ((out_len = getFromOfflineQueue(out_frame)) > 0) {
|
||||
_serial->writeFrame(out_frame, out_len);
|
||||
#ifdef DISPLAY_CLASS
|
||||
if (_ui) _ui->msgRead(offline_queue_len);
|
||||
#endif
|
||||
} else {
|
||||
out_frame[0] = RESP_CODE_NO_MORE_MESSAGES;
|
||||
_serial->writeFrame(out_frame, 1);
|
||||
@@ -7932,6 +7945,8 @@ void MyMesh::handleTerminalCommand(char* command) {
|
||||
terminalOutput().print(" memory\r\n");
|
||||
#endif
|
||||
terminalOutput().print(" get display.rotation\r\n");
|
||||
terminalOutput().print(" get display.inbox\r\n");
|
||||
terminalOutput().print(" set display.inbox <history|pending|unread>\r\n");
|
||||
terminalOutput().print(" set display.rotation <0|90|180|270>\r\n");
|
||||
terminalOutput().print(" get display.touch\r\n");
|
||||
terminalOutput().print(" set display.touch <on|off> (this boot only)\r\n");
|
||||
|
||||
@@ -363,7 +363,7 @@ private:
|
||||
bool writeContactRespFrame(uint8_t code, const ContactInfo &contact);
|
||||
void stopContactsIterator();
|
||||
bool updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, const uint8_t *frame, int len);
|
||||
void addToOfflineQueue(const uint8_t frame[], int len);
|
||||
bool addToOfflineQueue(const uint8_t frame[], int len);
|
||||
int getFromOfflineQueue(uint8_t frame[]);
|
||||
int getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]) override {
|
||||
return _store->getBlobByKey(key, key_len, dest_buf);
|
||||
|
||||
@@ -35,9 +35,6 @@
|
||||
#ifndef AUTO_OFF_MILLIS
|
||||
#define AUTO_OFF_MILLIS 15000 // 15 seconds
|
||||
#endif
|
||||
#ifndef USB_MESSAGE_PREVIEW_MILLIS
|
||||
#define USB_MESSAGE_PREVIEW_MILLIS 15000UL
|
||||
#endif
|
||||
#ifndef UI_RADIO_REFRESH_MILLIS
|
||||
#define UI_RADIO_REFRESH_MILLIS 2000UL
|
||||
#endif
|
||||
@@ -665,20 +662,30 @@ public:
|
||||
display.renderWidth(), display.renderHeight());
|
||||
if (expanded_home) {
|
||||
display.setTextSize(4);
|
||||
display.drawTextCentered(display.width() / 2, 20, "INBOX");
|
||||
if (display.getTextWidth(_task->inboxTitle()) > display.width()) display.setTextSize(3);
|
||||
display.drawTextCentered(display.width() / 2, 20, _task->inboxTitle());
|
||||
} else {
|
||||
sprintf(tmp, "INBOX: %d", _task->getPreviewCount());
|
||||
snprintf(tmp, sizeof(tmp), "%s: %d", _task->inboxTitle(), _task->getPreviewCount());
|
||||
display.setTextSize(2);
|
||||
if (display.getTextWidth(tmp) > display.width()) display.setTextSize(1);
|
||||
display.drawTextCentered(display.width() / 2, body_top + 2, tmp);
|
||||
}
|
||||
#else
|
||||
display.setTextSize(2);
|
||||
sprintf(tmp, "INBOX: %d", _task->getPreviewCount());
|
||||
const int home_content_top = body_top + 2 + display.textLineHeight()
|
||||
snprintf(tmp, sizeof(tmp), "%s: %d", _task->inboxTitle(), _task->getPreviewCount());
|
||||
if (display.getTextWidth(tmp) > display.width()) display.setTextSize(1);
|
||||
int home_content_top = body_top + 2 + display.textLineHeight()
|
||||
+ (display.height() > 64 ? 2 : 0);
|
||||
mesh::ui::drawTextCenteredEllipsized(display,
|
||||
{0, body_top + 2, display.width(), display.textLineHeight()},
|
||||
body_top + 2, tmp);
|
||||
display.setTextSize(1);
|
||||
display.setColor(UIColor::secondary_txt);
|
||||
snprintf(tmp, sizeof(tmp), "Pending: %d", _task->getMsgCount());
|
||||
mesh::ui::drawTextCenteredEllipsized(display,
|
||||
{0, home_content_top, display.width(), display.textLineHeight()},
|
||||
home_content_top, tmp);
|
||||
home_content_top += display.textLineHeight() + 1;
|
||||
#endif
|
||||
#ifdef UI_DEDICATED_PAIRING_BLOCK
|
||||
const mesh::ui::CompanionHomeLayout layout =
|
||||
@@ -695,19 +702,23 @@ public:
|
||||
|
||||
if (expanded_home) {
|
||||
snprintf(tmp, sizeof(tmp), "%d", _task->getPreviewCount());
|
||||
display.setTextSize(4);
|
||||
display.setTextSize(3);
|
||||
if (display.getTextWidth(tmp) > layout.info.width) {
|
||||
display.setTextSize(3);
|
||||
display.setTextSize(2);
|
||||
}
|
||||
display.setColor(UIColor::primary_txt);
|
||||
mesh::ui::drawTextCenteredEllipsized(
|
||||
display, layout.info, layout.instruction_y, tmp);
|
||||
display.setTextSize(1);
|
||||
snprintf(tmp, sizeof(tmp), "Pending: %d", _task->getMsgCount());
|
||||
mesh::ui::drawTextCenteredEllipsized(
|
||||
display, layout.info, layout.info.bottom() - display.textLineHeight(), tmp);
|
||||
} else {
|
||||
display.setTextSize(1);
|
||||
display.setColor(UIColor::secondary_txt);
|
||||
snprintf(tmp, sizeof(tmp), "Pending: %d", _task->getMsgCount());
|
||||
mesh::ui::drawTextCenteredEllipsized(
|
||||
display, layout.info, layout.instruction_y,
|
||||
PRESS_LABEL ": inbox");
|
||||
display, layout.info, layout.instruction_y, tmp);
|
||||
|
||||
#ifdef WIFI_SSID
|
||||
if (!isCompanionWiFiEnabled()) {
|
||||
@@ -731,11 +742,12 @@ public:
|
||||
const bool bluetooth_connected = _task->hasBluetoothConnection();
|
||||
const uint32_t bluetooth_pin = the_mesh.getBLEPin();
|
||||
const char* pairing_label = nullptr;
|
||||
const char* client_label = _task->connectedClientLabel();
|
||||
const char* pairing_value = nullptr;
|
||||
int pairing_value_size = 2;
|
||||
char pairing_pin[16];
|
||||
if (bluetooth_connected) {
|
||||
pairing_label = expanded_home ? "BLE" : "BLUETOOTH";
|
||||
if (client_label != nullptr && !_task->isPairingPromptActive()) {
|
||||
pairing_label = expanded_home && strcmp(client_label, "BLUETOOTH") == 0 ? "BLE" : client_label;
|
||||
pairing_value = expanded_home ? "LINKED" : "CONNECTED";
|
||||
if (expanded_home) pairing_value_size = 3;
|
||||
} else if (mesh::ui::shouldDisplayBluetoothPairingPin(
|
||||
@@ -792,12 +804,13 @@ public:
|
||||
mesh::ui::shouldDisplayBluetoothPairingPin(
|
||||
bluetooth_enabled, bluetooth_connected, bluetooth_pin)
|
||||
&& (!_task->isPairingPromptActive() || display.height() > 64);
|
||||
if (bluetooth_connected || show_bluetooth_pin) {
|
||||
const char* client_label = _task->connectedClientLabel();
|
||||
if (client_label != nullptr || show_bluetooth_pin) {
|
||||
char pairing_pin[16];
|
||||
const char* pairing_label = bluetooth_connected
|
||||
? "BLUETOOTH" : "BLUETOOTH PIN";
|
||||
const bool show_client = client_label != nullptr && !_task->isPairingPromptActive();
|
||||
const char* pairing_label = show_client ? client_label : "BLUETOOTH PIN";
|
||||
const char* pairing_value = "CONNECTED";
|
||||
if (!bluetooth_connected) {
|
||||
if (!show_client) {
|
||||
snprintf(pairing_pin, sizeof(pairing_pin), "%06u",
|
||||
(unsigned int)bluetooth_pin);
|
||||
pairing_value = pairing_pin;
|
||||
@@ -811,7 +824,7 @@ public:
|
||||
display.height() - home_content_top});
|
||||
display.setTextSize(1);
|
||||
display.setColor(UIColor::secondary_txt);
|
||||
rows.draw(PRESS_LABEL ": inbox");
|
||||
rows.draw(PRESS_LABEL ": messages");
|
||||
|
||||
#ifdef UI_SHOW_CLOCK
|
||||
display.setTextSize(3);
|
||||
@@ -1257,9 +1270,14 @@ class MsgPreviewScreen : public UIScreen {
|
||||
int view_offset;
|
||||
int channel_filter;
|
||||
|
||||
bool visible(const MsgEntry& entry) const {
|
||||
return mesh::ui::displayPowerPrefs().inbox != mesh::ui::DisplayInboxMode::Pending
|
||||
|| entry.queue_index >= 0;
|
||||
}
|
||||
|
||||
bool matchesFilter(const MsgEntry& entry) const {
|
||||
return channel_filter == CHANNEL_FILTER_ALL
|
||||
|| entry.channel_idx == channel_filter;
|
||||
return visible(entry) && (channel_filter == CHANNEL_FILTER_ALL
|
||||
|| entry.channel_idx == channel_filter);
|
||||
}
|
||||
|
||||
int filteredCount() const {
|
||||
@@ -1380,18 +1398,37 @@ public:
|
||||
explicit MsgPreviewScreen(UITask* task)
|
||||
: _task(task), view_offset(0), channel_filter(CHANNEL_FILTER_ALL) {}
|
||||
|
||||
bool hasMessages() const { return !history.empty(); }
|
||||
int messageCount() const { return (int)history.count(); }
|
||||
bool hasMessages() const {
|
||||
for (size_t age = 0; age < history.count(); ++age)
|
||||
if (visible(*history.newest(age))) return true;
|
||||
return false;
|
||||
}
|
||||
int messageCount() const {
|
||||
if (mesh::ui::displayPowerPrefs().inbox == mesh::ui::DisplayInboxMode::Unread)
|
||||
return (int)history.unreadCount();
|
||||
if (mesh::ui::displayPowerPrefs().inbox == mesh::ui::DisplayInboxMode::Pending)
|
||||
return _task->getMsgCount();
|
||||
return (int)history.count();
|
||||
}
|
||||
void queueRemoved(int index) { history.queueRemoved(index); }
|
||||
|
||||
void addPreview(uint8_t path_len, const char* from_name, const char* msg,
|
||||
int channel_idx, const char* channel_name) {
|
||||
int channel_idx, const char* channel_name,
|
||||
int queue_index = -1, bool select = true) {
|
||||
if (channel_idx < CHANNEL_FILTER_DIRECT
|
||||
|| channel_idx >= MAX_GROUP_CHANNELS) {
|
||||
channel_idx = CHANNEL_FILTER_DIRECT;
|
||||
channel_name = nullptr;
|
||||
}
|
||||
view_offset = 0;
|
||||
channel_filter = channel_idx;
|
||||
if (select) {
|
||||
view_offset = 0;
|
||||
channel_filter = channel_idx;
|
||||
} else if ((mesh::ui::displayPowerPrefs().inbox != mesh::ui::DisplayInboxMode::Pending
|
||||
|| queue_index >= 0)
|
||||
&& (channel_filter == CHANNEL_FILTER_ALL || channel_filter == channel_idx)) {
|
||||
// Retain the message being read when a connected app receives another.
|
||||
if (filteredCount() > 0) ++view_offset;
|
||||
}
|
||||
|
||||
char origin[62];
|
||||
if (path_len == 0xFF) {
|
||||
@@ -1401,7 +1438,7 @@ public:
|
||||
(unsigned int)path_len);
|
||||
}
|
||||
history.add(companionMessageNowMillis(), channel_idx, channel_name,
|
||||
origin, msg);
|
||||
origin, msg, queue_index);
|
||||
}
|
||||
|
||||
void renderSummary(DisplayDriver& display) const {
|
||||
@@ -1416,9 +1453,16 @@ public:
|
||||
for (size_t age = 0;
|
||||
age < history.count() && rendered < layout.visible_rows;
|
||||
++age) {
|
||||
if (history.hasNewerEntryForThread(age)) continue;
|
||||
const MsgEntry* entry = history.newest(age);
|
||||
if (entry == nullptr) continue;
|
||||
if (entry == nullptr || !visible(*entry)) continue;
|
||||
bool newer_in_thread = false;
|
||||
for (size_t newer = 0; newer < age; ++newer) {
|
||||
const MsgEntry* candidate = history.newest(newer);
|
||||
if (visible(*candidate) && MessageHistory::sameThread(*entry, *candidate)) {
|
||||
newer_in_thread = true; break;
|
||||
}
|
||||
}
|
||||
if (newer_in_thread) continue;
|
||||
|
||||
const int row_y = layout.top + rendered * layout.row_height;
|
||||
char label[48];
|
||||
@@ -1535,6 +1579,7 @@ public:
|
||||
filtered_count == 0 ? 0 : view_offset + 1, filtered_count);
|
||||
#endif
|
||||
const MsgEntry* p = filteredEntry(view_offset);
|
||||
if (p != nullptr && display.isOn()) history.markRead(p);
|
||||
char age[16] = {};
|
||||
if (p != nullptr) {
|
||||
mesh::ui::formatCompanionMessageAge(
|
||||
@@ -1741,6 +1786,14 @@ int UITask::getPreviewCount() const {
|
||||
return static_cast<const MsgPreviewScreen*>(msg_preview)->messageCount();
|
||||
}
|
||||
|
||||
const char* UITask::inboxTitle() const {
|
||||
switch (mesh::ui::displayPowerPrefs().inbox) {
|
||||
case mesh::ui::DisplayInboxMode::Pending: return "INBOX";
|
||||
case mesh::ui::DisplayInboxMode::Unread: return "UNREAD";
|
||||
default: return "HISTORY";
|
||||
}
|
||||
}
|
||||
|
||||
void UITask::renderMessageSummary(DisplayDriver& display) const {
|
||||
static_cast<const MsgPreviewScreen*>(msg_preview)->renderSummary(display);
|
||||
}
|
||||
@@ -1776,28 +1829,27 @@ switch(t){
|
||||
|
||||
void UITask::msgRead(int msgcount) {
|
||||
_msgcount = msgcount;
|
||||
if (msgcount == 0) {
|
||||
_deferred_msg_preview = false;
|
||||
const bool holding_usb_preview = curr == msg_preview && _msg_preview_until != 0
|
||||
&& static_cast<int32_t>(millis() - _msg_preview_until) < 0;
|
||||
if (!holding_usb_preview
|
||||
#if COMPANION_FEATURE_JOHN
|
||||
&& !isJohnReaderActive()
|
||||
#endif
|
||||
) {
|
||||
gotoHomeScreen();
|
||||
}
|
||||
}
|
||||
_next_refresh = 0;
|
||||
}
|
||||
|
||||
void UITask::syncMessageQueue(int msgcount, int removed_index) {
|
||||
if (msg_preview != nullptr)
|
||||
static_cast<MsgPreviewScreen*>(msg_preview)->queueRemoved(removed_index);
|
||||
msgRead(msgcount);
|
||||
}
|
||||
|
||||
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text,
|
||||
int msgcount, int channel_idx,
|
||||
const char* channel_name) {
|
||||
const char* channel_name, int queue_index) {
|
||||
_msgcount = msgcount;
|
||||
|
||||
((MsgPreviewScreen *)msg_preview)
|
||||
->addPreview(path_len, from_name, text, channel_idx, channel_name);
|
||||
if (isPairingScreenActive()) {
|
||||
->addPreview(path_len, from_name, text, channel_idx, channel_name,
|
||||
queue_index, !hasConnection());
|
||||
if (hasConnection()) {
|
||||
// Keep history, but do not change the page or wake for a connected client.
|
||||
_deferred_msg_preview = false;
|
||||
} else if (isPairingScreenActive()) {
|
||||
// Keep the PIN visible, but retain the preview so it can be shown after
|
||||
// pairing completes or the pairing display window expires.
|
||||
_deferred_msg_preview = true;
|
||||
@@ -1812,14 +1864,6 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text,
|
||||
setCurrScreen(msg_preview);
|
||||
}
|
||||
|
||||
// A connected app drains the offline queue almost immediately, which calls
|
||||
// msgRead(0). While attached to a computer, retain the actual message screen
|
||||
// for the configured preview interval even though the app has already
|
||||
// consumed the message.
|
||||
_msg_preview_until = _board->isUsbHostConnected()
|
||||
? millis() + USB_MESSAGE_PREVIEW_MILLIS
|
||||
: 0;
|
||||
|
||||
if (_display != NULL) {
|
||||
if (shouldWakeDisplayForMessage()) {
|
||||
_display->wake(mesh::ui::DisplayWake::Message);
|
||||
@@ -1901,7 +1945,8 @@ void UITask::showPairingPin() {
|
||||
void UITask::finishPairingScreen(bool timed_out) {
|
||||
_pairing_screen_until = 0;
|
||||
|
||||
if (_deferred_msg_preview && _msgcount > 0) {
|
||||
if (_deferred_msg_preview && !hasConnection()
|
||||
&& static_cast<MsgPreviewScreen*>(msg_preview)->hasMessages()) {
|
||||
_deferred_msg_preview = false;
|
||||
setCurrScreen(msg_preview);
|
||||
} else {
|
||||
@@ -2179,12 +2224,6 @@ void UITask::loop() {
|
||||
if (john_reader && curr != john_reader) john_reader->poll();
|
||||
#endif
|
||||
|
||||
if (_msgcount == 0 && _msg_preview_until != 0
|
||||
&& static_cast<int32_t>(millis() - _msg_preview_until) >= 0) {
|
||||
_msg_preview_until = 0;
|
||||
if (curr == msg_preview) gotoHomeScreen();
|
||||
}
|
||||
|
||||
if (_display != NULL && _display->isOn()) {
|
||||
if (millis() >= _next_refresh && curr && !isButtonGesturePending()) {
|
||||
_display->startFrame();
|
||||
|
||||
@@ -36,7 +36,6 @@ class UITask : public AbstractUITask {
|
||||
GenericVibration vibration;
|
||||
#endif
|
||||
unsigned long _next_refresh;
|
||||
unsigned long _msg_preview_until;
|
||||
unsigned long _pairing_screen_until;
|
||||
bool _deferred_msg_preview;
|
||||
CompanionNodePrefs* _node_prefs;
|
||||
@@ -93,7 +92,7 @@ class UITask : public AbstractUITask {
|
||||
|
||||
UIScreen* splash;
|
||||
UIScreen* home;
|
||||
UIScreen* msg_preview;
|
||||
UIScreen* msg_preview = nullptr;
|
||||
UIScreen* curr;
|
||||
#if COMPANION_FEATURE_JOHN
|
||||
UIScreen* john_reader = nullptr;
|
||||
@@ -118,7 +117,6 @@ public:
|
||||
|
||||
UITask(mesh::MainBoard* board, MultiSerialInterface* serial) : AbstractUITask(board, serial), _display(NULL), _sensors(NULL) {
|
||||
next_batt_chck = _next_refresh = 0;
|
||||
_msg_preview_until = 0;
|
||||
_pairing_screen_until = 0;
|
||||
_deferred_msg_preview = false;
|
||||
_msgcount = 0;
|
||||
@@ -180,9 +178,14 @@ public:
|
||||
|
||||
// from AbstractUITask
|
||||
void msgRead(int msgcount) override;
|
||||
void syncMessageQueue(int msgcount, int removed_index = -1) override;
|
||||
bool supportsInboxModes() const override { return _display != nullptr; }
|
||||
void inboxModeChanged() override { _next_refresh = 0; }
|
||||
const char* inboxTitle() const;
|
||||
void newMsg(uint8_t path_len, const char* from_name, const char* text,
|
||||
int msgcount, int channel_idx = -1,
|
||||
const char* channel_name = nullptr) override;
|
||||
const char* channel_name = nullptr,
|
||||
int queue_index = -1) override;
|
||||
void notify(UIEventType t = UIEventType::none) override;
|
||||
void loop() override;
|
||||
|
||||
|
||||
@@ -165,7 +165,8 @@ void UITask::clearMsgPreview() {
|
||||
|
||||
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text,
|
||||
int msgcount, int channel_idx,
|
||||
const char* channel_name) {
|
||||
const char* channel_name, int queue_index) {
|
||||
(void)queue_index;
|
||||
(void)channel_idx;
|
||||
(void)channel_name;
|
||||
_msgcount = msgcount;
|
||||
|
||||
@@ -94,7 +94,8 @@ public:
|
||||
void msgRead(int msgcount) override;
|
||||
void newMsg(uint8_t path_len, const char* from_name, const char* text,
|
||||
int msgcount, int channel_idx = -1,
|
||||
const char* channel_name = nullptr) override;
|
||||
const char* channel_name = nullptr,
|
||||
int queue_index = -1) override;
|
||||
void notify(UIEventType t = UIEventType::none) override;
|
||||
void loop() override;
|
||||
|
||||
|
||||
@@ -564,7 +564,8 @@ void UITask::msgRead(int msgcount) {
|
||||
|
||||
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text,
|
||||
int msgcount, int channel_idx,
|
||||
const char* channel_name) {
|
||||
const char* channel_name, int queue_index) {
|
||||
(void)queue_index;
|
||||
(void)channel_idx;
|
||||
(void)channel_name;
|
||||
_msgcount = msgcount;
|
||||
|
||||
@@ -122,7 +122,8 @@ public:
|
||||
void msgRead(int msgcount) override;
|
||||
void newMsg(uint8_t path_len, const char* from_name, const char* text,
|
||||
int msgcount, int channel_idx = -1,
|
||||
const char* channel_name = nullptr) override;
|
||||
const char* channel_name = nullptr,
|
||||
int queue_index = -1) override;
|
||||
void notify(UIEventType t = UIEventType::none) override;
|
||||
void loop() override;
|
||||
|
||||
|
||||
Reference in new issue
Block a user