From fb83687c7d9faa20b4d2a0bf09475811980e219b Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 20:20:11 +0100 Subject: [PATCH 01/29] messagegui: refactor `global` -> `globalThis` [global is used in Node.js. Consider using the identical globalThis as it was introduced in the ECMAScript spec.](https://www.espruino.com/ReferenceBANGLEJS2#l__global_global) --- apps/messagegui/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 31b7c95dcb..601b32c287 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -492,10 +492,10 @@ function checkMessages(options) { delete newMessages[0].show; // stop us getting stuck here if we're called a second time showMessage(newMessages[0].id, false); // buzz after showMessage, so being busy during layout doesn't affect the buzz pattern - if (global.BUZZ_ON_NEW_MESSAGE) { + if (globalThis.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 - global.BUZZ_ON_NEW_MESSAGE = false; + globalThis.BUZZ_ON_NEW_MESSAGE = false; // messages.buzz respects quiet mode - no need to check here require("messages").buzz(newMessages[0].src); } From a8e878f9c9ac2a08c5ee4cefa72359c7d0f046b5 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 22:21:12 +0100 Subject: [PATCH 02/29] messagegui: rm unused parameter + add semicolon --- apps/messagegui/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 601b32c287..9b864eec86 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -512,7 +512,7 @@ function checkMessages(options) { E.showScroller({ h : 50, 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); @@ -558,7 +558,7 @@ function checkMessages(options) { }); } -function returnToCheckMessages(clock) { +function returnToCheckMessages() { checkMessages({clockIfNoMsg:1,clockIfAllRead:1,ignoreUnread:settings.ignoreUnread,openMusic}); } From 5376ef24d65ca9ac918102e786a141909f5b7231 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 20:25:50 +0100 Subject: [PATCH 03/29] messagegui: suspend unread timeout while the watch is 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 9b864eec86..07cbe0aa97 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -599,8 +599,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 (!persist) {resetReloadTimeout();} + } }); From 53579a59bcf1058aa2a9d04547bc30b9fa6db976 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 20:57:53 +0100 Subject: [PATCH 04/29] messagegui: rename `showMessage` -> `showMessageOverview` --- apps/messagegui/app.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 07cbe0aa97..f7532c296a 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -46,7 +46,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 @@ -78,7 +78,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); + showMessageOverview(msg&&msg.id, false); }; Bangle.on("message", onMessagesModified); @@ -256,9 +256,9 @@ function showMessageScroller(msg) { g.setFont(bodyFont).setFontAlign(0,-1).drawString(lines[idx], r.x+r.w/2, r.y); }, select : function(idx) { if (idx>=lines.length-2) - showMessage(msg.id, true); + showMessageOverview(msg.id, true); }, - back : () => showMessage(msg.id, true) + back : () => showMessageOverview(msg.id, true) }); } @@ -266,7 +266,7 @@ function showMessageSettings(msg) { active = "settings"; var menu = {"":{ "title":/*LANG*/"Message", - back:() => showMessage(msg.id, true) + back:() => showMessageOverview(msg.id) }, }; @@ -280,11 +280,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); }); }; } @@ -328,7 +328,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); @@ -346,7 +346,7 @@ function showMessage(msgid, persist) { cancelReloadTimeout(); // don't auto-reload to clock now return showMapMessage(msg); } - active = "message"; + active = "overview"; // Normal text message display var title=msg.title, titleFont = fontLarge, lines; var body=msg.body, bodyFont = fontLarge; @@ -414,7 +414,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}); } @@ -452,8 +452,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); @@ -490,7 +490,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); + showMessageOverview(newMessages[0].id, false); // buzz after showMessage, so being busy during layout doesn't affect the buzz pattern if (globalThis.BUZZ_ON_NEW_MESSAGE) { // this is set if we entered the messages app by loading `messagegui.new.js` @@ -503,7 +503,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(); @@ -552,7 +552,7 @@ function checkMessages(options) { }, select : idx => { if (idx < MESSAGES.length) - showMessage(MESSAGES[idx].id, true); + showMessageOverview(MESSAGES[idx].id, true); }, back : () => load() }); From f8ad9f9f7fffc0b9830fb05300291950189b4fb8 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 21:49:48 +0100 Subject: [PATCH 05/29] messagegui: add a routing function for `showMessage*` functions --- apps/messagegui/app.js | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index f7532c296a..96b5c99dbe 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -78,7 +78,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 - showMessageOverview(msg&&msg.id, false); + showMessageRouter(msg, persist, "dependsOnActive"); }; Bangle.on("message", onMessagesModified); @@ -87,6 +87,39 @@ function saveMessages() { } E.on("kill", saveMessages); +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();} else if (Bangle.isLocked()) {resetReloadTimeout();} + + 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 (msg.id=="call") { + return showMessageOverview(msg.id); + } + if ("scroller"===explicitDestnation) { + return showMessageScroller(msg); + } + if ("overview"===explicitDestnation) { + return showMessageOverview(msg.id); + } + if ("dependsOnActive"===explicitDestnation) { + if ("scroller"===active) {return;} + if ("list"===active) {return returnToMain();} + if ("settings"===active || "overview"===active) {return;} + } + //if (false) {showMessageSettings(msg);} +} + function showMapMessage(msg) { active = "map"; require("messages").stopBuzz(); // stop repeated buzzing while the map is showing @@ -552,7 +585,7 @@ function checkMessages(options) { }, select : idx => { if (idx < MESSAGES.length) - showMessageOverview(MESSAGES[idx].id, true); + showMessageRouter(MESSAGES[idx], true, "overview"); }, back : () => load() }); From b3b6faec2212c21865742462f272ada262b3d9ff Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 22:04:12 +0100 Subject: [PATCH 06/29] messagegui: refactor `showMessageScroller` to `showMessagesScroller` ... which reads in all messages with initial scroll position at the chosen message. --- apps/messagegui/app.js | 146 +++++++++++++++++++++++++++++++++-------- 1 file changed, 120 insertions(+), 26 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 96b5c99dbe..b124a9b2dd 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -78,7 +78,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, persist, "dependsOnActive"); + showMessageOverview(msg&&msg.id, false); }; Bangle.on("message", onMessagesModified); @@ -107,13 +107,13 @@ function showMessageRouter(msg, persist, explicitDestnation) { return showMessageOverview(msg.id); } if ("scroller"===explicitDestnation) { - return showMessageScroller(msg); + return showMessagesScroller(msg); } if ("overview"===explicitDestnation) { return showMessageOverview(msg.id); } if ("dependsOnActive"===explicitDestnation) { - if ("scroller"===active) {return;} + if ("scroller"===active) {return showMessagesScroller(msg);} // reinit scroller with updated messages list. if ("list"===active) {return returnToMain();} if ("settings"===active || "overview"===active) {return;} } @@ -267,32 +267,126 @@ function showMusicMessage(msg) { }, 400); } -function showMessageScroller(msg) { - cancelReloadTimeout(); +function showMessagesScroller(msg) { + const MSG_IDX = msg ? MESSAGES.findIndex((m)=>m.id==msg.id) : undefined; + + if (replying) { return; } active = "scroller"; + + const WU = 1!==process.env.HWVERSION ? require("widget_utils") : undefined; + WU&&WU.hide(); + const APP_RECT = Bangle.appRect; + 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"]); + const FONT_HEIGHT = g.getFontHeight(); + let initScroll; + var titleLines = []; + let allLines = []; + let firstTitleLinePerMsg = []; + for (let i=0 ; i=lines.length-2) - showMessageOverview(msg.id, true); + draw : function(scrollIdx, r) {"ram"; + //print(scrollIdx) + 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); + if (scrollIdxshownScrollIdxLast) {shownScrollIdxLast = scrollIdx;} }, - back : () => showMessageOverview(msg.id, true) + select : function(scrollIdx, touch) { + for (let i=firstTitleLinePerMsg.length-1; i>=0 ; i--) { + if (scrollIdx>=firstTitleLinePerMsg[i]) { + if (!touch || touch.type===0) { + WU&&WU.show(); + delete titleLines, allLines; + //E.showScroller(); + updateReadMessages(); + setTimeout(()=>showMessageRouter(MESSAGES[i], true, "overview"),0); + } + break; + } + } + } }); + + // If Bangle.js 2 add an external select hw button handler. + if (2===process.env.HWVERSION) { + setWatch(()=>{ + if ("scroller"!==active) {return;} + 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 (!persist) {return load();} + Bangle.emit("touch", 1, {x:APP_RECT.x2/2, y:APP_RECT.y2/2, type:0}); + },0); + }, BTN); + } + + function updateReadMessages() { + let shownMsgIdxFirst, shownMsgIdxLast; + const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; + //print(firstTitleLinePerMsg) + //print(shownIdxFirst, shownIdxLast) + + for (let i=0; i showMessageScroller(msg); + menu[/*LANG*/"View Message"] = () => showMessagesScroller(msg); if (msg.reply && reply) { menu[/*LANG*/"Reply"] = () => { @@ -477,7 +571,7 @@ function showMessageOverview(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}); @@ -523,8 +617,8 @@ 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 - showMessageOverview(newMessages[0].id, false); - // buzz after showMessage, so being busy during layout doesn't affect the buzz pattern + showMessagesScroller(newMessages[0]); + // buzz after showMessagesScroller, so being busy during scroller setup doesn't affect the buzz pattern if (globalThis.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 From ef842544935c0e2698658ca992dee97a6c715e15 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 22:16:25 +0100 Subject: [PATCH 07/29] messagegui: move some plumbing from `showMessageOverview` ... to `showMessageRouter`. --- apps/messagegui/app.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index b124a9b2dd..b7eaecd67a 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -78,7 +78,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 - showMessageOverview(msg&&msg.id, false); + showMessageRouter(msg, persist, "dependsOnActive"); }; Bangle.on("message", onMessagesModified); @@ -455,9 +455,8 @@ function showMessageSettings(msg) { E.showMenu(menu); } -function showMessageOverview(msgid, persist) { +function showMessageOverview(msgid) { if (replying) { return; } - if(!persist) resetReloadTimeout(); let idx = MESSAGES.findIndex(m=>m.id==msgid); var msg = MESSAGES[idx]; if (updateLabelsInterval) { @@ -465,14 +464,6 @@ function showMessageOverview(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 = "overview"; // Normal text message display var title=msg.title, titleFont = fontLarge, lines; @@ -579,8 +570,8 @@ function showMessageOverview(msgid, persist) { Bangle.swipeHandler = (lr,ud) => { if (lr>0 && posHandler) posHandler(); if (lr<0 && negHandler) negHandler(); - if (ud>0 && idx0) showMessageOverview(MESSAGES[idx-1].id, true); + if (ud>0 && idx0) showMessageOverview(MESSAGES[idx-1].id); }; Bangle.on("swipe", Bangle.swipeHandler); g.reset().clearRect(Bangle.appRect); @@ -630,7 +621,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 showMessageOverview('music', true); + return showMessageOverview('music'); // no new messages - go to clock? if (options.clockIfAllRead && newMessages.length==0) return load(); From bb095b392aa2af525dd1a38b514dffcc437dc54c Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 26 Feb 2025 21:30:44 +0100 Subject: [PATCH 08/29] messagegui: bump version --- apps/messagegui/ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/messagegui/ChangeLog b/apps/messagegui/ChangeLog index 455f963438..d341295cbe 100644 --- a/apps/messagegui/ChangeLog +++ b/apps/messagegui/ChangeLog @@ -114,4 +114,5 @@ 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: Use new Rebble fonts if available - Remove workaround for 2v10 (>3 years ago) - assume everyone is on never firmware now \ No newline at end of file +0.86: Refactor to display a scroller with all messages loaded. + Initial scroll position is at the chosen message. From 70887a74fb4646125b19180775d13475aea46c16 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Thu, 6 Mar 2025 01:37:36 +0100 Subject: [PATCH 09/29] messagegui: WIP lr-swipes for neg/pos-handling on msgsscroller --- apps/messagegui/app.js | 74 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index b7eaecd67a..47aa3518fa 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -295,8 +295,18 @@ function showMessagesScroller(msg) { for (let i=0; i"; + } + if (!footer) { + footer = ["-".repeat(12)]; + } lines = lines.concat(g.wrapString(msgIter.body, APP_RECT.w-10), - ["-".repeat(12)]); + footer); allLines = allLines.concat(lines); } @@ -325,12 +335,20 @@ function showMessagesScroller(msg) { select : function(scrollIdx, touch) { for (let i=firstTitleLinePerMsg.length-1; i>=0 ; i--) { if (scrollIdx>=firstTitleLinePerMsg[i]) { + if (touch && touch.type===2) {return;} + const MSG_SELECTED = MESSAGES[i]; + WU&&WU.show(); + delete titleLines, allLines; + //E.showScroller(); + updateReadMessages(); if (!touch || touch.type===0) { - WU&&WU.show(); - delete titleLines, allLines; - //E.showScroller(); - updateReadMessages(); - setTimeout(()=>showMessageRouter(MESSAGES[i], true, "overview"),0); + setTimeout(()=>showMessageRouter(MSG_SELECTED, true, "overview"),0); + } + print(touch) + if (touch && touch.type.swipeLR) { + print("select swipe") + if (touch.type.swipeLR>0 && posHandler) {posHandler(MSG_SELECTED);} + if (touch.type.swipeLR<0 && negHandler) {negHandler(MSG_SELECTED);} } break; } @@ -387,6 +405,50 @@ function showMessagesScroller(msg) { } //print(MESSAGES) } + var negHandler,posHandler = [ ]; + if (msg.negative) { + negHandler = (msg)=>{ + print("negHandler") + msg.new = false; + cancelReloadTimeout(); // don't auto-reload to clock now + Bangle.messageResponse(msg,false); + returnToCheckMessages(); + }; + //footer.push({type:"img",src:atob("PhAB4A8AAAAAAAPAfAMAAAAAD4PwHAAAAAA/H4DwAAAAAH78B8AAAAAA/+A/AAAAAAH/Af//////w/gP//////8P4D///////H/Af//////z/4D8AAAAAB+/AfAAAAAA/H4DwAAAAAPg/AcAAAAADwHwDAAAAAA4A8AAAAAAAA=="),col:"#f00",cb:negHandler}); + } + if (msg.reply && reply) { + print("posHandler reply") + posHandler = (msg)=>{ + replying = true; + msg.new = false; + cancelReloadTimeout(); // don't auto-reload to clock now + reply.reply({msg: msg}) + .then(result => { + Bluetooth.println(JSON.stringify(result)); + replying = false; + returnToCheckMessages(); + }) + .catch(() => { + replying = false; + showMessagesScroller(msg); + }); + }; + //footer.push({type:"img",src:atob("QRABAAAAAAAH//+AAAAABgP//8AAAAADgf//4AAAAAHg4ABwAAAAAPh8APgAAAAAfj+B////////geHv///////hf+f///////GPw///////8cGBwAAAAAPx/gDgAAAAAfD/gHAAAAAA8DngOAAAAABwDHP8AAAAADACGf4AAAAAAAAM/w=="),col:"#0f0", cb:posHandler}); + } + else if (msg.positive) { + posHandler = (msg)=>{ + print("posHandler") + msg.new = false; + cancelReloadTimeout(); // don't auto-reload to clock now + Bangle.messageResponse(msg,true); + returnToCheckMessages(); + }; + //footer.push({type:"img",src:atob("QRABAAAAAAAAAAOAAAAABgAAA8AAAAADgAAD4AAAAAHgAAPgAAAAAPgAA+AAAAAAfgAD4///////gAPh///////gA+D///////AD4H//////8cPgAAAAAAPw8+AAAAAAAfB/4AAAAAAA8B/gAAAAAABwB+AAAAAAADAB4AAAAAAAAABgAA=="),col:"#0f0",cb:posHandler}); + } + Bangle.swipeHandler = (lr) => { + if (lr) {Bangle.emit("touch", 1, {x:APP_RECT.x2/2, y:APP_RECT.y2/2, type:{swipeLR:lr}});} + }; + Bangle.on("swipe", Bangle.swipeHandler); } function showMessageSettings(msg) { From 7104bd25d1ae974b89ef83f0b1530aa031732921 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 24 Mar 2025 23:44:29 +0100 Subject: [PATCH 10/29] messagegui: bump version --- apps/messagegui/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messagegui/metadata.json b/apps/messagegui/metadata.json index e0f47c6bc3..1f804ad56f 100644 --- a/apps/messagegui/metadata.json +++ b/apps/messagegui/metadata.json @@ -2,7 +2,7 @@ "id": "messagegui", "name": "Message UI", "shortName": "Messages", - "version": "0.85", + "version": "0.86", "description": "Default app to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", From 3937d3126dc6be8ef3eb5cbf83c035ae03b10073 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Tue, 25 Mar 2025 04:26:27 +0100 Subject: [PATCH 11/29] messagegui: avoid use of the overview screen make many tweaks to accommodate that change. Add external back on touch handler to the showMessagesScroller that shows the list of messages. Select a message (touch it on B2, HW button on B1) opens the message settings screen. Going back from message setting screen opens the showMessagesScroller on the current message again. TODO: See if the code for the showMessageOverview can be removed. --- apps/messagegui/app.js | 55 +++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 47aa3518fa..9502ded2dd 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -338,15 +338,19 @@ function showMessagesScroller(msg) { if (touch && touch.type===2) {return;} const MSG_SELECTED = MESSAGES[i]; WU&&WU.show(); - delete titleLines, allLines; //E.showScroller(); updateReadMessages(); - if (!touch || touch.type===0) { - setTimeout(()=>showMessageRouter(MSG_SELECTED, true, "overview"),0); + delete titleLines, allLines; + if (touch && touch.type.back) { + returnToMain(); + } else if (!touch || touch.type===0) { + setTimeout(()=>{ + showMessageSettings(MSG_SELECTED) + },0); } - print(touch) + //print(touch) if (touch && touch.type.swipeLR) { - print("select swipe") + //print("select swipe") if (touch.type.swipeLR>0 && posHandler) {posHandler(MSG_SELECTED);} if (touch.type.swipeLR<0 && negHandler) {negHandler(MSG_SELECTED);} } @@ -356,7 +360,7 @@ function showMessagesScroller(msg) { } }); - // If Bangle.js 2 add an external select hw button handler. + // If Bangle.js 2 add an external back hw button handler. if (2===process.env.HWVERSION) { setWatch(()=>{ if ("scroller"!==active) {return;} @@ -364,20 +368,33 @@ function showMessagesScroller(msg) { // Zero ms timeout as to not move on before the scroller has registered the emitted drag event. setTimeout(()=>{ if (!persist) {return load();} - Bangle.emit("touch", 1, {x:APP_RECT.x2/2, y:APP_RECT.y2/2, type:0}); + Bangle.emit("touch", 1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{back:true}}); },0); }, BTN); } + // Add an external back touch handler. + let touchHandler = (button, xy)=>{ + // if ((left side of Banlge 1 screen) || (top left corner of Bangle 2 screen)) + if ((!xy && 1===button) || (xy && xy.type===0 && xy.x<30 && xy.y<30)) { + if (!persist) {return load();} + returnToMain(); + E.stopEventPropagation(); + Bangle.removeListener("touch", touchHandler); + } + }; + Bangle.prependListener("touch", touchHandler); + function updateReadMessages() { let shownMsgIdxFirst, shownMsgIdxLast; const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; //print(firstTitleLinePerMsg) //print(shownIdxFirst, shownIdxLast) - for (let i=0; i{ - print("negHandler") + //print("negHandler") msg.new = false; cancelReloadTimeout(); // don't auto-reload to clock now Bangle.messageResponse(msg,false); @@ -417,7 +434,7 @@ function showMessagesScroller(msg) { //footer.push({type:"img",src:atob("PhAB4A8AAAAAAAPAfAMAAAAAD4PwHAAAAAA/H4DwAAAAAH78B8AAAAAA/+A/AAAAAAH/Af//////w/gP//////8P4D///////H/Af//////z/4D8AAAAAB+/AfAAAAAA/H4DwAAAAAPg/AcAAAAADwHwDAAAAAA4A8AAAAAAAA=="),col:"#f00",cb:negHandler}); } if (msg.reply && reply) { - print("posHandler reply") + //print("posHandler reply") posHandler = (msg)=>{ replying = true; msg.new = false; @@ -437,7 +454,7 @@ function showMessagesScroller(msg) { } else if (msg.positive) { posHandler = (msg)=>{ - print("posHandler") + //print("posHandler") msg.new = false; cancelReloadTimeout(); // don't auto-reload to clock now Bangle.messageResponse(msg,true); @@ -446,7 +463,7 @@ function showMessagesScroller(msg) { //footer.push({type:"img",src:atob("QRABAAAAAAAAAAOAAAAABgAAA8AAAAADgAAD4AAAAAHgAAPgAAAAAPgAA+AAAAAAfgAD4///////gAPh///////gA+D///////AD4H//////8cPgAAAAAAPw8+AAAAAAAfB/4AAAAAAA8B/gAAAAAABwB+AAAAAAADAB4AAAAAAAAABgAA=="),col:"#0f0",cb:posHandler}); } Bangle.swipeHandler = (lr) => { - if (lr) {Bangle.emit("touch", 1, {x:APP_RECT.x2/2, y:APP_RECT.y2/2, type:{swipeLR:lr}});} + if (lr) {Bangle.emit("touch", 1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{swipeLR:lr}});} }; Bangle.on("swipe", Bangle.swipeHandler); } @@ -455,7 +472,7 @@ function showMessageSettings(msg) { active = "settings"; var menu = {"":{ "title":/*LANG*/"Message", - back:() => showMessageOverview(msg.id) + back:() => showMessagesScroller(msg) }, }; @@ -469,11 +486,11 @@ function showMessageSettings(msg) { .then(result => { Bluetooth.println(JSON.stringify(result)); replying = false; - showMessageOverview(msg.id); + showMessagesScroller(msg); }) .catch(() => { replying = false; - showMessageOverview(msg.id); + showMessagesScroller(msg); }); }; } @@ -594,7 +611,7 @@ function showMessageOverview(msgid) { .catch(() => { replying = false; layout.render(); - showMessageOverview(msg.id); + showMessagesScroller(msg); }); }; footer.push({type:"img",src:atob("QRABAAAAAAAH//+AAAAABgP//8AAAAADgf//4AAAAAHg4ABwAAAAAPh8APgAAAAAfj+B////////geHv///////hf+f///////GPw///////8cGBwAAAAAPx/gDgAAAAAfD/gHAAAAAA8DngOAAAAABwDHP8AAAAADACGf4AAAAAAAAM/w=="),col:"#0f0", cb:posHandler}); } @@ -732,7 +749,7 @@ function checkMessages(options) { }, select : idx => { if (idx < MESSAGES.length) - showMessageRouter(MESSAGES[idx], true, "overview"); + showMessageRouter(MESSAGES[idx], true, "scroller"); }, back : () => load() }); From f18ddc80152c6a1e95bdbdb865e8a6b8ee13acc8 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Thu, 27 Mar 2025 00:11:58 +0100 Subject: [PATCH 12/29] messagegui: use images for pos and neg response indication also hunting some ram leaks. --- apps/messagegui/app.js | 49 ++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 9502ded2dd..602f63adb4 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -284,6 +284,7 @@ function showMessagesScroller(msg) { var titleLines = []; let allLines = []; let firstTitleLinePerMsg = []; + let footerImgs = {}; for (let i=0 ; i"; + if (msg.reply && reply) { + //footer[0] += ((!msg.negative)?" ".repeat(6):"") + " " + "-".repeat(4) + ">"; + footerImgs.pos = {src:atob("QRABAAAAAAAH//+AAAAABgP//8AAAAADgf//4AAAAAHg4ABwAAAAAPh8APgAAAAAfj+B////////geHv///////hf+f///////GPw///////8cGBwAAAAAPx/gDgAAAAAfD/gHAAAAAA8DngOAAAAABwDHP8AAAAADACGf4AAAAAAAAM/w=="),col:"#0f0"} + } else if (msg.positive) { + //footer[0] += ((!msg.negative)?" ".repeat(6):"") + " " + "-".repeat(4) + ">"; + footerImgs.pos = {src:atob("QRABAAAAAAAAAAOAAAAABgAAA8AAAAADgAAD4AAAAAHgAAPgAAAAAPgAA+AAAAAAfgAD4///////gAPh///////gA+D///////AD4H//////8cPgAAAAAAPw8+AAAAAAAfB/4AAAAAAA8B/gAAAAAABwB+AAAAAAADAB4AAAAAAAAABgAA=="),col:"#0f0"} } if (!footer) { footer = ["-".repeat(12)]; @@ -329,6 +335,11 @@ function showMessagesScroller(msg) { 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 (allLines[scrollIdx]==="") { + g. + setColor(footerImgs.neg.col).drawImage(footerImgs.neg.src,r.x+5+3,r.y). + setColor(footerImgs.pos.col).drawImage(footerImgs.pos.src,r.w-64-5,r.y); + } if (scrollIdxshownScrollIdxLast) {shownScrollIdxLast = scrollIdx;} }, @@ -338,7 +349,9 @@ function showMessagesScroller(msg) { if (touch && touch.type===2) {return;} const MSG_SELECTED = MESSAGES[i]; WU&&WU.show(); - //E.showScroller(); + print(process.memory()); + E.showScroller(); + print(process.memory()); updateReadMessages(); delete titleLines, allLines; if (touch && touch.type.back) { @@ -360,30 +373,34 @@ function showMessagesScroller(msg) { } }); + // Add an external back touch handler. + let touchHandler = (button, xy)=>{ + // if ((left side of Banlge 1 screen) || (top left corner of Bangle 2 screen)) + if ((!xy && 1===button) || (xy && xy.type===0 && xy.x<30 && xy.y<30)) { + if (!persist) {return load();} + returnToMain(); + E.stopEventPropagation(); + Bangle.removeListener("touch", touchHandler); + if (btnWatch) {clearWatch(btnWatch); btnWatch = undefined;} + } + }; + Bangle.prependListener("touch", touchHandler); + // If Bangle.js 2 add an external back hw button handler. + let btnWatch; if (2===process.env.HWVERSION) { - setWatch(()=>{ + btnWatch = setWatch(()=>{ if ("scroller"!==active) {return;} 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 (!persist) {return load();} + Bangle.removeListener("touch", touchHandler); Bangle.emit("touch", 1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{back:true}}); },0); }, BTN); } - // Add an external back touch handler. - let touchHandler = (button, xy)=>{ - // if ((left side of Banlge 1 screen) || (top left corner of Bangle 2 screen)) - if ((!xy && 1===button) || (xy && xy.type===0 && xy.x<30 && xy.y<30)) { - if (!persist) {return load();} - returnToMain(); - E.stopEventPropagation(); - Bangle.removeListener("touch", touchHandler); - } - }; - Bangle.prependListener("touch", touchHandler); function updateReadMessages() { let shownMsgIdxFirst, shownMsgIdxLast; From 5fbadc134e7d80891e70ad99bb7b36443be6d0ff Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Thu, 27 Mar 2025 00:26:46 +0100 Subject: [PATCH 13/29] messagegui: speed optimization for drawing images hopefully --- apps/messagegui/app.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 602f63adb4..98f51e369c 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -284,7 +284,7 @@ function showMessagesScroller(msg) { var titleLines = []; let allLines = []; let firstTitleLinePerMsg = []; - let footerImgs = {}; + let footerImgNeg, footerImgPos; for (let i=0 ; i"; - footerImgs.pos = {src:atob("QRABAAAAAAAH//+AAAAABgP//8AAAAADgf//4AAAAAHg4ABwAAAAAPh8APgAAAAAfj+B////////geHv///////hf+f///////GPw///////8cGBwAAAAAPx/gDgAAAAAfD/gHAAAAAA8DngOAAAAABwDHP8AAAAADACGf4AAAAAAAAM/w=="),col:"#0f0"} + footerImgPos = atob("QRABAAAAAAAH//+AAAAABgP//8AAAAADgf//4AAAAAHg4ABwAAAAAPh8APgAAAAAfj+B////////geHv///////hf+f///////GPw///////8cGBwAAAAAPx/gDgAAAAAfD/gHAAAAAA8DngOAAAAABwDHP8AAAAADACGf4AAAAAAAAM/w=="); } else if (msg.positive) { //footer[0] += ((!msg.negative)?" ".repeat(6):"") + " " + "-".repeat(4) + ">"; - footerImgs.pos = {src:atob("QRABAAAAAAAAAAOAAAAABgAAA8AAAAADgAAD4AAAAAHgAAPgAAAAAPgAA+AAAAAAfgAD4///////gAPh///////gA+D///////AD4H//////8cPgAAAAAAPw8+AAAAAAAfB/4AAAAAAA8B/gAAAAAABwB+AAAAAAADAB4AAAAAAAAABgAA=="),col:"#0f0"} + footerImgPos = atob("QRABAAAAAAAAAAOAAAAABgAAA8AAAAADgAAD4AAAAAHgAAPgAAAAAPgAA+AAAAAAfgAD4///////gAPh///////gA+D///////AD4H//////8cPgAAAAAAPw8+AAAAAAAfB/4AAAAAAA8B/gAAAAAABwB+AAAAAAADAB4AAAAAAAAABgAA=="); } if (!footer) { footer = ["-".repeat(12)]; @@ -337,8 +337,8 @@ function showMessagesScroller(msg) { g.setFont(bodyFont).setFontAlign(0,-1).drawString(allLines[scrollIdx], r.x+r.w/2, r.y); if (allLines[scrollIdx]==="") { g. - setColor(footerImgs.neg.col).drawImage(footerImgs.neg.src,r.x+5+3,r.y). - setColor(footerImgs.pos.col).drawImage(footerImgs.pos.src,r.w-64-5,r.y); + setColor("#f00").drawImage(footerImgNeg,r.x+5+3,r.y). + setColor("#0f0").drawImage(footerImgPos,r.w-64-5,r.y); } if (scrollIdxshownScrollIdxLast) {shownScrollIdxLast = scrollIdx;} From e530f4845156094908cb73810a142ce806f1e5d4 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Thu, 27 Mar 2025 00:49:26 +0100 Subject: [PATCH 14/29] messagegui: add a back button image to messagesscroller --- apps/messagegui/app.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 98f51e369c..5761a5049d 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -340,6 +340,9 @@ function showMessagesScroller(msg) { setColor("#f00").drawImage(footerImgNeg,r.x+5+3,r.y). setColor("#0f0").drawImage(footerImgPos,r.w-64-5,r.y); } + if (0===scrollIdx) { + g.setColor("#f00").drawImage(atob("GBiBAAAYAAH/gAf/4A//8B//+D///D///H/P/n+H/n8P/n4f/vwAP/wAP34f/n8P/n+H/n/P/j///D///B//+A//8Af/4AH/gAAYAA=="), r.x, r.y); + } if (scrollIdxshownScrollIdxLast) {shownScrollIdxLast = scrollIdx;} }, From 49a60764e54b7308e100ca54e5f7f20ea4a335bf Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Thu, 27 Mar 2025 01:36:53 +0100 Subject: [PATCH 15/29] messagegui: add hamburger menu indicator to hint that the message settings are available by touching the message. --- apps/messagegui/app.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 5761a5049d..3927dbae92 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -341,7 +341,9 @@ function showMessagesScroller(msg) { setColor("#0f0").drawImage(footerImgPos,r.w-64-5,r.y); } if (0===scrollIdx) { - g.setColor("#f00").drawImage(atob("GBiBAAAYAAH/gAf/4A//8B//+D///D///H/P/n+H/n8P/n4f/vwAP/wAP34f/n8P/n+H/n/P/j///D///B//+A//8Af/4AH/gAAYAA=="), r.x, r.y); + g. + setColor("#f00").drawImage(atob("GBiBAAAYAAH/gAf/4A//8B//+D///D///H/P/n+H/n8P/n4f/vwAP/wAP34f/n8P/n+H/n/P/j///D///B//+A//8Af/4AH/gAAYAA=="), r.x, r.y-1). + setColor(g.theme.fg2).drawImage(atob("GBgBABgAAf+AB//gD//wH//4P//8P//8fAA+fAA+f//+f//+/AA//AA/f//+f//+fAA+fAA+P//8P//8H//4D//wB//gAf+AABgA"),r.w-24,r.y-1); } if (scrollIdxshownScrollIdxLast) {shownScrollIdxLast = scrollIdx;} From 580c39592ec35b3f8d493dbbabb329e26c5bc41c Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Fri, 28 Mar 2025 00:21:36 +0100 Subject: [PATCH 16/29] messagegui: move the back and menu button to their own row --- 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 3927dbae92..d970ec4183 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -282,7 +282,7 @@ function showMessagesScroller(msg) { const FONT_HEIGHT = g.getFontHeight(); let initScroll; var titleLines = []; - let allLines = []; + let allLines = [""]; let firstTitleLinePerMsg = []; let footerImgNeg, footerImgPos; for (let i=0 ; i Date: Fri, 28 Mar 2025 02:10:13 +0100 Subject: [PATCH 17/29] messagegui: misc tweaks --- apps/messagegui/app.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index d970ec4183..4882e6a028 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -280,13 +280,14 @@ function showMessagesScroller(msg) { var bodyFont = fontBig; g.setFont(bodyFont); const FONT_HEIGHT = g.getFontHeight(); - let initScroll; + let initScrollIdx; var titleLines = []; - let allLines = [""]; + let allLines = [" "]; let firstTitleLinePerMsg = []; let footerImgNeg, footerImgPos; for (let i=0 ; i175-30 && xy.y<30) { + Bangle.emit("touch", 2, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:0}); + E.stopEventPropagation(); + if (btnWatch) {clearWatch(btnWatch); btnWatch = undefined;} + Bangle.removeListener("touch", touchHandler); } }; Bangle.prependListener("touch", touchHandler); @@ -401,7 +407,7 @@ function showMessagesScroller(msg) { setTimeout(()=>{ if (!persist) {return load();} Bangle.removeListener("touch", touchHandler); - Bangle.emit("touch", 1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{back:true}}); + Bangle.emit("touch",1, {type:{back:true}}); },0); }, BTN); } From 03d12b2efd318de93ce1ec08a3cd75e34d4d2460 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 29 Mar 2025 20:55:48 +0100 Subject: [PATCH 18/29] messagegui: small tweaks --- 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 4882e6a028..cbdb4343a5 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -384,6 +384,7 @@ function showMessagesScroller(msg) { // if ((left side of Banlge 1 screen) || (top left corner of Bangle 2 screen)) if ((!xy && 1===button) || (xy && xy.type===0 && xy.x<30 && xy.y<30)) { if (!persist) {return load();} + WU&&WU.show(); returnToMain(); E.stopEventPropagation(); Bangle.removeListener("touch", touchHandler); @@ -407,7 +408,7 @@ function showMessagesScroller(msg) { setTimeout(()=>{ if (!persist) {return load();} Bangle.removeListener("touch", touchHandler); - Bangle.emit("touch",1, {type:{back:true}}); + Bangle.emit("touch",1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{back:true}}); },0); }, BTN); } From f01b30dc97060fa0a9c9b424f6d4ee34c3ab8795 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 13:40:02 +0200 Subject: [PATCH 19/29] messagegui: add back persist variable that got lost --- apps/messagegui/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index cbdb4343a5..4fb7940817 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -49,6 +49,7 @@ if (Graphics.prototype.setFontIntl) { 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 +var persist = "messagegui.app.js" === global.__FILE__; /** this is a timeout if the app has started and is showing a single message but the user hasn't seen it (eg no user input) - in which case From 6f6d4d7f39d5543b5fab99e79e603030712ec339 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 14:03:04 +0200 Subject: [PATCH 20/29] messagegui: move hw btn action to back fn of E.showScroller Instead of adding an external button handler. This works now that [the red back widget is not added if widgets are not shown](https://github.com/espruino/Espruino/commit/453def81645c08e46195ad0627c1b77c8a59ee2a). This means we should wait for fw 2v26 stable before maybe merging this change to espruino/BangleApps. --- apps/messagegui/app.js | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 4fb7940817..05327dc7e8 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -377,6 +377,11 @@ function showMessagesScroller(msg) { break; } } + }, + back: function () { + if (!persist) { return load(); } + Bangle.removeListener("touch", touchHandler); + Bangle.emit("touch", 1, { x: Math.floor(APP_RECT.x2 / 2), y: Math.floor(APP_RECT.y2 / 2), type: { back: true } }); } }); @@ -389,32 +394,14 @@ function showMessagesScroller(msg) { returnToMain(); E.stopEventPropagation(); Bangle.removeListener("touch", touchHandler); - if (btnWatch) {clearWatch(btnWatch); btnWatch = undefined;} } else if (xy && xy.type===0 && xy.x>175-30 && xy.y<30) { Bangle.emit("touch", 2, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:0}); E.stopEventPropagation(); - if (btnWatch) {clearWatch(btnWatch); btnWatch = undefined;} Bangle.removeListener("touch", touchHandler); } }; Bangle.prependListener("touch", touchHandler); - // If Bangle.js 2 add an external back hw button handler. - let btnWatch; - if (2===process.env.HWVERSION) { - btnWatch = setWatch(()=>{ - if ("scroller"!==active) {return;} - 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 (!persist) {return load();} - Bangle.removeListener("touch", touchHandler); - Bangle.emit("touch",1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{back:true}}); - },0); - }, BTN); - } - - function updateReadMessages() { let shownMsgIdxFirst, shownMsgIdxLast; const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; From 1df532bf0d57f88a1f1be8aa0482066332533426 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 15:24:51 +0200 Subject: [PATCH 21/29] messagegui: separate logic to find selected msg to helper fn --- apps/messagegui/app.js | 57 ++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 05327dc7e8..fa701b34a3 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -351,31 +351,29 @@ function showMessagesScroller(msg) { if (scrollIdx>shownScrollIdxLast) {shownScrollIdxLast = scrollIdx;} }, select : function(scrollIdx, touch) { - for (let i=firstTitleLinePerMsg.length-1; i>=0 ; i--) { - if (scrollIdx>=firstTitleLinePerMsg[i]) { - if (touch && touch.type===2) {return;} - const MSG_SELECTED = MESSAGES[i]; - WU&&WU.show(); - print(process.memory()); - E.showScroller(); - print(process.memory()); - updateReadMessages(); - delete titleLines, allLines; - if (touch && touch.type.back) { - returnToMain(); - } else if (!touch || touch.type===0) { - setTimeout(()=>{ - showMessageSettings(MSG_SELECTED) - },0); - } - //print(touch) - if (touch && touch.type.swipeLR) { - //print("select swipe") - if (touch.type.swipeLR>0 && posHandler) {posHandler(MSG_SELECTED);} - if (touch.type.swipeLR<0 && negHandler) {negHandler(MSG_SELECTED);} - } - break; - } + if (touch && touch.type===2) {return;} + const MSG_SELECTED = findSelectedMsg(scrollIdx); + WU&&WU.show(); + + print(process.memory().free); + E.showScroller(); + Bangle.removeListener("swipe", Bangle.swipeHandler); + Bangle.removeListener("touch", touchHandler); + print(process.memory().free); + updateReadMessages(); + delete titleLines, allLines; + if (touch && touch.type.back) { + returnToMain(); + } else if (!touch || touch.type===0) { + setTimeout(()=>{ + showMessageSettings(MSG_SELECTED) + },0); + } + //print(touch) + if (touch && touch.type.swipeLR) { + //print("select swipe") + if (touch.type.swipeLR>0 && posHandler) {posHandler(MSG_SELECTED);} + if (touch.type.swipeLR<0 && negHandler) {negHandler(MSG_SELECTED);} } }, back: function () { @@ -385,6 +383,15 @@ function showMessagesScroller(msg) { } }); + // helper function for message selection + let findSelectedMsg = function(scrollIdx) { + for (let i = firstTitleLinePerMsg.length - 1; i >= 0; i--) { + if (scrollIdx >= firstTitleLinePerMsg[i]) { + return MESSAGES[i]; + } + } + } + // Add an external back touch handler. let touchHandler = (button, xy)=>{ // if ((left side of Banlge 1 screen) || (top left corner of Bangle 2 screen)) From ad59ca7dee440ded5829df06a73ca091a2eb87bb Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 15:46:56 +0200 Subject: [PATCH 22/29] messagegui: restructuring and adding some descriptive cmnts --- apps/messagegui/app.js | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index fa701b34a3..fd650de13a 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -383,16 +383,17 @@ function showMessagesScroller(msg) { } }); - // helper function for message selection - let findSelectedMsg = function(scrollIdx) { - for (let i = firstTitleLinePerMsg.length - 1; i >= 0; i--) { - if (scrollIdx >= firstTitleLinePerMsg[i]) { - return MESSAGES[i]; - } - } - } + //// Additional input handling to extend that of E.showScroller //// + + // Input handling for positive and negative response via swipes. + // Emits a touch event that in turn triggers the select function of E.showScroller above. + Bangle.swipeHandler = (lr) => { + if (lr) {Bangle.emit("touch", 1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{swipeLR:lr}});} + }; + Bangle.on("swipe", Bangle.swipeHandler); // Add an external back touch handler. + // Emits a new touch event that in turn triggers the select function of E.showScroller above. let touchHandler = (button, xy)=>{ // if ((left side of Banlge 1 screen) || (top left corner of Bangle 2 screen)) if ((!xy && 1===button) || (xy && xy.type===0 && xy.x<30 && xy.y<30)) { @@ -409,6 +410,18 @@ function showMessagesScroller(msg) { }; Bangle.prependListener("touch", touchHandler); + //// Helper functions //// + + // helper function for message selection + let findSelectedMsg = function(scrollIdx) { + for (let i = firstTitleLinePerMsg.length - 1; i >= 0; i--) { + if (scrollIdx >= firstTitleLinePerMsg[i]) { + return MESSAGES[i]; + } + } + } + + // Helper function to update new status of messages function updateReadMessages() { let shownMsgIdxFirst, shownMsgIdxLast; const LINES_PER_SCREEN = APP_RECT.h/FONT_HEIGHT; @@ -446,6 +459,8 @@ function showMessagesScroller(msg) { } //print(MESSAGES) } + + // Helper functions to handle positive and negative responses to messages var negHandler,posHandler = [ ]; if (msg.negative) { negHandler = (msg)=>{ @@ -486,10 +501,6 @@ function showMessagesScroller(msg) { }; //footer.push({type:"img",src:atob("QRABAAAAAAAAAAOAAAAABgAAA8AAAAADgAAD4AAAAAHgAAPgAAAAAPgAA+AAAAAAfgAD4///////gAPh///////gA+D///////AD4H//////8cPgAAAAAAPw8+AAAAAAAfB/4AAAAAAA8B/gAAAAAABwB+AAAAAAADAB4AAAAAAAAABgAA=="),col:"#0f0",cb:posHandler}); } - Bangle.swipeHandler = (lr) => { - if (lr) {Bangle.emit("touch", 1, {x:Math.floor(APP_RECT.x2/2), y:Math.floor(APP_RECT.y2/2), type:{swipeLR:lr}});} - }; - Bangle.on("swipe", Bangle.swipeHandler); } function showMessageSettings(msg) { From 8ae6e674af1f4a1b387029c9ff153cd33efa4010 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 15:52:16 +0200 Subject: [PATCH 23/29] messagegui: remove back fn reliance on select fn ... in E.showScroller --- apps/messagegui/app.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index fd650de13a..af5de48202 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -362,9 +362,7 @@ function showMessagesScroller(msg) { print(process.memory().free); updateReadMessages(); delete titleLines, allLines; - if (touch && touch.type.back) { - returnToMain(); - } else if (!touch || touch.type===0) { + if (!touch || touch.type===0) { setTimeout(()=>{ showMessageSettings(MSG_SELECTED) },0); @@ -379,7 +377,7 @@ function showMessagesScroller(msg) { back: function () { if (!persist) { return load(); } Bangle.removeListener("touch", touchHandler); - Bangle.emit("touch", 1, { x: Math.floor(APP_RECT.x2 / 2), y: Math.floor(APP_RECT.y2 / 2), type: { back: true } }); + returnToMain(); } }); From 0c3cffe7af6315c413f201e286d8d0986b004289 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 16:11:02 +0200 Subject: [PATCH 24/29] messagegui: use global consistently, not globalThis. --- apps/messagegui/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index af5de48202..5475497865 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -722,10 +722,10 @@ function checkMessages(options) { delete newMessages[0].show; // stop us getting stuck here if we're called a second time showMessagesScroller(newMessages[0]); // buzz after showMessagesScroller, so being busy during scroller setup doesn't affect the buzz pattern - if (globalThis.BUZZ_ON_NEW_MESSAGE) { + 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 - globalThis.BUZZ_ON_NEW_MESSAGE = false; + global.BUZZ_ON_NEW_MESSAGE = false; // messages.buzz respects quiet mode - no need to check here require("messages").buzz(newMessages[0].src); } From 98d79988b398c60e350ce57f9d971915cb47bf1a Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 17:39:21 +0200 Subject: [PATCH 25/29] messagegui: remove dead code for music handling --- apps/messagegui/app.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 5475497865..fc3fc7021c 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -731,9 +731,6 @@ function checkMessages(options) { } return; } - // 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 showMessageOverview('music'); // no new messages - go to clock? if (options.clockIfAllRead && newMessages.length==0) return load(); From 5027312de96fdec862f3a6ef292768e0c1b23659 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 20:05:03 +0200 Subject: [PATCH 26/29] messagegui: keep idx info of selected messages in messagesScroller --- apps/messagegui/app.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index fc3fc7021c..29b789277a 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -352,7 +352,8 @@ function showMessagesScroller(msg) { }, select : function(scrollIdx, touch) { if (touch && touch.type===2) {return;} - const MSG_SELECTED = findSelectedMsg(scrollIdx); + const MSG_SELECTED_IDX = findSelectedMsgIdx(scrollIdx); + const MSG_SELECTED = MESSAGES[MSG_SELECTED_IDX]; WU&&WU.show(); print(process.memory().free); @@ -411,10 +412,10 @@ function showMessagesScroller(msg) { //// Helper functions //// // helper function for message selection - let findSelectedMsg = function(scrollIdx) { + let findSelectedMsgIdx = function(scrollIdx) { for (let i = firstTitleLinePerMsg.length - 1; i >= 0; i--) { if (scrollIdx >= firstTitleLinePerMsg[i]) { - return MESSAGES[i]; + return i; } } } From 3e95bafe023becced3dffd95fe920e6c381edb5c Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 21 Apr 2025 20:09:59 +0200 Subject: [PATCH 27/29] messagegui: fix marking messages read --- 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 29b789277a..30535db30e 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -369,8 +369,9 @@ function showMessagesScroller(msg) { },0); } //print(touch) - if (touch && touch.type.swipeLR) { + if (touch && touch.type.swipeLR!=0) { //print("select swipe") + updateReadMessages(); if (touch.type.swipeLR>0 && posHandler) {posHandler(MSG_SELECTED);} if (touch.type.swipeLR<0 && negHandler) {negHandler(MSG_SELECTED);} } @@ -378,6 +379,8 @@ function showMessagesScroller(msg) { back: function () { if (!persist) { return load(); } Bangle.removeListener("touch", touchHandler); + updateReadMessages(); + WU&&WU.show(); returnToMain(); } }); From dff3bc736dafb6bed9f33a12d49598d889367c95 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Tue, 22 Apr 2025 02:21:39 +0200 Subject: [PATCH 28/29] messagegui: fix calls so the route to the overview screen --- 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 30535db30e..760fa0ada9 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -724,7 +724,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 - showMessagesScroller(newMessages[0]); + showMessageRouter(newMessages[0], persist); // 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` From 7a449d860e75beddf6b3470ba90df5be56350b02 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Tue, 22 Apr 2025 13:39:59 +0200 Subject: [PATCH 29/29] messagegui: default route msg to messagesScroller --- apps/messagegui/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 760fa0ada9..b5c06a902f 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -118,6 +118,7 @@ function showMessageRouter(msg, persist, explicitDestnation) { if ("list"===active) {return returnToMain();} if ("settings"===active || "overview"===active) {return;} } + return showMessagesScroller(msg); //if (false) {showMessageSettings(msg);} }