mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-02 02:06:11 +00:00
Unread badges per category + context menu stays open on action
- newMsg() now takes contact_type; room server messages (ADV_TYPE_ROOM) tracked separately in _room_unread; DM badge = msgCount - roomUnread - MODE_SELECT shows unread badges for all 3 rows: DM, Channels, Rooms - Room unread cleared when user opens Room Servers list or msgRead(0) - Channel context menu: ENTER performs action but stays open; only CANCEL (Back button) closes it so user can see the updated state Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1a1cda4a1a
commit
158bbf74c8
@@ -40,7 +40,7 @@ public:
|
|||||||
void enableSerial() { _serial->enable(); }
|
void enableSerial() { _serial->enable(); }
|
||||||
void disableSerial() { _serial->disable(); }
|
void disableSerial() { _serial->disable(); }
|
||||||
virtual void msgRead(int msgcount) = 0;
|
virtual void msgRead(int msgcount) = 0;
|
||||||
virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) = 0;
|
virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount, uint8_t contact_type = 0) = 0;
|
||||||
virtual void notify(UIEventType t = UIEventType::none) = 0;
|
virtual void notify(UIEventType t = UIEventType::none) = 0;
|
||||||
virtual void addChannelMsg(uint8_t channel_idx, const char* text) {}
|
virtual void addChannelMsg(uint8_t channel_idx, const char* text) {}
|
||||||
virtual void loop() = 0;
|
virtual void loop() = 0;
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
|
|||||||
// we only want to show text messages on display, not cli data
|
// 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;
|
bool should_display = txt_type == TXT_TYPE_PLAIN || txt_type == TXT_TYPE_SIGNED_PLAIN;
|
||||||
if (should_display && _ui) {
|
if (should_display && _ui) {
|
||||||
_ui->newMsg(path_len, from.name, text, offline_queue_len);
|
_ui->newMsg(path_len, from.name, text, offline_queue_len, from.type);
|
||||||
if (!_serial->isConnected()) {
|
if (!_serial->isConnected()) {
|
||||||
_ui->notify(UIEventType::contactMessage);
|
_ui->notify(UIEventType::contactMessage);
|
||||||
}
|
}
|
||||||
@@ -573,7 +573,7 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe
|
|||||||
if (getChannel(channel_idx, channel_details)) {
|
if (getChannel(channel_idx, channel_details)) {
|
||||||
channel_name = channel_details.name;
|
channel_name = channel_details.name;
|
||||||
}
|
}
|
||||||
if (_ui) _ui->newMsg(path_len, channel_name, text, offline_queue_len);
|
if (_ui) _ui->newMsg(path_len, channel_name, text, offline_queue_len, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -986,7 +986,12 @@ public:
|
|||||||
display.drawTextCentered(display.width()/2, 0, "MESSAGE");
|
display.drawTextCentered(display.width()/2, 0, "MESSAGE");
|
||||||
display.fillRect(0, 10, display.width(), 1);
|
display.fillRect(0, 10, display.width(), 1);
|
||||||
const char* opts[] = { "Direct message", "Channels", "Room Servers" };
|
const char* opts[] = { "Direct message", "Channels", "Room Servers" };
|
||||||
int dm_unread = _task->getMsgCount();
|
int badges[3] = {
|
||||||
|
_task->getMsgCount() - _task->getRoomUnreadCount(), // DM only
|
||||||
|
_task->getChannelUnreadCount(),
|
||||||
|
_task->getRoomUnreadCount()
|
||||||
|
};
|
||||||
|
if (badges[0] < 0) badges[0] = 0;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int y = START_Y + i * ITEM_H;
|
int y = START_Y + i * ITEM_H;
|
||||||
bool sel = (i == _mode_sel);
|
bool sel = (i == _mode_sel);
|
||||||
@@ -1001,9 +1006,9 @@ public:
|
|||||||
display.print(sel ? ">" : " ");
|
display.print(sel ? ">" : " ");
|
||||||
display.setCursor(8, y);
|
display.setCursor(8, y);
|
||||||
display.print(opts[i]);
|
display.print(opts[i]);
|
||||||
if (i == 0 && dm_unread > 0) {
|
if (badges[i] > 0) {
|
||||||
char badge[5];
|
char badge[5];
|
||||||
snprintf(badge, sizeof(badge), "%d", dm_unread);
|
snprintf(badge, sizeof(badge), "%d", badges[i]);
|
||||||
int bw = display.getTextWidth(badge) + 2;
|
int bw = display.getTextWidth(badge) + 2;
|
||||||
display.setCursor(display.width() - bw, y);
|
display.setCursor(display.width() - bw, y);
|
||||||
display.print(badge);
|
display.print(badge);
|
||||||
@@ -1379,6 +1384,7 @@ public:
|
|||||||
_phase = CHANNEL_PICK;
|
_phase = CHANNEL_PICK;
|
||||||
} else {
|
} else {
|
||||||
_room_mode = (_mode_sel == 2);
|
_room_mode = (_mode_sel == 2);
|
||||||
|
if (_room_mode) _task->clearRoomUnread();
|
||||||
buildContactList();
|
buildContactList();
|
||||||
_contact_sel = _contact_scroll = 0;
|
_contact_sel = _contact_scroll = 0;
|
||||||
_phase = CONTACT_PICK;
|
_phase = CONTACT_PICK;
|
||||||
@@ -1421,7 +1427,7 @@ public:
|
|||||||
uint8_t nstate = chNotifState(ch_idx);
|
uint8_t nstate = chNotifState(ch_idx);
|
||||||
setChNotifState(ch_idx, (nstate + 1) % 3); // cycle: default→OFF→ON→default
|
setChNotifState(ch_idx, (nstate + 1) % 3); // cycle: default→OFF→ON→default
|
||||||
}
|
}
|
||||||
_ctx_open = false;
|
// stay open so user can see result; CANCEL closes
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -2002,6 +2008,7 @@ public:
|
|||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.drawTextCentered(display.width() / 2, 22, "Messages");
|
display.drawTextCentered(display.width() / 2, 22, "Messages");
|
||||||
int total_unread = _task->getMsgCount() + _task->getChannelUnreadCount();
|
int total_unread = _task->getMsgCount() + _task->getChannelUnreadCount();
|
||||||
|
// getMsgCount() already includes room msgs via offline_queue_len; avoid double-count
|
||||||
if (total_unread > 0) {
|
if (total_unread > 0) {
|
||||||
char badge[20];
|
char badge[20];
|
||||||
snprintf(badge, sizeof(badge), "%d unread", total_unread);
|
snprintf(badge, sizeof(badge), "%d unread", total_unread);
|
||||||
@@ -2360,12 +2367,14 @@ switch(t){
|
|||||||
void UITask::msgRead(int msgcount) {
|
void UITask::msgRead(int msgcount) {
|
||||||
_msgcount = msgcount;
|
_msgcount = msgcount;
|
||||||
if (msgcount == 0) {
|
if (msgcount == 0) {
|
||||||
|
_room_unread = 0;
|
||||||
gotoHomeScreen();
|
gotoHomeScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) {
|
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount, uint8_t contact_type) {
|
||||||
_msgcount = msgcount;
|
_msgcount = msgcount;
|
||||||
|
if (contact_type == ADV_TYPE_ROOM) _room_unread++;
|
||||||
|
|
||||||
char alert_buf[80];
|
char alert_buf[80];
|
||||||
snprintf(alert_buf, sizeof(alert_buf), "Msg: %.20s", from_name);
|
snprintf(alert_buf, sizeof(alert_buf), "Msg: %.20s", from_name);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class UITask : public AbstractUITask {
|
|||||||
char _alert[80];
|
char _alert[80];
|
||||||
unsigned long _alert_expiry;
|
unsigned long _alert_expiry;
|
||||||
int _msgcount;
|
int _msgcount;
|
||||||
|
int _room_unread;
|
||||||
int _last_notif_ch_idx;
|
int _last_notif_ch_idx;
|
||||||
unsigned long ui_started_at, next_batt_chck;
|
unsigned long ui_started_at, next_batt_chck;
|
||||||
uint16_t _batt_mv; // EMA-filtered battery voltage
|
uint16_t _batt_mv; // EMA-filtered battery voltage
|
||||||
@@ -73,6 +74,7 @@ public:
|
|||||||
next_batt_chck = _next_refresh = 0;
|
next_batt_chck = _next_refresh = 0;
|
||||||
ui_started_at = 0;
|
ui_started_at = 0;
|
||||||
_batt_mv = 0;
|
_batt_mv = 0;
|
||||||
|
_msgcount = _room_unread = 0;
|
||||||
_last_notif_ch_idx = -1;
|
_last_notif_ch_idx = -1;
|
||||||
curr = NULL;
|
curr = NULL;
|
||||||
}
|
}
|
||||||
@@ -87,6 +89,8 @@ public:
|
|||||||
void addChannelMsg(uint8_t channel_idx, const char* text) override;
|
void addChannelMsg(uint8_t channel_idx, const char* text) override;
|
||||||
int getMsgCount() const { return _msgcount; }
|
int getMsgCount() const { return _msgcount; }
|
||||||
int getChannelUnreadCount() const;
|
int getChannelUnreadCount() const;
|
||||||
|
int getRoomUnreadCount() const { return _room_unread; }
|
||||||
|
void clearRoomUnread() { _room_unread = 0; }
|
||||||
bool hasDisplay() const { return _display != NULL; }
|
bool hasDisplay() const { return _display != NULL; }
|
||||||
bool isButtonPressed() const;
|
bool isButtonPressed() const;
|
||||||
|
|
||||||
@@ -114,7 +118,7 @@ public:
|
|||||||
|
|
||||||
// from AbstractUITask
|
// from AbstractUITask
|
||||||
void msgRead(int msgcount) override;
|
void msgRead(int msgcount) override;
|
||||||
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
|
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount, uint8_t contact_type = 0) override;
|
||||||
void notify(UIEventType t = UIEventType::none) override;
|
void notify(UIEventType t = UIEventType::none) override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user