mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
fix(ui): OLED joystick rotation — enforce reset after prefs rd()
The previous fix set joystick_rotation=0 before reading from file, but the subsequent rd() call overwrote it with whatever was stored (e.g. 2 from a prior e-ink firmware). Move the hardware-enforce block to after rd() so stale values in flash are always corrected on OLED builds (FEAT_JOYSTICK_ROTATION_SETTING=0). Remove the now-redundant pre-read block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -209,14 +209,6 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
|||||||
#ifdef DISPLAY_ROTATION
|
#ifdef DISPLAY_ROTATION
|
||||||
_prefs.display_rotation = DISPLAY_ROTATION;
|
_prefs.display_rotation = DISPLAY_ROTATION;
|
||||||
#endif
|
#endif
|
||||||
#ifdef JOYSTICK_ROTATION
|
|
||||||
_prefs.joystick_rotation = JOYSTICK_ROTATION;
|
|
||||||
#elif !FEAT_JOYSTICK_ROTATION_SETTING
|
|
||||||
// OLED: no rotation setting in UI — always reset to 0 so stale e-ink prefs
|
|
||||||
// (which could have a non-zero value) don't silently reverse the joystick.
|
|
||||||
_prefs.joystick_rotation = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
File file = openRead(_fs, filename);
|
File file = openRead(_fs, filename);
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
@@ -303,6 +295,13 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
|||||||
rd(&_prefs.display_rotation, sizeof(_prefs.display_rotation));
|
rd(&_prefs.display_rotation, sizeof(_prefs.display_rotation));
|
||||||
rd(_prefs.page_order, sizeof(_prefs.page_order));
|
rd(_prefs.page_order, sizeof(_prefs.page_order));
|
||||||
rd(&_prefs.joystick_rotation, sizeof(_prefs.joystick_rotation));
|
rd(&_prefs.joystick_rotation, sizeof(_prefs.joystick_rotation));
|
||||||
|
// Override any stale stored value — must come AFTER rd() so files that already
|
||||||
|
// have the field (e.g. migrated from e-ink with rotation=2) are also corrected.
|
||||||
|
#ifdef JOYSTICK_ROTATION
|
||||||
|
_prefs.joystick_rotation = JOYSTICK_ROTATION;
|
||||||
|
#elif !FEAT_JOYSTICK_ROTATION_SETTING
|
||||||
|
_prefs.joystick_rotation = 0;
|
||||||
|
#endif
|
||||||
rd(&_prefs.eink_full_refresh_every, sizeof(_prefs.eink_full_refresh_every));
|
rd(&_prefs.eink_full_refresh_every, sizeof(_prefs.eink_full_refresh_every));
|
||||||
rd(&_prefs.page_order_set, sizeof(_prefs.page_order_set));
|
rd(&_prefs.page_order_set, sizeof(_prefs.page_order_set));
|
||||||
// Migration: pre-magic firmware wrote page_order without a flag. If we see a plausible
|
// Migration: pre-magic firmware wrote page_order without a flag. If we see a plausible
|
||||||
|
|||||||
@@ -661,12 +661,8 @@ public:
|
|||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hist_box_h = 2 * lh + 1;
|
|
||||||
int hist_item_h = hist_box_h + 1;
|
|
||||||
int hist_start_y = display.headerH();
|
int hist_start_y = display.headerH();
|
||||||
int cby = display.height() - lh - 2;
|
int cby = display.height() - lh - 2;
|
||||||
_hist_visible = (cby - 1 - hist_start_y) / hist_item_h;
|
|
||||||
if (_hist_visible < 1) _hist_visible = 1;
|
|
||||||
|
|
||||||
char title[24];
|
char title[24];
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
@@ -677,10 +673,38 @@ public:
|
|||||||
int dm_count = dmHistCountForContact(_sel_contact.id.pub_key);
|
int dm_count = dmHistCountForContact(_sel_contact.id.pub_key);
|
||||||
uint32_t now_ts = rtc_clock.getCurrentTime();
|
uint32_t now_ts = rtc_clock.getCurrentTime();
|
||||||
|
|
||||||
for (int i = 0; i < _hist_visible && (_dm_hist_scroll + i) < dm_count; i++) {
|
// Portrait e-ink (height > width): variable-height boxes that show the full
|
||||||
|
// wrapped message text. All other displays/orientations: compact 2-line boxes.
|
||||||
|
bool portrait_expand = (display.height() > display.width());
|
||||||
|
const int MAX_VIS_BOXES = 8;
|
||||||
|
int box_ys[MAX_VIS_BOXES], box_hs[MAX_VIS_BOXES], n_vis = 0;
|
||||||
|
{
|
||||||
|
const int fixed_bh = 2 * lh + 1;
|
||||||
|
int cur_y = hist_start_y;
|
||||||
|
for (int ii = 0; ii < MAX_VIS_BOXES && (_dm_hist_scroll + ii) < dm_count; ii++) {
|
||||||
|
int bh = fixed_bh;
|
||||||
|
if (portrait_expand) {
|
||||||
|
int rp = dmHistEntryForContact(_sel_contact.id.pub_key, _dm_hist_scroll + ii);
|
||||||
|
if (rp >= 0) {
|
||||||
|
char trans[160];
|
||||||
|
display.translateUTF8ToBlocks(trans, skipReplyPrefix(_dm_hist[rp].text), sizeof(trans));
|
||||||
|
char wl[8][FS_CHARS_MAX];
|
||||||
|
int nl = FullscreenMsgView::wrapLines(display, trans, display.width() - 6, wl, 8);
|
||||||
|
bh = (1 + (nl > 0 ? nl : 1)) * lh + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur_y + bh > cby) break;
|
||||||
|
box_ys[n_vis] = cur_y; box_hs[n_vis] = bh; n_vis++;
|
||||||
|
cur_y += bh + (portrait_expand ? 2 : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_hist_visible = n_vis;
|
||||||
|
|
||||||
|
for (int i = 0; i < n_vis && (_dm_hist_scroll + i) < dm_count; i++) {
|
||||||
int item = _dm_hist_scroll + i;
|
int item = _dm_hist_scroll + i;
|
||||||
bool sel = (item == _dm_hist_sel);
|
bool sel = (item == _dm_hist_sel);
|
||||||
int y = hist_start_y + i * hist_item_h;
|
int y = box_ys[i];
|
||||||
|
int bh = box_hs[i];
|
||||||
|
|
||||||
int ring_pos = dmHistEntryForContact(_sel_contact.id.pub_key, item);
|
int ring_pos = dmHistEntryForContact(_sel_contact.id.pub_key, item);
|
||||||
if (ring_pos < 0) continue;
|
if (ring_pos < 0) continue;
|
||||||
@@ -693,19 +717,24 @@ public:
|
|||||||
|
|
||||||
if (sel) {
|
if (sel) {
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.fillRect(0, y, display.width(), hist_box_h);
|
display.fillRect(0, y, display.width(), bh);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.drawTextEllipsized(3, y + 1, display.width() - cw - 2 - age_w, sender);
|
|
||||||
if (age[0]) { display.setCursor(display.width() - age_w, y + 1); display.print(age); }
|
|
||||||
display.drawTextEllipsized(3, y + lh + 1, display.width() - cw - 2, skipReplyPrefix(e.text));
|
|
||||||
} else {
|
} else {
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.drawRect(0, y, display.width(), hist_box_h);
|
display.drawRect(0, y, display.width(), bh);
|
||||||
display.fillRect(1, y + 1, display.width() - 2, lh);
|
display.fillRect(1, y + 1, display.width() - 2, lh);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.drawTextEllipsized(3, y + 1, display.width() - cw - 2 - age_w, sender);
|
}
|
||||||
if (age[0]) { display.setCursor(display.width() - age_w, y + 1); display.print(age); }
|
display.drawTextEllipsized(3, y + 1, display.width() - cw - 2 - age_w, sender);
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
if (age[0]) { display.setCursor(display.width() - age_w, y + 1); display.print(age); }
|
||||||
|
if (!sel) display.setColor(DisplayDriver::LIGHT);
|
||||||
|
if (portrait_expand) {
|
||||||
|
char trans[160];
|
||||||
|
display.translateUTF8ToBlocks(trans, skipReplyPrefix(e.text), sizeof(trans));
|
||||||
|
char wl[8][FS_CHARS_MAX];
|
||||||
|
int nl = FullscreenMsgView::wrapLines(display, trans, display.width() - 6, wl, 8);
|
||||||
|
for (int li = 0; li < nl; li++) { display.setCursor(3, y + (li + 1) * lh + 1); display.print(wl[li]); }
|
||||||
|
} else {
|
||||||
display.drawTextEllipsized(3, y + lh + 1, display.width() - cw - 2, skipReplyPrefix(e.text));
|
display.drawTextEllipsized(3, y + lh + 1, display.width() - cw - 2, skipReplyPrefix(e.text));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -721,7 +750,8 @@ public:
|
|||||||
display.print("^");
|
display.print("^");
|
||||||
}
|
}
|
||||||
if (_dm_hist_scroll + _hist_visible < dm_count) {
|
if (_dm_hist_scroll + _hist_visible < dm_count) {
|
||||||
display.setCursor(display.width() - cw, hist_start_y + (_hist_visible - 1) * hist_item_h + hist_box_h - lh);
|
int arrow_y = (n_vis > 0) ? box_ys[n_vis - 1] + box_hs[n_vis - 1] - lh : hist_start_y;
|
||||||
|
display.setCursor(display.width() - cw, arrow_y);
|
||||||
display.print("v");
|
display.print("v");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,12 +794,8 @@ public:
|
|||||||
return 2000;
|
return 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hist_box_h = 2 * lh + 1;
|
|
||||||
int hist_item_h = hist_box_h + 1;
|
|
||||||
int hist_start_y = display.headerH();
|
int hist_start_y = display.headerH();
|
||||||
int cby = display.height() - lh - 2;
|
int cby = display.height() - lh - 2;
|
||||||
_hist_visible = (cby - 1 - hist_start_y) / hist_item_h;
|
|
||||||
if (_hist_visible < 1) _hist_visible = 1;
|
|
||||||
|
|
||||||
ChannelDetails ch;
|
ChannelDetails ch;
|
||||||
the_mesh.getChannel(_sel_channel_idx, ch);
|
the_mesh.getChannel(_sel_channel_idx, ch);
|
||||||
@@ -781,17 +807,48 @@ public:
|
|||||||
int ch_hist_count = histCountForChannel(_sel_channel_idx);
|
int ch_hist_count = histCountForChannel(_sel_channel_idx);
|
||||||
uint32_t now_ts = rtc_clock.getCurrentTime();
|
uint32_t now_ts = rtc_clock.getCurrentTime();
|
||||||
|
|
||||||
for (int i = 0; i < _hist_visible && (_hist_scroll + i) < ch_hist_count; i++) {
|
// Portrait e-ink (height > width): variable-height boxes that show the full
|
||||||
|
// wrapped message text. All other displays/orientations: compact 2-line boxes.
|
||||||
|
bool portrait_expand = (display.height() > display.width());
|
||||||
|
const int MAX_VIS_BOXES = 8;
|
||||||
|
int box_ys[MAX_VIS_BOXES], box_hs[MAX_VIS_BOXES], n_vis = 0;
|
||||||
|
{
|
||||||
|
const int fixed_bh = 2 * lh + 1;
|
||||||
|
int cur_y = hist_start_y;
|
||||||
|
for (int ii = 0; ii < MAX_VIS_BOXES && (_hist_scroll + ii) < ch_hist_count; ii++) {
|
||||||
|
int bh = fixed_bh;
|
||||||
|
if (portrait_expand) {
|
||||||
|
int rp = histEntryForChannel(_sel_channel_idx, _hist_scroll + ii);
|
||||||
|
if (rp >= 0) {
|
||||||
|
const char* rtext = _hist[rp].text;
|
||||||
|
const char* rsep = strstr(rtext, ": ");
|
||||||
|
const char* rbody = rsep ? rsep + 2 : rtext;
|
||||||
|
char trans[160];
|
||||||
|
display.translateUTF8ToBlocks(trans, skipReplyPrefix(rbody), sizeof(trans));
|
||||||
|
char wl[8][FS_CHARS_MAX];
|
||||||
|
int nl = FullscreenMsgView::wrapLines(display, trans, display.width() - 6, wl, 8);
|
||||||
|
bh = (1 + (nl > 0 ? nl : 1)) * lh + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur_y + bh > cby) break;
|
||||||
|
box_ys[n_vis] = cur_y; box_hs[n_vis] = bh; n_vis++;
|
||||||
|
cur_y += bh + (portrait_expand ? 2 : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_hist_visible = n_vis;
|
||||||
|
|
||||||
|
for (int i = 0; i < n_vis && (_hist_scroll + i) < ch_hist_count; i++) {
|
||||||
int item = _hist_scroll + i;
|
int item = _hist_scroll + i;
|
||||||
bool sel = (item == _hist_sel);
|
bool sel = (item == _hist_sel);
|
||||||
int y = hist_start_y + i * hist_item_h;
|
int y = box_ys[i];
|
||||||
|
int bh = box_hs[i];
|
||||||
|
|
||||||
int ring_pos = histEntryForChannel(_sel_channel_idx, item);
|
int ring_pos = histEntryForChannel(_sel_channel_idx, item);
|
||||||
if (ring_pos < 0) continue;
|
if (ring_pos < 0) continue;
|
||||||
|
|
||||||
const char* text = _hist[ring_pos].text;
|
const char* text = _hist[ring_pos].text;
|
||||||
const char* sep = strstr(text, ": ");
|
const char* sep = strstr(text, ": ");
|
||||||
char sender[22], msg_part[79];
|
char sender[22], msg_part[140];
|
||||||
if (sep) {
|
if (sep) {
|
||||||
int nl = sep - text; if (nl > 21) nl = 21;
|
int nl = sep - text; if (nl > 21) nl = 21;
|
||||||
strncpy(sender, text, nl); sender[nl] = '\0';
|
strncpy(sender, text, nl); sender[nl] = '\0';
|
||||||
@@ -808,19 +865,24 @@ public:
|
|||||||
|
|
||||||
if (sel) {
|
if (sel) {
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.fillRect(0, y, display.width(), hist_box_h);
|
display.fillRect(0, y, display.width(), bh);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.drawTextEllipsized(3, y + 1, display.width() - cw - 2 - age_w, sender);
|
|
||||||
if (age[0]) { display.setCursor(display.width() - age_w, y + 1); display.print(age); }
|
|
||||||
display.drawTextEllipsized(3, y + lh + 1, display.width() - cw - 2, skipReplyPrefix(msg_part));
|
|
||||||
} else {
|
} else {
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.drawRect(0, y, display.width(), hist_box_h);
|
display.drawRect(0, y, display.width(), bh);
|
||||||
display.fillRect(1, y + 1, display.width() - 2, lh);
|
display.fillRect(1, y + 1, display.width() - 2, lh);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.drawTextEllipsized(3, y + 1, display.width() - cw - 2 - age_w, sender);
|
}
|
||||||
if (age[0]) { display.setCursor(display.width() - age_w, y + 1); display.print(age); }
|
display.drawTextEllipsized(3, y + 1, display.width() - cw - 2 - age_w, sender);
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
if (age[0]) { display.setCursor(display.width() - age_w, y + 1); display.print(age); }
|
||||||
|
if (!sel) display.setColor(DisplayDriver::LIGHT);
|
||||||
|
if (portrait_expand) {
|
||||||
|
char trans[160];
|
||||||
|
display.translateUTF8ToBlocks(trans, skipReplyPrefix(msg_part), sizeof(trans));
|
||||||
|
char wl[8][FS_CHARS_MAX];
|
||||||
|
int nl = FullscreenMsgView::wrapLines(display, trans, display.width() - 6, wl, 8);
|
||||||
|
for (int li = 0; li < nl; li++) { display.setCursor(3, y + (li + 1) * lh + 1); display.print(wl[li]); }
|
||||||
|
} else {
|
||||||
display.drawTextEllipsized(3, y + lh + 1, display.width() - cw - 2, skipReplyPrefix(msg_part));
|
display.drawTextEllipsized(3, y + lh + 1, display.width() - cw - 2, skipReplyPrefix(msg_part));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -837,7 +899,8 @@ public:
|
|||||||
display.print("^");
|
display.print("^");
|
||||||
}
|
}
|
||||||
if (_hist_scroll + _hist_visible < ch_hist_count) {
|
if (_hist_scroll + _hist_visible < ch_hist_count) {
|
||||||
display.setCursor(display.width() - cw, hist_start_y + (_hist_visible - 1) * hist_item_h + hist_box_h - lh);
|
int arrow_y = (n_vis > 0) ? box_ys[n_vis - 1] + box_hs[n_vis - 1] - lh : hist_start_y;
|
||||||
|
display.setCursor(display.width() - cw, arrow_y);
|
||||||
display.print("v");
|
display.print("v");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1138,7 +1201,7 @@ public:
|
|||||||
ML[chNotifMelody(ch_idx)]); }
|
ML[chNotifMelody(ch_idx)]); }
|
||||||
{ NodePrefs* p2 = _task->getNodePrefs();
|
{ NodePrefs* p2 = _task->getNodePrefs();
|
||||||
bool is_fav = p2 && (p2->ch_fav_bitmask & (1ULL << ch_idx));
|
bool is_fav = p2 && (p2->ch_fav_bitmask & (1ULL << ch_idx));
|
||||||
snprintf(_ctx_ch_fav_item, sizeof(_ctx_ch_fav_item), is_fav ? "Unfav" : "Fav"); }
|
snprintf(_ctx_ch_fav_item, sizeof(_ctx_ch_fav_item), is_fav ? "Fav: yes" : "Fav: no"); }
|
||||||
_ctx_menu.begin("Channel options", 4);
|
_ctx_menu.begin("Channel options", 4);
|
||||||
_ctx_menu.addItem("Mark all read");
|
_ctx_menu.addItem("Mark all read");
|
||||||
_ctx_menu.addItem(_ctx_notif_item);
|
_ctx_menu.addItem(_ctx_notif_item);
|
||||||
|
|||||||
Reference in New Issue
Block a user