From 79d16e6ac12a3be7e331aae48b59ad7568c95363 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Fri, 3 Jan 2025 02:56:56 +0100 Subject: [PATCH 01/24] messagegui: refactor to a scroller handling many messages simultaneously --- apps/messagegui/ChangeLog | 1 + apps/messagegui/app.js | 181 +++++++++++++++++++++++++++++----- apps/messagegui/metadata.json | 2 +- 3 files changed, 161 insertions(+), 23 deletions(-) diff --git a/apps/messagegui/ChangeLog b/apps/messagegui/ChangeLog index 8df1075558..c6e7be674d 100644 --- a/apps/messagegui/ChangeLog +++ b/apps/messagegui/ChangeLog @@ -113,3 +113,4 @@ 0.82: Stop buzzing when a message is removed (e.g. call answered) 0.83: Add option to not open the first unread message 0.84: Fix: Assign show message entry to the settings menu and not the message itself. +0.85: (WIP) refactor to display a scroller with three messages loaded. When scrolling to the top or end new/older messages are loaded in. diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 21cd1c3e1a..be9b861313 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -90,7 +90,7 @@ var onMessagesModified = function(type,msg) { } if (msg && msg.id=="nav" && msg.t=="modify" && active!="map") return; // don't show an updated nav message if we're just in the menu - showMessage(msg&&msg.id, false); + showMessagesScroller(msg, false) }; Bangle.on("message", onMessagesModified); @@ -246,32 +246,169 @@ function showMusicMessage(msg) { }, 400); } -function showMessageScroller(msg) { - cancelReloadTimeout(); +function showMessagesScroller(msg, persist, alreadyProcessed) { + if (persist===undefined) {persist = true;} + const MSG_IDX = msg ? MESSAGES.findIndex((m)=>m.id==msg.id) : 0; + const INITIATED_FROM = ( + alreadyProcessed===undefined ? "other function" : + (MSG_IDX<=alreadyProcessed.idxSpan.start ? "scrolling up" : + (MSG_IDX >= alreadyProcessed.idxSpan.stop-1 ? "scrolling down" : + undefined)) + ); + if (!alreadyProcessed) {alreadyProcessed = {idxSpan:{}};} // So `alreadyProcessed.idxSpan.start/stop` can be looked for on first run. + + const WU = require("widget_utils"); + WU.hide(); + + if (replying) { return; } + if (persist) {cancelReloadTimeout();} else {resetReloadTimeout();} + + let idxSpan = ( + INITIATED_FROM==="other function" ? + {start : Math.max(MSG_IDX-1, 0), stop : Math.min(MSG_IDX+2, MESSAGES.length)} : + (INITIATED_FROM==="scrolling up" ? + {start : MSG_IDX, stop : alreadyProcessed.idxSpan.start } : + (INITIATED_FROM==="scrolling down" ? + { start : alreadyProcessed.idxSpan.stop, stop : Math.min(MSG_IDX+1, MESSAGES.length) } : + undefined)) + ); + active = "scroller"; var bodyFont = fontBig; g.setFont(bodyFont); - var lines = []; - if (msg.title) lines = g.wrapString(msg.title, g.getWidth()-10); - var titleCnt = lines.length; - if (titleCnt) lines.push(""); // add blank line after title - lines = lines.concat(g.wrapString(msg.body, g.getWidth()-10),["",/*LANG*/"< Back"]); + var titleLines = []; + var messagesWrapped = []; + for (let i=idxSpan.start ; i=MESSAGES.length) {break;} + continue; + } + + var lines = []; + const TITLE_STRING = msgLocal.title||msgLocal.sender||msgLocal.subject||msgLocal.src||"No Title"; + //const TITLE_STRING = "".concat(msgLocal.title, msgLocal.title&&"\n", + // msgLocal.sender, msgLocal.sender&&"\n", + // msgLocal.subject, msgLocal.subject&&"\n", msgLocal.src) || "No Title"; + lines = g.wrapString(TITLE_STRING, g.getWidth()-10); + for (let i=0; i x + allLines.length)); + allLines = allLines.concat(alreadyProcessed.lines); + } else if (INITIATED_FROM === "scrolling down") { + initScroll = alreadyProcessed.lines.length-(g.getHeight()/g.getFontHeight()); + titleLines = alreadyProcessed.titleLines.concat(titleLines. + map((x) => x + alreadyProcessed.lines.length)); + allLines = alreadyProcessed.lines.concat(allLines); + } + + if (allLines.length == 0 && alreadyProcessed.lines.length == 0) { + cancelReloadTimeout(); + returnToClockIfEmpty(); + } + + alreadyProcessed = { // Update with the newly processed messages. + lines : allLines, + titleLines : titleLines, + idxSpan: { + start : Math.min(idxSpan.start, + (alreadyProcessed.idxSpan.start===undefined) ? + MESSAGES.length : alreadyProcessed.idxSpan.start), + stop : Math.max(idxSpan.stop, alreadyProcessed.idxSpan.stop||0)} + }; + + function identifyDisplayedMsg(scrollIdx) { + let firstTitleLinePerMsg = [titleLines[0]]; + for (let i=1; i=0 ; i--) { + if (scrollIdx>=firstTitleLinePerMsg[i]) { + return MESSAGES[i + alreadyProcessed.idxSpan.start]; + } + } + } + + let prevScrollIdx; // Used for stopping repeated triggering of next message by the scroller. + let prevPrevScrollIdx; // Used to choose how to identify displayed message when selecting with button. + E.showScroller({ + scroll : initScroll*g.getFontHeight(), h : g.getFontHeight(), // height of each menu item in pixels - c : lines.length, // number of menu items + c : allLines.length, // number of menu items // a function to draw a menu item - draw : function(idx, r) { - // FIXME: in 2v13 onwards, clearRect(r) will work fine. There's a bug in 2v12 - g.setBgColor(idx=lines.length-2) - showMessage(msg.id, true); + draw : function(scrollIdx, r) { + "ram"; + g.setBgColor(titleLines.find(e=>e==scrollIdx)!==undefined ? g.theme.bg2 : g.theme.bg). + setColor(titleLines.find(e=>e==scrollIdx)!==undefined ? g.theme.fg2 : g.theme.fg). + clearRect(r); + g.setFont(bodyFont).setFontAlign(0,-1).drawString(allLines[scrollIdx], r.x+r.w/2, r.y); + // Load in next/previous message on demand by reinitializing showMessagesScroller while passing on the processed messages. + if (scrollIdx>=allLines.length-1 && scrollIdx!=prevScrollIdx && + alreadyProcessed.idxSpan.stop { + E.showScroller(); + if (BTN_WATCH) {clearWatch(BTN_WATCH);} + showMessagesScroller(MESSAGES[alreadyProcessed.idxSpan.stop], + true, alreadyProcessed); + }, 40); + } + if (scrollIdx==0 && scrollIdx!=prevScrollIdx && alreadyProcessed.idxSpan.start>0) { + setTimeout(() => { + E.showScroller(); + if (BTN_WATCH) {clearWatch(BTN_WATCH);} + showMessagesScroller(MESSAGES[alreadyProcessed.idxSpan.start-1], + true, alreadyProcessed); + }, 40); + } + if (prevPrevScrollIdx!==prevScrollIdx) {prevPrevScrollIdx = prevScrollIdx;} + prevScrollIdx = scrollIdx; }, - back : () => showMessage(msg.id, true) + select : function(scrollIdx, touch) { + const MSG_SELECT = identifyDisplayedMsg(scrollIdx); + if (touch.type == 0) { + WU.show(); + if (BTN_WATCH) {clearWatch(BTN_WATCH);} + showMessage(MSG_SELECT.id, true); + } + if (touch.type == 2) { + WU.show(); + if (BTN_WATCH) {clearWatch(BTN_WATCH);} + showMessageSettings(MSG_SELECT); + } + } }); + + const BTN_WATCH = setWatch(()=>{ + Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessage` screen is loaded. + // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. + setTimeout(()=>{const SCROLL_IDX_CENTER_SCREEN = prevScrollIdx>prevPrevScrollIdx ? + prevScrollIdx-5 : prevScrollIdx+5; // FIXME: `±5` should depend on screen height and font height. + WU.show(); + showMessage(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); + },0) + }, BTN, {edge:'rising'}); } function showMessageSettings(msg) { @@ -283,7 +420,7 @@ function showMessageSettings(msg) { }; if (msg.id!="music") - menu[/*LANG*/"View Message"] = () => showMessageScroller(msg); + menu[/*LANG*/"View Message"] = () => showMessagesScroller(msg); if (msg.reply && reply) { menu[/*LANG*/"Reply"] = () => { @@ -456,7 +593,7 @@ function showMessage(msgid, persist) { ]}, {type:"txt", font:bodyFont, label:body, fillx:1, filly:1, pad:2, cb:()=>{ // allow tapping to show a larger version - showMessageScroller(msg); + showMessagesScroller(msg); } }, {type:"h",fillx:1, c: footer} ]},{back:goBack}); @@ -502,7 +639,7 @@ function checkMessages(options) { // If we have a new message, show it if (!options.ignoreUnread && newMessages.length) { delete newMessages[0].show; // stop us getting stuck here if we're called a second time - showMessage(newMessages[0].id, false); + showMessagesScroller(newMessages[0], false); // buzz after showMessage, so being busy during layout doesn't affect the buzz pattern if (global.BUZZ_ON_NEW_MESSAGE) { // this is set if we entered the messages app by loading `messagegui.new.js` diff --git a/apps/messagegui/metadata.json b/apps/messagegui/metadata.json index 3e0538d9e6..e0f47c6bc3 100644 --- a/apps/messagegui/metadata.json +++ b/apps/messagegui/metadata.json @@ -2,7 +2,7 @@ "id": "messagegui", "name": "Message UI", "shortName": "Messages", - "version": "0.84", + "version": "0.85", "description": "Default app to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 43e343a61433e3cec40dca7a84bf8385f038530e Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Fri, 3 Jan 2025 23:59:59 +0100 Subject: [PATCH 02/24] messagegui: small refactor --- apps/messagegui/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index be9b861313..5f7eb0b354 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -403,8 +403,9 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { const BTN_WATCH = setWatch(()=>{ Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessage` screen is loaded. // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. + const ENTRIES_PER_HALF_SCREEN = (g.getHeight()/g.getFontHeight()) / 2; setTimeout(()=>{const SCROLL_IDX_CENTER_SCREEN = prevScrollIdx>prevPrevScrollIdx ? - prevScrollIdx-5 : prevScrollIdx+5; // FIXME: `±5` should depend on screen height and font height. + prevScrollIdx-ENTRIES_PER_HALF_SCREEN : prevScrollIdx+ENTRIES_PER_HALF_SCREEN; WU.show(); showMessage(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); },0) From 6884b5cd84a6c1c2927577543d799f0b221c7727 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 4 Jan 2025 01:36:51 +0100 Subject: [PATCH 03/24] messagegui: small refactor --- apps/messagegui/app.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 5f7eb0b354..9b46b5135c 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -279,26 +279,26 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { var titleLines = []; var messagesWrapped = []; for (let i=idxSpan.start ; i=MESSAGES.length) {break;} continue; } var lines = []; - const TITLE_STRING = msgLocal.title||msgLocal.sender||msgLocal.subject||msgLocal.src||"No Title"; - //const TITLE_STRING = "".concat(msgLocal.title, msgLocal.title&&"\n", - // msgLocal.sender, msgLocal.sender&&"\n", - // msgLocal.subject, msgLocal.subject&&"\n", msgLocal.src) || "No Title"; + const TITLE_STRING = MSG_ITER.title||MSG_ITER.sender||MSG_ITER.subject||MSG_ITER.src||"No Title"; + //const TITLE_STRING = "".concat(MSG_ITER.title, MSG_ITER.title&&"\n", + // MSG_ITER.sender, MSG_ITER.sender&&"\n", + // MSG_ITER.subject, MSG_ITER.subject&&"\n", MSG_ITER.src) || "No Title"; lines = g.wrapString(TITLE_STRING, g.getWidth()-10); for (let i=0; i Date: Sat, 4 Jan 2025 02:17:06 +0100 Subject: [PATCH 04/24] messagegui: store some func calls to vars for reuse --- apps/messagegui/app.js | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 9b46b5135c..46c51e53ca 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -257,10 +257,8 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { ); if (!alreadyProcessed) {alreadyProcessed = {idxSpan:{}};} // So `alreadyProcessed.idxSpan.start/stop` can be looked for on first run. - const WU = require("widget_utils"); - WU.hide(); - if (replying) { return; } + active = "scroller"; if (persist) {cancelReloadTimeout();} else {resetReloadTimeout();} let idxSpan = ( @@ -273,9 +271,14 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { undefined)) ); - active = "scroller"; + const WU = require("widget_utils"); + WU.hide(); + const APP_RECT = Bangle.appRect; + var bodyFont = fontBig; g.setFont(bodyFont); + const FONT_HEIGHT = g.getFontHeight(); + const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; var titleLines = []; var messagesWrapped = []; for (let i=idxSpan.start ; i x + allLines.length)); allLines = allLines.concat(alreadyProcessed.lines); } else if (INITIATED_FROM === "scrolling down") { - initScroll = alreadyProcessed.lines.length-(g.getHeight()/g.getFontHeight()); + initScroll = alreadyProcessed.lines.length-(LINES_PER_SCREEN); titleLines = alreadyProcessed.titleLines.concat(titleLines. map((x) => x + alreadyProcessed.lines.length)); allLines = alreadyProcessed.lines.concat(allLines); @@ -350,12 +353,13 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { } } - let prevScrollIdx; // Used for stopping repeated triggering of next message by the scroller. - let prevPrevScrollIdx; // Used to choose how to identify displayed message when selecting with button. + // Used for stopping repeated triggering of next message by the scroller and + // to choose how to identify displayed message when selecting with hw button. + let prevScrollIdxs = [undefined, undefined]; // [prevIdx, prevPrevIdx] E.showScroller({ - scroll : initScroll*g.getFontHeight(), - h : g.getFontHeight(), // height of each menu item in pixels + scroll : initScroll*FONT_HEIGHT, + h : FONT_HEIGHT, // height of each menu item in pixels c : allLines.length, // number of menu items // a function to draw a menu item draw : function(scrollIdx, r) { @@ -365,7 +369,7 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { clearRect(r); g.setFont(bodyFont).setFontAlign(0,-1).drawString(allLines[scrollIdx], r.x+r.w/2, r.y); // Load in next/previous message on demand by reinitializing showMessagesScroller while passing on the processed messages. - if (scrollIdx>=allLines.length-1 && scrollIdx!=prevScrollIdx && + if (scrollIdx>=allLines.length-1 && scrollIdx!=prevScrollIdxs[0] && alreadyProcessed.idxSpan.stop { E.showScroller(); @@ -374,7 +378,7 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { true, alreadyProcessed); }, 40); } - if (scrollIdx==0 && scrollIdx!=prevScrollIdx && alreadyProcessed.idxSpan.start>0) { + if (scrollIdx==0 && scrollIdx!=prevScrollIdxs[0] && alreadyProcessed.idxSpan.start>0) { setTimeout(() => { E.showScroller(); if (BTN_WATCH) {clearWatch(BTN_WATCH);} @@ -382,8 +386,8 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { true, alreadyProcessed); }, 40); } - if (prevPrevScrollIdx!==prevScrollIdx) {prevPrevScrollIdx = prevScrollIdx;} - prevScrollIdx = scrollIdx; + if (prevScrollIdxs[1]!==prevScrollIdxs[0]) {prevScrollIdxs[1] = prevScrollIdxs[0];} + prevScrollIdxs[0] = scrollIdx; }, select : function(scrollIdx, touch) { const MSG_SELECT = identifyDisplayedMsg(scrollIdx); @@ -403,9 +407,8 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { const BTN_WATCH = setWatch(()=>{ Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessage` screen is loaded. // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. - const ENTRIES_PER_HALF_SCREEN = (g.getHeight()/g.getFontHeight()) / 2; setTimeout(()=>{const SCROLL_IDX_CENTER_SCREEN = prevScrollIdx>prevPrevScrollIdx ? - prevScrollIdx-ENTRIES_PER_HALF_SCREEN : prevScrollIdx+ENTRIES_PER_HALF_SCREEN; + prevScrollIdx-LINES_PER_SCREEN/2 : prevScrollIdx+LINES_PER_SCREEN; WU.show(); showMessage(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); },0) From ca3e41a89df0354136934ee61ab7070b7c483eda Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 4 Jan 2025 02:28:31 +0100 Subject: [PATCH 05/24] messagegui: fix lint warn and some logic --- apps/messagegui/app.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 46c51e53ca..ba57661933 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -407,8 +407,9 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { const BTN_WATCH = setWatch(()=>{ Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessage` screen is loaded. // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. - setTimeout(()=>{const SCROLL_IDX_CENTER_SCREEN = prevScrollIdx>prevPrevScrollIdx ? - prevScrollIdx-LINES_PER_SCREEN/2 : prevScrollIdx+LINES_PER_SCREEN; + setTimeout(()=>{ + const SCROLL_IDX_CENTER_SCREEN = prevScrollIdxs[0]>prevScrollIdxs[1] ? + prevScrollIdxs[0]-LINES_PER_SCREEN/2:prevScrollIdxs[0]+LINES_PER_SCREEN/2; WU.show(); showMessage(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); },0) From a6eb3369516b52240912a1453c3b35c8188a23e3 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 4 Jan 2025 03:11:10 +0100 Subject: [PATCH 06/24] messagegui: refactoring... --- apps/messagegui/app.js | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index ba57661933..f9db5f0721 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -357,6 +357,19 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { // to choose how to identify displayed message when selecting with hw button. let prevScrollIdxs = [undefined, undefined]; // [prevIdx, prevPrevIdx] + function shouldAddNext(scrollIdx) {"ram"; return (scrollIdx>=allLines.length-1 && + scrollIdx!=prevScrollIdxs[0] && alreadyProcessed.idxSpan.stop0)} + function reinitAdding(idx) { + setTimeout(() => { + E.showScroller(); + if (BTN_WATCH) {clearWatch(BTN_WATCH);} + showMessagesScroller(MESSAGES[idx], + true, alreadyProcessed); + }, 40); + } + E.showScroller({ scroll : initScroll*FONT_HEIGHT, h : FONT_HEIGHT, // height of each menu item in pixels @@ -369,23 +382,8 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { clearRect(r); g.setFont(bodyFont).setFontAlign(0,-1).drawString(allLines[scrollIdx], r.x+r.w/2, r.y); // Load in next/previous message on demand by reinitializing showMessagesScroller while passing on the processed messages. - if (scrollIdx>=allLines.length-1 && scrollIdx!=prevScrollIdxs[0] && - alreadyProcessed.idxSpan.stop { - E.showScroller(); - if (BTN_WATCH) {clearWatch(BTN_WATCH);} - showMessagesScroller(MESSAGES[alreadyProcessed.idxSpan.stop], - true, alreadyProcessed); - }, 40); - } - if (scrollIdx==0 && scrollIdx!=prevScrollIdxs[0] && alreadyProcessed.idxSpan.start>0) { - setTimeout(() => { - E.showScroller(); - if (BTN_WATCH) {clearWatch(BTN_WATCH);} - showMessagesScroller(MESSAGES[alreadyProcessed.idxSpan.start-1], - true, alreadyProcessed); - }, 40); - } + if (shouldAddNext(scrollIdx)) {reinitAdding(alreadyProcessed.idxSpan.stop);} + if (shouldAddPrev(scrollIdx)) {reinitAdding(alreadyProcessed.idxSpan.start-1);} if (prevScrollIdxs[1]!==prevScrollIdxs[0]) {prevScrollIdxs[1] = prevScrollIdxs[0];} prevScrollIdxs[0] = scrollIdx; }, From a8133ad2daf07d97d477f31c57c622bdcca4f74a Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 4 Jan 2025 03:44:02 +0100 Subject: [PATCH 07/24] messagegui: refactoring more --- apps/messagegui/app.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index f9db5f0721..fb664ef525 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -364,7 +364,7 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { function reinitAdding(idx) { setTimeout(() => { E.showScroller(); - if (BTN_WATCH) {clearWatch(BTN_WATCH);} + if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT);} showMessagesScroller(MESSAGES[idx], true, alreadyProcessed); }, 40); @@ -388,30 +388,26 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { prevScrollIdxs[0] = scrollIdx; }, select : function(scrollIdx, touch) { + WU.show(); const MSG_SELECT = identifyDisplayedMsg(scrollIdx); - if (touch.type == 0) { - WU.show(); - if (BTN_WATCH) {clearWatch(BTN_WATCH);} - showMessage(MSG_SELECT.id, true); - } - if (touch.type == 2) { - WU.show(); - if (BTN_WATCH) {clearWatch(BTN_WATCH);} - showMessageSettings(MSG_SELECT); - } + if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT);} + if (!touch) {showMessage(MSG_SELECT.id,true); return} + if (touch.type == 0) {showMessage(MSG_SELECT.id,true);} + if (touch.type == 2) {showMessageSettings(MSG_SELECT);} } }); - const BTN_WATCH = setWatch(()=>{ + // If Bangle.js 2 add an external select hw button handler. + const BTN_EXT_SELECT = ((2===process.env.HWVERSION) && (setWatch(()=>{ Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessage` screen is loaded. // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ const SCROLL_IDX_CENTER_SCREEN = prevScrollIdxs[0]>prevScrollIdxs[1] ? - prevScrollIdxs[0]-LINES_PER_SCREEN/2:prevScrollIdxs[0]+LINES_PER_SCREEN/2; + prevScrollIdxs[0]-LINES_PER_SCREEN/2:prevScrollIdxs[0]+LINES_PER_SCREEN/2; WU.show(); showMessage(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); },0) - }, BTN, {edge:'rising'}); + }, BTN, {edge:'rising'}))); } function showMessageSettings(msg) { From a3c98415dc3961dc08b962e7e68f6b989d025a9c Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sun, 12 Jan 2025 23:57:55 +0100 Subject: [PATCH 08/24] messagegui: more refinement, some refactoring --- apps/messagegui/app.js | 93 ++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index fb664ef525..6cb4890398 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -90,7 +90,7 @@ var onMessagesModified = function(type,msg) { } if (msg && msg.id=="nav" && msg.t=="modify" && active!="map") return; // don't show an updated nav message if we're just in the menu - showMessagesScroller(msg, false) + showMessage(msg, "modified"); }; Bangle.on("message", onMessagesModified); @@ -99,6 +99,27 @@ function saveMessages() { } E.on("kill", saveMessages); +function showMessage(msg, calledFrom) { + ////var active; // active screen (undefined/"list"/"music"/"map"/"message"/"scroller"/"settings") + //if (active==undefined) { } else if (active=="list") ... //and so on. + + if (msg.id=="music") { + cancelReloadTimeout(); // don't auto-reload to clock now + return showMusicMessage(msg); + } + if (msg.id=="nav") { + cancelReloadTimeout(); // don't auto-reload to clock now + return showMapMessage(msg); + } + if (calledFrom=="modified" && active=="scroller") { // reinit scroller with updated messages list. + return showMessagesScroller(msg); + } + if (calledFrom=="scrollerSelect") { + return showMessageOverview(msg.id); + } + //if (false) {showMessageSettings(msg);} +} + function showMapMessage(msg) { active = "map"; require("messages").stopBuzz(); // stop repeated buzzing while the map is showing @@ -248,19 +269,20 @@ function showMusicMessage(msg) { function showMessagesScroller(msg, persist, alreadyProcessed) { if (persist===undefined) {persist = true;} - const MSG_IDX = msg ? MESSAGES.findIndex((m)=>m.id==msg.id) : 0; + const MSG_IDX = msg ? MESSAGES.findIndex((m)=>m.id==msg.id) : undefined; const INITIATED_FROM = ( alreadyProcessed===undefined ? "other function" : (MSG_IDX<=alreadyProcessed.idxSpan.start ? "scrolling up" : (MSG_IDX >= alreadyProcessed.idxSpan.stop-1 ? "scrolling down" : undefined)) ); - if (!alreadyProcessed) {alreadyProcessed = {idxSpan:{}};} // So `alreadyProcessed.idxSpan.start/stop` can be looked for on first run. if (replying) { return; } active = "scroller"; if (persist) {cancelReloadTimeout();} else {resetReloadTimeout();} + if (!alreadyProcessed) {alreadyProcessed = {idxSpan:{}};} // So `alreadyProcessed.idxSpan.start/stop` can be looked for on first run. + let idxSpan = ( INITIATED_FROM==="other function" ? {start : Math.max(MSG_IDX-1, 0), stop : Math.min(MSG_IDX+2, MESSAGES.length)} : @@ -285,17 +307,14 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { let MSG_ITER = MESSAGES[i]; MSG_ITER.new = false; - if (MSG_ITER.id=="music" || MSG_ITER.source=="maps" || MSG_ITER.id =="call") { - idxSpan.stop++ - if (idxSpan.stop>=MESSAGES.length) {break;} - continue; - } + //if (/*MSG_ITER.id=="music" ||*/ MSG_ITER.source=="maps" || MSG_ITER.id =="call") { + // idxSpan.stop++ + // if (idxSpan.stop>=MESSAGES.length) {break;} + // continue; + //} var lines = []; - const TITLE_STRING = MSG_ITER.title||MSG_ITER.sender||MSG_ITER.subject||MSG_ITER.src||"No Title"; - //const TITLE_STRING = "".concat(MSG_ITER.title, MSG_ITER.title&&"\n", - // MSG_ITER.sender, MSG_ITER.sender&&"\n", - // MSG_ITER.subject, MSG_ITER.subject&&"\n", MSG_ITER.src) || "No Title"; + const TITLE_STRING = MSG_ITER.title||MSG_ITER.sender||MSG_ITER.subject||MSG_ITER.src||/*LANG*/"No Title"; lines = g.wrapString(TITLE_STRING, APP_RECT.w-10); for (let i=0; i0)} function reinitAdding(idx) { setTimeout(() => { - E.showScroller(); - if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT);} - showMessagesScroller(MESSAGES[idx], - true, alreadyProcessed); + Bangle.emit("drag", {dy:0}); // Make sure scrolling doesn't continue after reinit. + // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. + setTimeout(()=>{ + E.showScroller(); + if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT); delete BTN_EXT_SELECT;} + showMessagesScroller(MESSAGES[idx], + true, alreadyProcessed); + },0) }, 40); } @@ -390,22 +413,22 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { select : function(scrollIdx, touch) { WU.show(); const MSG_SELECT = identifyDisplayedMsg(scrollIdx); - if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT);} - if (!touch) {showMessage(MSG_SELECT.id,true); return} - if (touch.type == 0) {showMessage(MSG_SELECT.id,true);} + if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT); delete BTN_EXT_SELECT} + if (!touch) {showMessage(MSG_SELECT, "scrollerSelect"); return} + if (touch.type == 0) {showMessage(MSG_SELECT,"scrollerSelect");} if (touch.type == 2) {showMessageSettings(MSG_SELECT);} } }); // If Bangle.js 2 add an external select hw button handler. const BTN_EXT_SELECT = ((2===process.env.HWVERSION) && (setWatch(()=>{ - Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessage` screen is loaded. + Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessageOverview` screen is loaded. // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ const SCROLL_IDX_CENTER_SCREEN = prevScrollIdxs[0]>prevScrollIdxs[1] ? prevScrollIdxs[0]-LINES_PER_SCREEN/2:prevScrollIdxs[0]+LINES_PER_SCREEN/2; WU.show(); - showMessage(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); + showMessageOverview(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); },0) }, BTN, {edge:'rising'}))); } @@ -414,7 +437,7 @@ function showMessageSettings(msg) { active = "settings"; var menu = {"":{ "title":/*LANG*/"Message", - back:() => showMessage(msg.id, true) + back:() => showMessageOverview(msg.id, true) }, }; @@ -428,11 +451,11 @@ function showMessageSettings(msg) { .then(result => { Bluetooth.println(JSON.stringify(result)); replying = false; - showMessage(msg.id); + showMessageOverview(msg.id); }) .catch(() => { replying = false; - showMessage(msg.id); + showMessageOverview(msg.id); }); }; } @@ -476,7 +499,7 @@ function showMessageSettings(msg) { E.showMenu(menu); } -function showMessage(msgid, persist) { +function showMessageOverview(msgid, persist) { if (replying) { return; } if(!persist) resetReloadTimeout(); let idx = MESSAGES.findIndex(m=>m.id==msgid); @@ -486,14 +509,6 @@ function showMessage(msgid, persist) { updateLabelsInterval=undefined; } if (!msg) return returnToClockIfEmpty(); // go home if no message found - if (msg.id=="music") { - cancelReloadTimeout(); // don't auto-reload to clock now - return showMusicMessage(msg); - } - if (msg.id=="nav") { - cancelReloadTimeout(); // don't auto-reload to clock now - return showMapMessage(msg); - } active = "message"; // Normal text message display var title=msg.title, titleFont = fontLarge, lines; @@ -562,7 +577,7 @@ function showMessage(msgid, persist) { .catch(() => { replying = false; layout.render(); - showMessage(msg.id); + showMessageOverview(msg.id); }); }; footer.push({type:"img",src:atob("QRABAAAAAAAH//+AAAAABgP//8AAAAADgf//4AAAAAHg4ABwAAAAAPh8APgAAAAAfj+B////////geHv///////hf+f///////GPw///////8cGBwAAAAAPx/gDgAAAAAfD/gHAAAAAA8DngOAAAAABwDHP8AAAAADACGf4AAAAAAAAM/w=="),col:"#0f0", cb:posHandler}); } @@ -600,8 +615,8 @@ function showMessage(msgid, persist) { Bangle.swipeHandler = (lr,ud) => { if (lr>0 && posHandler) posHandler(); if (lr<0 && negHandler) negHandler(); - if (ud>0 && idx0) showMessage(MESSAGES[idx-1].id, true); + if (ud>0 && idx0) showMessageOverview(MESSAGES[idx-1].id, true); }; Bangle.on("swipe", Bangle.swipeHandler); g.reset().clearRect(Bangle.appRect); @@ -639,7 +654,7 @@ function checkMessages(options) { if (!options.ignoreUnread && newMessages.length) { delete newMessages[0].show; // stop us getting stuck here if we're called a second time showMessagesScroller(newMessages[0], false); - // buzz after showMessage, so being busy during layout doesn't affect the buzz pattern + // buzz after showMessagesScroller, so being busy during scroller setup doesn't affect the buzz pattern if (global.BUZZ_ON_NEW_MESSAGE) { // this is set if we entered the messages app by loading `messagegui.new.js` // ... but only buzz the first time we view a new message @@ -651,7 +666,7 @@ function checkMessages(options) { } // no new messages: show playing music? Only if we have playing music, or state=="show" (set by messagesmusic) if (options.openMusic && MESSAGES.some(m=>m.id=="music" && ((m.track && m.state=="play") || m.state=="show"))) - return showMessage('music', true); + return showMessageOverview('music', true); // no new messages - go to clock? if (options.clockIfAllRead && newMessages.length==0) return load(); @@ -700,7 +715,7 @@ function checkMessages(options) { }, select : idx => { if (idx < MESSAGES.length) - showMessage(MESSAGES[idx].id, true); + showMessageOverview(MESSAGES[idx].id, true); }, back : () => load() }); From 3445f7ffdd92ae509709b9269b7ad82309db0a87 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 22 Jan 2025 20:58:16 +0100 Subject: [PATCH 09/24] messagegui: tweaks and refactor --- apps/messagegui/app.js | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 6cb4890398..a239a43dc4 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -90,7 +90,7 @@ var onMessagesModified = function(type,msg) { } if (msg && msg.id=="nav" && msg.t=="modify" && active!="map") return; // don't show an updated nav message if we're just in the menu - showMessage(msg, "modified"); + showMessageRouter(msg, "modified"); }; Bangle.on("message", onMessagesModified); @@ -99,7 +99,7 @@ function saveMessages() { } E.on("kill", saveMessages); -function showMessage(msg, calledFrom) { +function showMessageRouter(msg, calledFrom) { ////var active; // active screen (undefined/"list"/"music"/"map"/"message"/"scroller"/"settings") //if (active==undefined) { } else if (active=="list") ... //and so on. @@ -117,6 +117,9 @@ function showMessage(msg, calledFrom) { if (calledFrom=="scrollerSelect") { return showMessageOverview(msg.id); } + if (msg.id=="call") { + return showMessageOverview(msg.id); + } //if (false) {showMessageSettings(msg);} } @@ -304,23 +307,23 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { var titleLines = []; var messagesWrapped = []; for (let i=idxSpan.start ; i=MESSAGES.length) {break;} // continue; //} var lines = []; - const TITLE_STRING = MSG_ITER.title||MSG_ITER.sender||MSG_ITER.subject||MSG_ITER.src||/*LANG*/"No Title"; + const TITLE_STRING = msgIter.title||msgIter.sender||msgIter.subject||msgIter.src||/*LANG*/"No Title"; lines = g.wrapString(TITLE_STRING, APP_RECT.w-10); for (let i=0; i x + alreadyProcessed.lines.length)); allLines = alreadyProcessed.lines.concat(allLines); } + initScroll = initScroll*FONT_HEIGHT; if (allLines.length == 0 && alreadyProcessed.lines.length == 0) { cancelReloadTimeout(); @@ -377,29 +381,28 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { let prevScrollIdxs = [undefined, undefined]; // [prevIdx, prevPrevIdx] function shouldAddNext(scrollIdx) {"ram"; return (scrollIdx>=allLines.length-1 && - scrollIdx!=prevScrollIdxs[0] && alreadyProcessed.idxSpan.stop0)} + scrollIdx!=prevScrollIdxs[0] && alreadyProcessed.idxSpan.start>0);} function reinitAdding(idx) { setTimeout(() => { - Bangle.emit("drag", {dy:0}); // Make sure scrolling doesn't continue after reinit. + Bangle.emit("drag", {dy:0}); // Make sure scrolling doesn't continue after reinit. FIXME: Is this a hack that begs for a bug being fixed elsewhere? // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ E.showScroller(); if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT); delete BTN_EXT_SELECT;} showMessagesScroller(MESSAGES[idx], true, alreadyProcessed); - },0) + },0); }, 40); } E.showScroller({ - scroll : initScroll*FONT_HEIGHT, + scroll : initScroll, h : FONT_HEIGHT, // height of each menu item in pixels c : allLines.length, // number of menu items // a function to draw a menu item - draw : function(scrollIdx, r) { - "ram"; + draw : function(scrollIdx, r) {"ram"; g.setBgColor(titleLines.find(e=>e==scrollIdx)!==undefined ? g.theme.bg2 : g.theme.bg). setColor(titleLines.find(e=>e==scrollIdx)!==undefined ? g.theme.fg2 : g.theme.fg). clearRect(r); @@ -413,9 +416,9 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { select : function(scrollIdx, touch) { WU.show(); const MSG_SELECT = identifyDisplayedMsg(scrollIdx); - if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT); delete BTN_EXT_SELECT} - if (!touch) {showMessage(MSG_SELECT, "scrollerSelect"); return} - if (touch.type == 0) {showMessage(MSG_SELECT,"scrollerSelect");} + if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT); delete BTN_EXT_SELECT;} + if (!touch) {showMessageRouter(MSG_SELECT, "scrollerSelect"); return;} + if (touch.type == 0) {showMessageRouter(MSG_SELECT,"scrollerSelect");} if (touch.type == 2) {showMessageSettings(MSG_SELECT);} } }); @@ -429,7 +432,7 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { prevScrollIdxs[0]-LINES_PER_SCREEN/2:prevScrollIdxs[0]+LINES_PER_SCREEN/2; WU.show(); showMessageOverview(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); - },0) + },0); }, BTN, {edge:'rising'}))); } @@ -675,7 +678,7 @@ function checkMessages(options) { E.showScroller({ h : 48, c : Math.max(MESSAGES.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) - draw : function(idx, r) {"ram" + draw : function(idx, r) {"ram"; var msg = MESSAGES[idx]; if (msg && msg.new) g.setBgColor(g.theme.bgH).setColor(g.theme.fgH); else g.setBgColor(g.theme.bg).setColor(g.theme.fg); From 155cf87e807d63195f5ecab1571e625fdcefa28a Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Fri, 24 Jan 2025 21:18:46 +0100 Subject: [PATCH 10/24] messagegui: fix clear hw btn handler, etc --- apps/messagegui/app.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index a239a43dc4..1b6fa4c1e9 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -390,7 +390,7 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ E.showScroller(); - if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT); delete BTN_EXT_SELECT;} + clearBtnHandler(); showMessagesScroller(MESSAGES[idx], true, alreadyProcessed); },0); @@ -416,18 +416,24 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { select : function(scrollIdx, touch) { WU.show(); const MSG_SELECT = identifyDisplayedMsg(scrollIdx); - if (BTN_EXT_SELECT) {clearWatch(BTN_EXT_SELECT); delete BTN_EXT_SELECT;} + clearBtnHandler(); if (!touch) {showMessageRouter(MSG_SELECT, "scrollerSelect"); return;} if (touch.type == 0) {showMessageRouter(MSG_SELECT,"scrollerSelect");} if (touch.type == 2) {showMessageSettings(MSG_SELECT);} } }); + function clearBtnHandler() { + if (Bangle.btnHandler) {clearWatch(Bangle.btnHandler); Bangle.btnHandler=undefined;} + } + clearBtnHandler(); + // If Bangle.js 2 add an external select hw button handler. - const BTN_EXT_SELECT = ((2===process.env.HWVERSION) && (setWatch(()=>{ + Bangle.btnHandler = ((2===process.env.HWVERSION) && (setWatch(()=>{ Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessageOverview` screen is loaded. // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ + if ("messagegui.new.js"===global.__FILE__) {return load();} const SCROLL_IDX_CENTER_SCREEN = prevScrollIdxs[0]>prevScrollIdxs[1] ? prevScrollIdxs[0]-LINES_PER_SCREEN/2:prevScrollIdxs[0]+LINES_PER_SCREEN/2; WU.show(); From 6c939fa6b65d861709beff84d943924fcbf7a30a Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Fri, 24 Jan 2025 22:47:37 +0100 Subject: [PATCH 11/24] messagegui: reset unread timeout when scrolling --- apps/messagegui/app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 1b6fa4c1e9..6cfceb6c0f 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -410,7 +410,10 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { // Load in next/previous message on demand by reinitializing showMessagesScroller while passing on the processed messages. if (shouldAddNext(scrollIdx)) {reinitAdding(alreadyProcessed.idxSpan.stop);} if (shouldAddPrev(scrollIdx)) {reinitAdding(alreadyProcessed.idxSpan.start-1);} - if (prevScrollIdxs[1]!==prevScrollIdxs[0]) {prevScrollIdxs[1] = prevScrollIdxs[0];} + if (prevScrollIdxs[1]!==prevScrollIdxs[0]) { + prevScrollIdxs[1] = prevScrollIdxs[0]; + if (!persist) {resetReloadTimeout();} + } prevScrollIdxs[0] = scrollIdx; }, select : function(scrollIdx, touch) { From 9807d60085e26eedc8ea7e66e904403bacf0348f Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 25 Jan 2025 10:48:56 +0100 Subject: [PATCH 12/24] messagegui: retain persist bool info on scroller reinit --- apps/messagegui/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 6cfceb6c0f..d92df7e53a 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -392,7 +392,7 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { E.showScroller(); clearBtnHandler(); showMessagesScroller(MESSAGES[idx], - true, alreadyProcessed); + persist, alreadyProcessed); },0); }, 40); } From 31a6c55f92388d826da67f565da843f025e8347a Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 25 Jan 2025 11:12:23 +0100 Subject: [PATCH 13/24] messagegui: fix some logic. --- apps/messagegui/app.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index d92df7e53a..c0e39e174a 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -90,7 +90,7 @@ var onMessagesModified = function(type,msg) { } if (msg && msg.id=="nav" && msg.t=="modify" && active!="map") return; // don't show an updated nav message if we're just in the menu - showMessageRouter(msg, "modified"); + showMessageRouter(msg, true, "modified"); }; Bangle.on("message", onMessagesModified); @@ -99,7 +99,7 @@ function saveMessages() { } E.on("kill", saveMessages); -function showMessageRouter(msg, calledFrom) { +function showMessageRouter(msg, persist, calledFrom) { ////var active; // active screen (undefined/"list"/"music"/"map"/"message"/"scroller"/"settings") //if (active==undefined) { } else if (active=="list") ... //and so on. @@ -112,13 +112,13 @@ function showMessageRouter(msg, calledFrom) { return showMapMessage(msg); } if (calledFrom=="modified" && active=="scroller") { // reinit scroller with updated messages list. - return showMessagesScroller(msg); + return showMessagesScroller(msg, persist); } if (calledFrom=="scrollerSelect") { - return showMessageOverview(msg.id); + return showMessageOverview(msg.id, persist); } if (msg.id=="call") { - return showMessageOverview(msg.id); + return showMessageOverview(msg.id, persist); } //if (false) {showMessageSettings(msg);} } @@ -420,8 +420,8 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { WU.show(); const MSG_SELECT = identifyDisplayedMsg(scrollIdx); clearBtnHandler(); - if (!touch) {showMessageRouter(MSG_SELECT, "scrollerSelect"); return;} - if (touch.type == 0) {showMessageRouter(MSG_SELECT,"scrollerSelect");} + if (!touch) {showMessageRouter(MSG_SELECT, true, "scrollerSelect"); return;} + if (touch.type == 0) {showMessageRouter(MSG_SELECT, true, "scrollerSelect");} if (touch.type == 2) {showMessageSettings(MSG_SELECT);} } }); From bb92ddd8dc769709b19e782a3028b64c9c578ef2 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 25 Jan 2025 11:41:46 +0100 Subject: [PATCH 14/24] messagegui: persist on msgs modified depends on __FILE__ --- apps/messagegui/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index c0e39e174a..6ac34dc017 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -90,7 +90,8 @@ var onMessagesModified = function(type,msg) { } if (msg && msg.id=="nav" && msg.t=="modify" && active!="map") return; // don't show an updated nav message if we're just in the menu - showMessageRouter(msg, true, "modified"); + let persist = "messagegui.new.js"===global.__FILE__?false:true; + showMessageRouter(msg, persist, "modified"); }; Bangle.on("message", onMessagesModified); From f1c74ece1b2861e6cffee9c015fa329698a67ec4 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 25 Jan 2025 11:48:06 +0100 Subject: [PATCH 15/24] messagegui: make sure to cancel unread timeout if persist --- apps/messagegui/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 6ac34dc017..c101ae7538 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -104,6 +104,8 @@ function showMessageRouter(msg, persist, calledFrom) { ////var active; // active screen (undefined/"list"/"music"/"map"/"message"/"scroller"/"settings") //if (active==undefined) { } else if (active=="list") ... //and so on. + if (persist) {cancelReloadTimeout()} + if (msg.id=="music") { cancelReloadTimeout(); // don't auto-reload to clock now return showMusicMessage(msg); From d6e9c9c273450f3134a9e4e8fd60a97680658256 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 25 Jan 2025 22:18:02 +0100 Subject: [PATCH 16/24] messagegui: fix open music interface on select from list --- apps/messagegui/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index c101ae7538..31ee38d33f 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -730,7 +730,7 @@ function checkMessages(options) { }, select : idx => { if (idx < MESSAGES.length) - showMessageOverview(MESSAGES[idx].id, true); + showMessageRouter(MESSAGES[idx], true); }, back : () => load() }); From d2d0bb5302811217cb99e85a204e35cdd909ae0e Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 25 Jan 2025 23:49:26 +0100 Subject: [PATCH 17/24] messagegui: tweaks --- apps/messagegui/app.js | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 31ee38d33f..dc407f0149 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -45,7 +45,7 @@ if (Graphics.prototype.setFontIntl) { fontVLarge = noScale?"Intl":"Intl:3"; } -var active; // active screen (undefined/"list"/"music"/"map"/"message"/"scroller"/"settings") +var active; // active screen (undefined/"list"/"music"/"map"/"overview"/"scroller"/"settings") var openMusic = false; // go back to music screen after we handle something else? var replying = false; // If we're replying to a message, don't interrupt // hack for 2v10 firmware's lack of ':size' font handling @@ -91,7 +91,7 @@ var onMessagesModified = function(type,msg) { if (msg && msg.id=="nav" && msg.t=="modify" && active!="map") return; // don't show an updated nav message if we're just in the menu let persist = "messagegui.new.js"===global.__FILE__?false:true; - showMessageRouter(msg, persist, "modified"); + showMessageRouter(msg, persist, "dependsOnActive"); }; Bangle.on("message", onMessagesModified); @@ -100,8 +100,10 @@ function saveMessages() { } E.on("kill", saveMessages); -function showMessageRouter(msg, persist, calledFrom) { - ////var active; // active screen (undefined/"list"/"music"/"map"/"message"/"scroller"/"settings") +function showMessageRouter(msg, persist, explicitDestnation) { + //explicitDestnation (undefined/"scroller"/"overview"/"dependsOnActive") + + ////var active; // active screen (undefined/"list"/"music"/"map"/"overview"/"scroller"/"settings") //if (active==undefined) { } else if (active=="list") ... //and so on. if (persist) {cancelReloadTimeout()} @@ -114,14 +116,19 @@ function showMessageRouter(msg, persist, calledFrom) { cancelReloadTimeout(); // don't auto-reload to clock now return showMapMessage(msg); } - if (calledFrom=="modified" && active=="scroller") { // reinit scroller with updated messages list. + if (msg.id=="call") { + return showMessageOverview(msg.id, persist); + } + if ("scroller"===explicitDestnation) { return showMessagesScroller(msg, persist); } - if (calledFrom=="scrollerSelect") { + if ("overview"===explicitDestnation) { return showMessageOverview(msg.id, persist); } - if (msg.id=="call") { - return showMessageOverview(msg.id, persist); + if ("dependsOnActive"===explicitDestnation) { + if ("scroller"===active) {return showMessagesScroller(msg, persist);} // reinit scroller with updated messages list. + if ("list"===active) {return returnToMain();} + if ("settings"===active || "overview"===active) {return;} } //if (false) {showMessageSettings(msg);} } @@ -423,8 +430,8 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { WU.show(); const MSG_SELECT = identifyDisplayedMsg(scrollIdx); clearBtnHandler(); - if (!touch) {showMessageRouter(MSG_SELECT, true, "scrollerSelect"); return;} - if (touch.type == 0) {showMessageRouter(MSG_SELECT, true, "scrollerSelect");} + if (!touch) {showMessageRouter(MSG_SELECT, true, "overview"); return;} + if (touch.type == 0) {showMessageRouter(MSG_SELECT, true, "overview");} if (touch.type == 2) {showMessageSettings(MSG_SELECT);} } }); @@ -524,7 +531,7 @@ function showMessageOverview(msgid, persist) { updateLabelsInterval=undefined; } if (!msg) return returnToClockIfEmpty(); // go home if no message found - active = "message"; + active = "overview"; // Normal text message display var title=msg.title, titleFont = fontLarge, lines; var body=msg.body, bodyFont = fontLarge; @@ -730,7 +737,7 @@ function checkMessages(options) { }, select : idx => { if (idx < MESSAGES.length) - showMessageRouter(MESSAGES[idx], true); + showMessageRouter(MESSAGES[idx], true, "overview"); }, back : () => load() }); From 457c260b93f194179b00d385b62e198081746ce2 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 20:52:28 +0100 Subject: [PATCH 18/24] messagegui: suspend unread timeout when unlocked --- apps/messagegui/app.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index dc407f0149..79592a8aa3 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -784,8 +784,14 @@ setTimeout(() => { }, 10); // if checkMessages wants to 'load', do that /* If the Bangle is unlocked by the user, treat that -as a queue to stop repeated buzzing */ +as a queue to stop repeated buzzing. +Also suspend the reload timeout while the watch is unlocked. */ Bangle.on('lock',locked => { - if (!locked) + if (!locked) { require("messages").stopBuzz(); + cancelReloadTimeout(); + } + if (locked) { + if ("messagegui.new.js"===global.__FILE__) {resetReloadTimeout();} + } }); From 6e070247637b8501e16796b678ab756f67545d2e Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 21:02:25 +0100 Subject: [PATCH 19/24] messagegui: remove unused parameter --- apps/messagegui/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 79592a8aa3..baf773baa4 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -743,7 +743,7 @@ function checkMessages(options) { }); } -function returnToCheckMessages(clock) { +function returnToCheckMessages() { checkMessages({clockIfNoMsg:1,clockIfAllRead:1,ignoreUnread:settings.ignoreUnread,openMusic}); } From 53ef0c3df876ba123b1c04d76bcfe8afe4f0b26c Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Fri, 31 Jan 2025 22:13:55 +0100 Subject: [PATCH 20/24] messagegui: simpler logic for the scroller --- apps/messagegui/app.js | 94 +++++------------------------------------- 1 file changed, 10 insertions(+), 84 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index baf773baa4..25891fed9f 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -280,32 +280,14 @@ function showMusicMessage(msg) { }, 400); } -function showMessagesScroller(msg, persist, alreadyProcessed) { +function showMessagesScroller(msg, persist) { if (persist===undefined) {persist = true;} const MSG_IDX = msg ? MESSAGES.findIndex((m)=>m.id==msg.id) : undefined; - const INITIATED_FROM = ( - alreadyProcessed===undefined ? "other function" : - (MSG_IDX<=alreadyProcessed.idxSpan.start ? "scrolling up" : - (MSG_IDX >= alreadyProcessed.idxSpan.stop-1 ? "scrolling down" : - undefined)) - ); if (replying) { return; } active = "scroller"; if (persist) {cancelReloadTimeout();} else {resetReloadTimeout();} - if (!alreadyProcessed) {alreadyProcessed = {idxSpan:{}};} // So `alreadyProcessed.idxSpan.start/stop` can be looked for on first run. - - let idxSpan = ( - INITIATED_FROM==="other function" ? - {start : Math.max(MSG_IDX-1, 0), stop : Math.min(MSG_IDX+2, MESSAGES.length)} : - (INITIATED_FROM==="scrolling up" ? - {start : MSG_IDX, stop : alreadyProcessed.idxSpan.start } : - (INITIATED_FROM==="scrolling down" ? - { start : alreadyProcessed.idxSpan.stop, stop : Math.min(MSG_IDX+1, MESSAGES.length) } : - undefined)) - ); - const WU = require("widget_utils"); WU.hide(); const APP_RECT = Bangle.appRect; @@ -314,65 +296,30 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { g.setFont(bodyFont); const FONT_HEIGHT = g.getFontHeight(); const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; + let initScroll; var titleLines = []; - var messagesWrapped = []; - for (let i=idxSpan.start ; i=MESSAGES.length) {break;} - // continue; - //} - var lines = []; const TITLE_STRING = msgIter.title||msgIter.sender||msgIter.subject||msgIter.src||/*LANG*/"No Title"; lines = g.wrapString(TITLE_STRING, APP_RECT.w-10); for (let i=0; i x + allLines.length)); - allLines = allLines.concat(alreadyProcessed.lines); - } else if (INITIATED_FROM === "scrolling down") { - initScroll = alreadyProcessed.lines.length-(LINES_PER_SCREEN); - titleLines = alreadyProcessed.titleLines.concat(titleLines. - map((x) => x + alreadyProcessed.lines.length)); - allLines = alreadyProcessed.lines.concat(allLines); - } - initScroll = initScroll*FONT_HEIGHT; - - if (allLines.length == 0 && alreadyProcessed.lines.length == 0) { + if (allLines.length == 0) { cancelReloadTimeout(); returnToClockIfEmpty(); } - alreadyProcessed = { // Update with the newly processed messages. - lines : allLines, - titleLines : titleLines, - idxSpan: { - start : Math.min(idxSpan.start, - (alreadyProcessed.idxSpan.start===undefined) ? - MESSAGES.length : alreadyProcessed.idxSpan.start), - stop : Math.max(idxSpan.stop, alreadyProcessed.idxSpan.stop||0)} - }; - function identifyDisplayedMsg(scrollIdx) { let firstTitleLinePerMsg = [titleLines[0]]; for (let i=1; i=0 ; i--) { if (scrollIdx>=firstTitleLinePerMsg[i]) { - return MESSAGES[i + alreadyProcessed.idxSpan.start]; + return MESSAGES[i]; } } } - // Used for stopping repeated triggering of next message by the scroller and - // to choose how to identify displayed message when selecting with hw button. + // Used to choose how to identify displayed message when selecting with hw button. let prevScrollIdxs = [undefined, undefined]; // [prevIdx, prevPrevIdx] - function shouldAddNext(scrollIdx) {"ram"; return (scrollIdx>=allLines.length-1 && - scrollIdx!=prevScrollIdxs[0] && alreadyProcessed.idxSpan.stop0);} - function reinitAdding(idx) { - setTimeout(() => { - Bangle.emit("drag", {dy:0}); // Make sure scrolling doesn't continue after reinit. FIXME: Is this a hack that begs for a bug being fixed elsewhere? - // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. - setTimeout(()=>{ - E.showScroller(); - clearBtnHandler(); - showMessagesScroller(MESSAGES[idx], - persist, alreadyProcessed); - },0); - }, 40); - } - E.showScroller({ scroll : initScroll, h : FONT_HEIGHT, // height of each menu item in pixels @@ -417,9 +346,6 @@ function showMessagesScroller(msg, persist, alreadyProcessed) { setColor(titleLines.find(e=>e==scrollIdx)!==undefined ? g.theme.fg2 : g.theme.fg). clearRect(r); g.setFont(bodyFont).setFontAlign(0,-1).drawString(allLines[scrollIdx], r.x+r.w/2, r.y); - // Load in next/previous message on demand by reinitializing showMessagesScroller while passing on the processed messages. - if (shouldAddNext(scrollIdx)) {reinitAdding(alreadyProcessed.idxSpan.stop);} - if (shouldAddPrev(scrollIdx)) {reinitAdding(alreadyProcessed.idxSpan.start-1);} if (prevScrollIdxs[1]!==prevScrollIdxs[0]) { prevScrollIdxs[1] = prevScrollIdxs[0]; if (!persist) {resetReloadTimeout();} From 41934ba454d7cd82f18f10d4b44d76e74568cfe0 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sun, 2 Feb 2025 00:39:26 +0100 Subject: [PATCH 21/24] messagegui: refactor more to make scroller logic simpler --- apps/messagegui/app.js | 55 ++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 25891fed9f..33532d30ae 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -295,10 +295,10 @@ function showMessagesScroller(msg, persist) { var bodyFont = fontBig; g.setFont(bodyFont); const FONT_HEIGHT = g.getFontHeight(); - const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; let initScroll; var titleLines = []; let allLines = []; + let firstTitleLinePerMsg = []; for (let i=0 ; i=0 ; i--) { - if (scrollIdx>=firstTitleLinePerMsg[i]) { - return MESSAGES[i]; - } - } - } - - // Used to choose how to identify displayed message when selecting with hw button. - let prevScrollIdxs = [undefined, undefined]; // [prevIdx, prevPrevIdx] - E.showScroller({ scroll : initScroll, h : FONT_HEIGHT, // height of each menu item in pixels @@ -346,39 +331,35 @@ function showMessagesScroller(msg, persist) { setColor(titleLines.find(e=>e==scrollIdx)!==undefined ? g.theme.fg2 : g.theme.fg). clearRect(r); g.setFont(bodyFont).setFontAlign(0,-1).drawString(allLines[scrollIdx], r.x+r.w/2, r.y); - if (prevScrollIdxs[1]!==prevScrollIdxs[0]) { - prevScrollIdxs[1] = prevScrollIdxs[0]; - if (!persist) {resetReloadTimeout();} - } - prevScrollIdxs[0] = scrollIdx; + if (!persist) {resetReloadTimeout();} }, select : function(scrollIdx, touch) { WU.show(); - const MSG_SELECT = identifyDisplayedMsg(scrollIdx); clearBtnHandler(); - if (!touch) {showMessageRouter(MSG_SELECT, true, "overview"); return;} - if (touch.type == 0) {showMessageRouter(MSG_SELECT, true, "overview");} - if (touch.type == 2) {showMessageSettings(MSG_SELECT);} + for (let i=firstTitleLinePerMsg.length-1; i>=0 ; i--) { + if (scrollIdx>=firstTitleLinePerMsg[i]) { + if (!touch || touch.type===0) {showMessageRouter(MESSAGES[i], true, + "overview"); return;} + if (touch.type == 2) {showMessageSettings(MESSAGES[i]);} + break; + } + } } }); - function clearBtnHandler() { - if (Bangle.btnHandler) {clearWatch(Bangle.btnHandler); Bangle.btnHandler=undefined;} - } - clearBtnHandler(); - // If Bangle.js 2 add an external select hw button handler. - Bangle.btnHandler = ((2===process.env.HWVERSION) && (setWatch(()=>{ + let btnHandler = ((2===process.env.HWVERSION) && (setWatch(()=>{ Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessageOverview` screen is loaded. // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ if ("messagegui.new.js"===global.__FILE__) {return load();} - const SCROLL_IDX_CENTER_SCREEN = prevScrollIdxs[0]>prevScrollIdxs[1] ? - prevScrollIdxs[0]-LINES_PER_SCREEN/2:prevScrollIdxs[0]+LINES_PER_SCREEN/2; - WU.show(); - showMessageOverview(identifyDisplayedMsg(SCROLL_IDX_CENTER_SCREEN).id, true); + Bangle.emit("touch", 1, {x:Bangle.appRect.x2/2, y:Bangle.appRect.y2/2, type:0}); },0); - }, BTN, {edge:'rising'}))); + }, BTN, {edge:'rising', repeat:true}))); + + function clearBtnHandler() { + if (btnHandler) {clearWatch(btnHandler); btnHandler=undefined;} + } } function showMessageSettings(msg) { From 6b6f79ff0c946ffeebcb48aec7751622b59f1a4d Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sun, 2 Feb 2025 00:55:33 +0100 Subject: [PATCH 22/24] messagegui: small change --- apps/messagegui/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 33532d30ae..8446041cf7 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -353,7 +353,7 @@ function showMessagesScroller(msg, persist) { // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ if ("messagegui.new.js"===global.__FILE__) {return load();} - Bangle.emit("touch", 1, {x:Bangle.appRect.x2/2, y:Bangle.appRect.y2/2, type:0}); + Bangle.emit("touch", 1, {x:APP_RECT.x2/2, y:APP_RECT.y2/2, type:0}); },0); }, BTN, {edge:'rising', repeat:true}))); From e6bf0d74ace62942380d59e0f48b7f0718530cf7 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sun, 2 Feb 2025 01:00:01 +0100 Subject: [PATCH 23/24] messagegui: add FIXME comment --- apps/messagegui/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 8446041cf7..7a6588e69b 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -302,7 +302,7 @@ function showMessagesScroller(msg, persist) { for (let i=0 ; i Date: Mon, 3 Feb 2025 00:00:19 +0100 Subject: [PATCH 24/24] messagegui: improve logic re what messages to be marked `new=false` --- apps/messagegui/app.js | 48 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 7a6588e69b..243b96e8f3 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -302,7 +302,6 @@ function showMessagesScroller(msg, persist) { for (let i=0 ; ie==scrollIdx)!==undefined ? g.theme.bg2 : g.theme.bg). setColor(titleLines.find(e=>e==scrollIdx)!==undefined ? g.theme.fg2 : g.theme.fg). clearRect(r); g.setFont(bodyFont).setFontAlign(0,-1).drawString(allLines[scrollIdx], r.x+r.w/2, r.y); + if (scrollIdxshownIdxLast) {shownIdxLast = scrollIdx;} if (!persist) {resetReloadTimeout();} }, select : function(scrollIdx, touch) { WU.show(); - clearBtnHandler(); for (let i=firstTitleLinePerMsg.length-1; i>=0 ; i--) { if (scrollIdx>=firstTitleLinePerMsg[i]) { - if (!touch || touch.type===0) {showMessageRouter(MESSAGES[i], true, - "overview"); return;} - if (touch.type == 2) {showMessageSettings(MESSAGES[i]);} + if (!touch || touch.type===0) { + showMessageRouter(MESSAGES[i], true, "overview") + } else if (touch.type == 2) { + showMessageSettings(MESSAGES[i]); + } break; } } + clearBtnHandler(); + updateReadMessages(); } }); + // If Bangle.js 2 add an external select hw button handler. let btnHandler = ((2===process.env.HWVERSION) && (setWatch(()=>{ Bangle.emit("drag", {dy:0}); // Compatibility with `kineticscroll`, stopping the scroller so it doesn't continue scrolling when the `showMessageOverview` screen is loaded. @@ -360,6 +369,35 @@ function showMessagesScroller(msg, persist) { function clearBtnHandler() { if (btnHandler) {clearWatch(btnHandler); btnHandler=undefined;} } + + function updateReadMessages() { + let shownMsgIdxFirst, shownMsgIdxLast; + const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; + //print(firstTitleLinePerMsg) + //print(shownIdxFirst, shownIdxLast) + + for (let i=0; ifirstTitleLinePerMsg[i]) { + shownMsgIdxFirst = i; + } + + if (shownIdxLast>=firstTitleLinePerMsg[i+1] && shownIdxLast-LINES_PER_SCREEN