mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-01 10:21:59 +00:00
refactor: one place each for "in view" and the keyboard's backspace
ui-new's messagesInView() and ui-lvgl's threadInView() hold the lit-and-unlocked test the viewing checks repeated; the keyboard's three copies of the backspace call deleteBeforeCursor(). A stale comment on the cursor-mode hint goes, onDisplayOn() sits after the view helpers it calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3469,8 +3469,9 @@ void MyMesh::loop() {
|
||||
if ((dirty_contacts_expiry && millisHasNowPassed(dirty_contacts_expiry))
|
||||
|| (dirty_paths_expiry && millisHasNowPassed(dirty_paths_expiry))) {
|
||||
if (millis() - _last_input_ms < USER_QUIET_MILLIS) {
|
||||
if (dirty_contacts_expiry) dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
if (dirty_paths_expiry) dirty_paths_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
unsigned long later = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
if (dirty_contacts_expiry) dirty_contacts_expiry = later;
|
||||
if (dirty_paths_expiry) dirty_paths_expiry = later;
|
||||
} else {
|
||||
saveContacts();
|
||||
dirty_contacts_expiry = dirty_paths_expiry = 0;
|
||||
|
||||
@@ -1914,12 +1914,16 @@ void UITask::onMessageArrived(const UiEvent& ev) {
|
||||
}
|
||||
|
||||
// On screen: a conversation left open under the lock or a dark display isn't read.
|
||||
bool UITask::threadInView() const {
|
||||
return !_asleep && !locked() && _screen == SCR_THREAD;
|
||||
}
|
||||
|
||||
bool UITask::isViewingChannel(uint8_t channel_idx) {
|
||||
return !_asleep && !locked() && _screen == SCR_THREAD && _thread_is_channel && _thread_channel == channel_idx;
|
||||
return threadInView() && _thread_is_channel && _thread_channel == channel_idx;
|
||||
}
|
||||
|
||||
bool UITask::isViewingDM(const uint8_t* pub_key) {
|
||||
return !_asleep && !locked() && _screen == SCR_THREAD && !_thread_is_channel && memcmp(_thread_key, pub_key, 4) == 0;
|
||||
return threadInView() && !_thread_is_channel && memcmp(_thread_key, pub_key, 4) == 0;
|
||||
}
|
||||
|
||||
// ── Status bar + toast (top layer, over every screen) ─────────────────────────
|
||||
|
||||
@@ -430,6 +430,7 @@ private:
|
||||
void buildThread();
|
||||
void threadOpenAt(int first);
|
||||
void reopenThreadIfUnread();
|
||||
bool threadInView() const; // a thread on a lit, unlocked screen
|
||||
void refreshThread();
|
||||
void refreshThreadAges();
|
||||
uint32_t threadSignature() const;
|
||||
|
||||
@@ -546,6 +546,7 @@ struct KeyboardWidget {
|
||||
return p;
|
||||
}
|
||||
|
||||
// Backspace: the codepoint before the cursor.
|
||||
void deleteBeforeCursor() {
|
||||
t9_cell = -1;
|
||||
if (cursor_pos <= 0) return;
|
||||
@@ -600,9 +601,7 @@ struct KeyboardWidget {
|
||||
// Compact mode only ever draws 2 short hint lines (no grid, no status line
|
||||
// -- see below), but reserves at least as much height as the smallest real
|
||||
// grid (T9's 3 rows) would need, rather than shrinking to just those 2
|
||||
// lines: cursor_mode's own 3-line hint (drawn in this same region,
|
||||
// regardless of Compact, for a physical-button user) already relies on
|
||||
// that floor and would otherwise get clipped.
|
||||
// lines, so the preview keeps the same height whichever mode is on.
|
||||
// A tall screen (the 4.2" panel: 20 lines) gives the keys half a line more each.
|
||||
const int key_lh = display.height() >= 18 * lh ? lh * 3 / 2 : lh;
|
||||
const int kb_h = compact_ui ? (KB_T9_ROWS + 1) * lh : (rows + 1) * key_lh;
|
||||
@@ -1077,13 +1076,7 @@ struct KeyboardWidget {
|
||||
// no ambiguity to resolve at this layer -- pollCardKB() already decided.
|
||||
if (c == KEY_KB_ENTER) return DONE;
|
||||
if (c == 0x08) {
|
||||
t9_cell = -1; // invalidate any pending T9 cycle -- see the grid paths below
|
||||
if (cursor_pos > 0) {
|
||||
int n = kbUtf8LastCharBytes(buf, cursor_pos);
|
||||
memmove(buf + cursor_pos - n, buf + cursor_pos, len - cursor_pos);
|
||||
len -= n; cursor_pos -= n;
|
||||
buf[len] = '\0';
|
||||
}
|
||||
deleteBeforeCursor(); // also ends any pending T9 cycle -- see the grid paths below
|
||||
return NONE;
|
||||
}
|
||||
if (c >= 0x20 && c <= 0x7E) {
|
||||
@@ -1140,13 +1133,7 @@ struct KeyboardWidget {
|
||||
}
|
||||
// special row
|
||||
if (col == 0) {
|
||||
t9_cell = -1;
|
||||
if (cursor_pos > 0) {
|
||||
int n = kbUtf8LastCharBytes(buf, cursor_pos);
|
||||
memmove(buf + cursor_pos - n, buf + cursor_pos, len - cursor_pos);
|
||||
len -= n; cursor_pos -= n;
|
||||
buf[len] = '\0';
|
||||
}
|
||||
deleteBeforeCursor();
|
||||
} else if (col == 1) {
|
||||
pin_mode = false; // ABC switch: the user's own layout
|
||||
row = col = 0;
|
||||
@@ -1304,14 +1291,7 @@ struct KeyboardWidget {
|
||||
buf[len] = '\0';
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (cursor_pos > 0) {
|
||||
int n = kbUtf8LastCharBytes(buf, cursor_pos);
|
||||
memmove(buf + cursor_pos - n, buf + cursor_pos, len - cursor_pos);
|
||||
len -= n; cursor_pos -= n;
|
||||
buf[len] = '\0';
|
||||
}
|
||||
break;
|
||||
case 2: deleteBeforeCursor(); break;
|
||||
case 3:
|
||||
openPlaceholders();
|
||||
break;
|
||||
|
||||
@@ -1063,13 +1063,6 @@ public:
|
||||
_dm_hist_scroll = 0;
|
||||
_dm_fs.active = false;
|
||||
}
|
||||
// The display came back on over a conversation: what was filed while it was
|
||||
// dark is unread -- read on from its first message, as on opening.
|
||||
void onDisplayOn() {
|
||||
if (_ctx_menu.active) return;
|
||||
if (_phase == CHANNEL_HIST && !_fs.active && _history.chUnread(_sel_channel_idx) > 0) beginChannelView(_sel_channel_idx);
|
||||
else if (_phase == DM_HIST && !_dm_fs.active && _task->getDMUnread(_sel_contact.id.pub_key) > 0) beginDmView();
|
||||
}
|
||||
void beginChannelView(uint8_t channel_idx) {
|
||||
_sel_channel_idx = channel_idx;
|
||||
_unread_at_entry = (int)_history.chUnread(channel_idx);
|
||||
@@ -1081,6 +1074,13 @@ public:
|
||||
_hist_sel = _new_idx >= 0 ? _new_idx : _history.histCountForChannel(channel_idx) > 0 ? 0 : -1;
|
||||
_fs.active = false;
|
||||
}
|
||||
// The display came back on over a conversation: what was filed while it was
|
||||
// dark is unread -- read on from its first message, as on opening.
|
||||
void onDisplayOn() {
|
||||
if (_ctx_menu.active) return;
|
||||
if (_phase == CHANNEL_HIST && !_fs.active && _history.chUnread(_sel_channel_idx) > 0) beginChannelView(_sel_channel_idx);
|
||||
else if (_phase == DM_HIST && !_dm_fs.active && _task->getDMUnread(_sel_contact.id.pub_key) > 0) beginDmView();
|
||||
}
|
||||
|
||||
// On the first unread (sel), opening: the scroll showing it highest with
|
||||
// "New" above it (stack(s) lays out from s, sets div_y when "New" fits).
|
||||
|
||||
@@ -2280,13 +2280,14 @@ void UITask::pickBotRoomTarget() {
|
||||
MyMesh::Listener* UITask::meshListener() { return _core; }
|
||||
|
||||
// On screen: a conversation left open under the lock or a dark display isn't read.
|
||||
bool UITask::messagesInView() const {
|
||||
return curr == messages_screen && _display && _display->isOn() && !_locked;
|
||||
}
|
||||
bool UITask::isViewingChannel(uint8_t channel_idx) {
|
||||
return curr == messages_screen && _display && _display->isOn() && !_locked
|
||||
&& ((MessagesScreen*)messages_screen)->isViewingChannel(channel_idx);
|
||||
return messagesInView() && ((MessagesScreen*)messages_screen)->isViewingChannel(channel_idx);
|
||||
}
|
||||
bool UITask::isViewingDM(const uint8_t* pub_key) {
|
||||
return curr == messages_screen && _display && _display->isOn() && !_locked
|
||||
&& ((MessagesScreen*)messages_screen)->isViewingDM(pub_key);
|
||||
return messagesInView() && ((MessagesScreen*)messages_screen)->isViewingDM(pub_key);
|
||||
}
|
||||
void UITask::onViewedHistoryGrew(bool channel) {
|
||||
((MessagesScreen*)messages_screen)->onViewedHistoryGrew(channel);
|
||||
@@ -3170,8 +3171,8 @@ void UITask::loop() {
|
||||
pollConnection(); // BLE link state -> hasConnection() (see UITaskBase)
|
||||
drainCoreEvents(); // react to what the Core filed during mesh processing (alerts, wake, sounds)
|
||||
{ // a conversation in view again (display on, unlocked): on to what came in meanwhile
|
||||
bool on = _display && _display->isOn() && !_locked;
|
||||
if (on && !_display_was_on && curr == messages_screen) ((MessagesScreen*)messages_screen)->onDisplayOn();
|
||||
bool on = messagesInView();
|
||||
if (on && !_display_was_on) ((MessagesScreen*)messages_screen)->onDisplayOn();
|
||||
_display_was_on = on;
|
||||
}
|
||||
if (status_screen) ((StatusScreen*)status_screen)->sample(); // Status history lines, once a minute
|
||||
|
||||
@@ -60,10 +60,11 @@ class UITask : public UITaskBase, public UiCoreHost {
|
||||
GenericVibration vibration;
|
||||
#endif
|
||||
unsigned long _next_refresh, _auto_off;
|
||||
bool _display_was_on = true; // loop(): the display back on and unlocked
|
||||
bool _display_was_on = true; // loop(): messagesInView() last time round
|
||||
NodePrefs* _node_prefs;
|
||||
bool _locked;
|
||||
bool _tool_from_home = false;
|
||||
bool messagesInView() const; // Messages on a lit, unlocked display
|
||||
unsigned long _lock_wake_until; // when to blank screen again after locked wake (5s)
|
||||
int _lock_seq_count; // Enter presses while Back held (lock/unlock sequence)
|
||||
unsigned long _lock_seq_ms; // millis() of last lock-sequence press (for timeout)
|
||||
|
||||
Reference in New Issue
Block a user