From b44dd75e3e19c9f740ffabc9d5c3b0d7d61349d4 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 30 Oct 2024 08:40:57 +0000 Subject: [PATCH 01/15] settings: fix indent --- apps/setting/settings.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index d9d77d052..ccaec1558 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -274,11 +274,11 @@ function showThemeMenu() { let newTheme = storage.readJSON(n); themesMenu[newTheme.name ? newTheme.name : n] = () => { upd({ - fg:cl(newTheme.fg), bg:cl(newTheme.bg), - fg2:cl(newTheme.fg2), bg2:cl(newTheme.bg2), - fgH:cl(newTheme.fgH), bgH:cl(newTheme.bgH), - dark:newTheme.dark - }); + fg:cl(newTheme.fg), bg:cl(newTheme.bg), + fg2:cl(newTheme.fg2), bg2:cl(newTheme.bg2), + fgH:cl(newTheme.fgH), bgH:cl(newTheme.bgH), + dark:newTheme.dark + }); }; } ); From d7d60b4bca12093022ea6fd5a69635dc25149d5d Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 30 Oct 2024 08:41:24 +0000 Subject: [PATCH 02/15] settings: delete duplicate "< Back" setting --- apps/setting/settings.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index ccaec1558..cf82aedd7 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -341,7 +341,6 @@ function showThemeMenu() { }, }; }); - menu["< Back"] = () => showThemeMenu(); m = E.showMenu(menu); } } From 9503c0fc6b6d86ac1abb4bfbfce37ef9dd4ca6ba Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 30 Oct 2024 08:43:08 +0000 Subject: [PATCH 03/15] settings: remember previous menu's scroll position --- apps/setting/settings.js | 202 +++++++++++++++++++++++---------------- 1 file changed, 118 insertions(+), 84 deletions(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index cf82aedd7..56549227f 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -5,12 +5,38 @@ Bangle.drawWidgets(); const BANGLEJS2 = process.env.HWVERSION==2; const storage = require('Storage'); let settings; +const scrolls = []; +let menuScroller; function updateSettings() { //storage.erase('setting.json'); // - not needed, just causes extra writes if settings were the same storage.write('setting.json', settings); } +function pushMenu(menu) { + if(menuScroller) scrolls.push(menuScroller.scroll); + + // if !menu, we're just pushing and something else takes + // care of E.showMenu() + if(menu) { + const m = E.showMenu(menu); + menuScroller = m.scroller; + return m; + } +} + +function restoreMenu(menu) { + if(!menu[""]) menu[""] = {}; + menu[""].scroll = scrolls[scrolls.length - 1] | 0; + menuScroller = E.showMenu(menu).scroller; +} + +function popMenu(menu) { + if(!menu[""]) menu[""] = {}; + menu[""].scroll = scrolls.pop() | 0; + menuScroller = E.showMenu(menu).scroller; +} + function updateOptions() { var o = settings.options; // Check to make sure nobody disabled all wakeups and locked themselves out! @@ -65,38 +91,38 @@ if (("object" != typeof settings) || ("object" != typeof settings.options)) resetSettings(); -function showMainMenu() { +function mainMenu() { const mainmenu = { '': { 'title': /*LANG*/'Settings' }, '< Back': ()=>load(), - /*LANG*/'Apps': ()=>showAppSettingsMenu(), - /*LANG*/'System': ()=>showSystemMenu(), - /*LANG*/'Bluetooth': ()=>showBLEMenu(), - /*LANG*/'Alerts': ()=>showAlertsMenu(), - /*LANG*/'Utils': ()=>showUtilMenu() + /*LANG*/'Apps': ()=>pushMenu(appSettingsMenu()), + /*LANG*/'System': ()=>pushMenu(systemMenu()), + /*LANG*/'Bluetooth': ()=>pushMenu(BLEMenu()), + /*LANG*/'Alerts': ()=>pushMenu(alertsMenu()), + /*LANG*/'Utils': ()=>pushMenu(utilMenu()) }; - return E.showMenu(mainmenu); + return mainmenu; } -function showSystemMenu() { +function systemMenu() { const mainmenu = { '': { 'title': /*LANG*/'System' }, - '< Back': ()=>showMainMenu(), - /*LANG*/'Theme': ()=>showThemeMenu(), - /*LANG*/'LCD': ()=>showLCDMenu(), - /*LANG*/'Locale': ()=>showLocaleMenu(), - /*LANG*/'Clock': ()=>showClockMenu(), - /*LANG*/'Launcher': ()=>showLauncherMenu(), - /*LANG*/'Date & Time': ()=>showSetTimeMenu() + '< Back': ()=>popMenu(mainMenu()), + /*LANG*/'Theme': ()=>pushMenu(themeMenu()), + /*LANG*/'LCD': ()=>pushMenu(LCDMenu()), + /*LANG*/'Locale': ()=>pushMenu(localeMenu()), + /*LANG*/'Clock': ()=>pushMenu(clockMenu()), + /*LANG*/'Launcher': ()=>pushMenu(launcherMenu()), + /*LANG*/'Date & Time': ()=>pushMenu(setTimeMenu()) }; - return E.showMenu(mainmenu); + return mainmenu; } -function showAlertsMenu() { +function alertsMenu() { var beepMenuItem; if (BANGLEJS2) { beepMenuItem = { @@ -128,7 +154,7 @@ function showAlertsMenu() { const mainmenu = { '': { 'title': /*LANG*/'Alerts' }, - '< Back': ()=>showMainMenu(), + '< Back': ()=>popMenu(mainMenu()), /*LANG*/'Beep': beepMenuItem, /*LANG*/'Vibration': { value: settings.vibrate, @@ -153,18 +179,18 @@ function showAlertsMenu() { } }; - return E.showMenu(mainmenu); + return mainmenu; } -function showBLEMenu() { +function BLEMenu() { var hidV = [false, "kbmedia", "kb", "com", "joy"]; var hidN = [/*LANG*/"Off", /*LANG*/"Kbrd & Media", /*LANG*/"Kbrd", /*LANG*/"Kbrd & Mouse", /*LANG*/"Joystick"]; var privacy = [/*LANG*/"Off", /*LANG*/"Show name", /*LANG*/"Hide name"]; - E.showMenu({ + return { '': { 'title': /*LANG*/'Bluetooth' }, - '< Back': ()=>showMainMenu(), + '< Back': ()=>popMenu(mainMenu()), /*LANG*/'Make Connectable': ()=>makeConnectable(), /*LANG*/'BLE': { value: settings.ble, @@ -217,7 +243,7 @@ function showBLEMenu() { }, /*LANG*/'Passkey': { value: settings.passkey?settings.passkey:/*LANG*/"none", - onchange: () => setTimeout(showPasskeyMenu) // graphical_menu redraws after the call + onchange: () => setTimeout(() => pushMenu(passkeyMenu())) // graphical_menu redraws after the call }, /*LANG*/'Whitelist': { value: @@ -228,12 +254,12 @@ function showBLEMenu() { ? " (" + settings.whitelist.length + ")" : "" ), - onchange: () => setTimeout(showWhitelistMenu) // graphical_menu redraws after the call + onchange: () => setTimeout(() => pushMenu(whitelistMenu())) // graphical_menu redraws after the call } - }); + }; } -function showThemeMenu() { +function themeMenu() { function cl(x) { return g.setColor(x).getColor(); } function upd(th) { g.theme = th; @@ -250,7 +276,7 @@ function showThemeMenu() { var themesMenu = { '':{title:/*LANG*/'Theme'}, - '< Back': ()=>showSystemMenu(), + '< Back': ()=>popMenu(systemMenu()), /*LANG*/'Dark BW': ()=>{ upd({ fg:cl("#fff"), bg:cl("#000"), @@ -283,11 +309,11 @@ function showThemeMenu() { } ); - themesMenu[/*LANG*/'Customize'] = () => showCustomThemeMenu(); + themesMenu[/*LANG*/'Customize'] = () => pushMenu(customThemeMenu()); - var m = E.showMenu(themesMenu); + var m = pushMenu(themesMenu); - function showCustomThemeMenu() { + function customThemeMenu() { function setT(t, v) { let th = g.theme; th[t] = v; @@ -318,7 +344,7 @@ function showThemeMenu() { } let menu = { '':{title:/*LANG*/'Custom Theme'}, - "< Back": () => showThemeMenu() + "< Back": () => popMenu(themeMenu()) }; const labels = { fg: /*LANG*/'Foreground', bg: /*LANG*/'Background', @@ -341,17 +367,17 @@ function showThemeMenu() { }, }; }); - m = E.showMenu(menu); + m = pushMenu(menu); } } -function showPasskeyMenu() { +function passkeyMenu() { var menu = { - "< Back" : ()=>showBLEMenu(), + "< Back" : ()=>popMenu(BLEMenu()), /*LANG*/"Disable" : () => { settings.passkey = undefined; updateSettings(); - showBLEMenu(); + popMenu(BLEMenu()); } }; if (!settings.passkey || settings.passkey.length!=6) { @@ -370,24 +396,24 @@ function showPasskeyMenu() { } }; })(i); - E.showMenu(menu); + return menu; } -function showWhitelistMenu() { +function whitelistMenu() { var menu = { - "< Back" : ()=>showBLEMenu(), + "< Back" : ()=>popMenu(BLEMenu()), }; if (settings.whitelist_disabled) { menu[/*LANG*/"Enable"] = () => { delete settings.whitelist_disabled; updateSettings(); - showBLEMenu(); + popMenu(BLEMenu()); }; } else { menu[/*LANG*/"Disable"] = () => { settings.whitelist_disabled = true; updateSettings(); - showBLEMenu(); + popMenu(BLEMenu()); }; } @@ -398,14 +424,14 @@ function showWhitelistMenu() { settings.whitelist.splice(settings.whitelist.indexOf(d),1); updateSettings(); } - setTimeout(showWhitelistMenu, 50); + setTimeout(() => pushMenu(whitelistMenu()), 50); }); } }); menu[/*LANG*/'Add Device']=function() { E.showAlert(/*LANG*/"Connect device\nto add to\nwhitelist",/*LANG*/"Whitelist").then(function() { NRF.removeAllListeners('connect'); - showWhitelistMenu(); + pushMenu(whitelistMenu()); }); NRF.removeAllListeners('connect'); NRF.on('connect', function(addr) { @@ -420,13 +446,13 @@ function showWhitelistMenu() { settings.whitelist.push(addr); updateSettings(); NRF.removeAllListeners('connect'); - showWhitelistMenu(); + pushMenu(whitelistMenu()); }); }; - E.showMenu(menu); + return menu; } -function showLCDMenu() { +function LCDMenu() { // converts g to Espruino internal unit function gToInternal(g) { return g * 8192; } // converts Espruino internal unit to g @@ -436,7 +462,7 @@ function showLCDMenu() { const lcdMenu = { '': { 'title': 'LCD' }, - '< Back': ()=>showSystemMenu(), + '< Back': ()=>popMenu(systemMenu()), }; if (BANGLEJS2) Object.assign(lcdMenu, { @@ -583,13 +609,13 @@ function showLCDMenu() { } }); - return E.showMenu(lcdMenu) + return lcdMenu } -function showLocaleMenu() { +function localeMenu() { const localemenu = { '': { 'title': /*LANG*/'Locale' }, - '< Back': ()=>showSystemMenu(), + '< Back': ()=>popMenu(systemMenu()), /*LANG*/'Time Zone': { value: settings.timezone, format: v => (v > 0 ? "+" : "") + v, @@ -620,13 +646,13 @@ function showLocaleMenu() { }, } }; - return E.showMenu(localemenu); + return localemenu; } -function showUtilMenu() { +function utilMenu() { var menu = { '': { 'title': /*LANG*/'Utilities' }, - '< Back': ()=>showMainMenu(), + '< Back': ()=>popMenu(mainMenu()), /*LANG*/'Debug': { value: E.clip(0|settings.log,0,3), min: 0, @@ -640,7 +666,7 @@ function showUtilMenu() { /*LANG*/'Compact Storage': () => { E.showMessage(/*LANG*/"Compacting...\nTakes approx\n1 minute",{title:/*LANG*/"Storage"}); storage.compact(); - showUtilMenu(); + restoreMenu(utilMenu()); }, /*LANG*/'Rewrite Settings': () => { storage.write(".boot0","eval(require('Storage').read('bootupdate.js'));"); @@ -660,9 +686,13 @@ function showUtilMenu() { }, 1); } }; + const back = () => { + restoreMenu(utilMenu()); + }; + if (BANGLEJS2) menu[/*LANG*/'Calibrate Battery'] = () => { - E.showPrompt(/*LANG*/"Is the battery fully charged?",{title:/*LANG*/"Calibrate",back:showUtilMenu}).then(ok => { + E.showPrompt(/*LANG*/"Is the battery fully charged?",{title:/*LANG*/"Calibrate",back}).then(ok => { if (ok) { var s=storage.readJSON("setting.json"); s.batFullVoltage = (analogRead(D3)+analogRead(D3)+analogRead(D3)+analogRead(D3))/4; @@ -674,17 +704,17 @@ function showUtilMenu() { }); }; menu[/*LANG*/'Reset Settings'] = () => { - E.showPrompt(/*LANG*/'Reset to Defaults?',{title:/*LANG*/"Settings",back:showUtilMenu}).then((v) => { + E.showPrompt(/*LANG*/'Reset to Defaults?',{title:/*LANG*/"Settings",back}).then((v) => { if (v) { E.showMessage(/*LANG*/'Resetting'); resetSettings(); - setTimeout(showMainMenu, 50); - } else showUtilMenu(); + setTimeout(() => popMenu(mainMenu), 50); + } else restoreMenu(utilMenu()); }); }; menu[/*LANG*/"Turn Off"] = () => { E.showPrompt(/*LANG*/"Are you sure? Alarms and timers won't fire", { - title:/*LANG*/"Turn Off",back:showUtilMenu + title:/*LANG*/"Turn Off",back }).then((confirmed) => { if (confirmed) { E.showMessage(/*LANG*/"See you\nlater!", /*LANG*/"Goodbye"); @@ -697,34 +727,34 @@ function showUtilMenu() { Bangle.softOff ? Bangle.softOff() : Bangle.off(); }, 2500); } else { - showUtilMenu(); + restoreMenu(utilMenu()); } }); }; if (Bangle.factoryReset) { menu[/*LANG*/'Factory Reset'] = ()=>{ - E.showPrompt(/*LANG*/'This will remove everything!',{title:/*LANG*/"Factory Reset",back:showUtilMenu}).then((v) => { + E.showPrompt(/*LANG*/'This will remove everything!',{title:/*LANG*/"Factory Reset",back}).then((v) => { if (v) { var n = ((Math.random()*4)&3) + 1; E.showPrompt(/*LANG*/"To confirm, please press "+n,{ title:/*LANG*/"Factory Reset", buttons : {"1":1,"2":2,"3":3,"4":4}, - back:showUtilMenu + back }).then(function(v) { if (v==n) { E.showMessage(); Terminal.setConsole(); Bangle.factoryReset(); } else { - showUtilMenu(); + back(); } }); - } else showUtilMenu(); + } else back(); }); } } - return E.showMenu(menu); + return menu; } function makeConnectable() { @@ -739,19 +769,20 @@ function makeConnectable() { } if (!r) try { NRF.sleep(); } catch (e) { } delete NRF.ignoreWhitelist; - showMainMenu(); + popMenu(mainMenu()); }); } -function showClockMenu() { +function clockMenu() { var clockApps = storage.list(/\.info$/) .map(app => {var a=storage.readJSON(app, 1);return (a&&a.type == "clock")?a:undefined}) .filter(app => app) // filter out any undefined apps .sort((a, b) => a.sortorder - b.sortorder); + const back = ()=>popMenu(systemMenu()); const clockMenu = { '': { 'title': /*LANG*/'Select Clock', }, - '< Back': ()=>showSystemMenu(), + '< Back': back, }; clockApps.forEach((app, index) => { var label = app.name; @@ -762,24 +793,25 @@ function showClockMenu() { settings.clock = app.src; settings.clockHasWidgets = storage.read(app.src).includes("Bangle.loadWidgets"); updateSettings(); - showMainMenu(); + back(); }; }); if (clockApps.length === 0) { clockMenu[/*LANG*/"No Clocks Found"] = () => { }; } - return E.showMenu(clockMenu); + return clockMenu; } -function showLauncherMenu() { +function launcherMenu() { var launcherApps = storage.list(/\.info$/) .map(app => {var a=storage.readJSON(app, 1);return (a&&a.type == "launch")?a:undefined}) .filter(app => app) // filter out any undefined apps .sort((a, b) => a.sortorder - b.sortorder); + const back = ()=>popMenu(systemMenu()); const launcherMenu = { '': { 'title': /*LANG*/'Select Launcher', }, - '< Back': ()=>showSystemMenu(), + '< Back': back, }; launcherApps.forEach((app, index) => { var label = app.name; @@ -789,22 +821,22 @@ function showLauncherMenu() { launcherMenu[label] = () => { settings.launcher = app.src; updateSettings(); - showMainMenu(); + back(); }; }); if (launcherApps.length === 0) { launcherMenu[/*LANG*/"No Launchers Found"] = () => { }; } - return E.showMenu(launcherMenu); + return launcherMenu; } -function showSetTimeMenu() { +function setTimeMenu() { let d = new Date(); const timemenu = { '': { 'title': /*LANG*/'Date & Time' }, '< Back': function () { setTime(d.getTime() / 1000); - showSystemMenu(); + popMenu(systemMenu()); }, /*LANG*/'Day': { value: d.getDate(), @@ -851,13 +883,13 @@ function showSetTimeMenu() { } } }; - return E.showMenu(timemenu); + return timemenu; } -function showAppSettingsMenu() { +function appSettingsMenu() { let appmenu = { '': { 'title': /*LANG*/'App Settings' }, - '< Back': ()=>showMainMenu(), + '< Back': ()=>popMenu(mainMenu()), } const apps = storage.list(/\.settings\.js$/) .map(s => s.substr(0, s.length-12)) @@ -878,12 +910,13 @@ function showAppSettingsMenu() { apps.forEach(function (app) { appmenu[app.name] = () => { showAppSettings(app) }; }) - E.showMenu(appmenu) + return appmenu; } function showAppSettings(app) { + const back = () => popMenu(appSettingsMenu()); const showError = msg => { E.showMessage(`${app.name}:\n${msg}!\n\nBTN1 to go back`); - setWatch(showAppSettingsMenu, BTN1, { repeat: false }); + setWatch(back, BTN1, { repeat: false }); } let appSettings = storage.read(app.id+'.settings.js'); try { @@ -896,8 +929,9 @@ function showAppSettings(app) { return showError(/*LANG*/'Invalid settings'); } try { - // pass showAppSettingsMenu as "back" argument - appSettings(()=>showAppSettingsMenu()); + // pass appSettingsMenu as "back" argument + pushMenu(); + appSettings(back); } catch (e) { console.log(`${app.name} settings error:`, e); return showError(/*LANG*/'Error in settings'); @@ -961,7 +995,7 @@ function showTouchscreenCalibration() { g.setFont("6x8:2").setFontAlign(0,0).drawString(/*LANG*/"Calibrated!", g.getWidth()/2, g.getHeight()/2); } // now load the main menu again - setTimeout(showLCDMenu, 500); + setTimeout(() => restoreMenu(LCDMenu), 500); } function touchHandler(_,e) { @@ -993,5 +1027,5 @@ function showTouchscreenCalibration() { showTapSpot(); } -showMainMenu(); +pushMenu(mainMenu()); } From 75ed3daf526b3cd095f80b033e569bf9d37f78b7 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 30 Oct 2024 08:53:23 +0000 Subject: [PATCH 04/15] settings: special-case theme menu (push & pop) --- apps/setting/settings.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 56549227f..723f420c5 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -111,7 +111,7 @@ function systemMenu() { const mainmenu = { '': { 'title': /*LANG*/'System' }, '< Back': ()=>popMenu(mainMenu()), - /*LANG*/'Theme': ()=>pushMenu(themeMenu()), + /*LANG*/'Theme': ()=>showThemeMenu(), /*LANG*/'LCD': ()=>pushMenu(LCDMenu()), /*LANG*/'Locale': ()=>pushMenu(localeMenu()), /*LANG*/'Clock': ()=>pushMenu(clockMenu()), @@ -259,7 +259,7 @@ function BLEMenu() { }; } -function themeMenu() { +function showThemeMenu(pop) { function cl(x) { return g.setColor(x).getColor(); } function upd(th) { g.theme = th; @@ -309,11 +309,11 @@ function themeMenu() { } ); - themesMenu[/*LANG*/'Customize'] = () => pushMenu(customThemeMenu()); + themesMenu[/*LANG*/'Customize'] = () => showCustomThemeMenu(); - var m = pushMenu(themesMenu); + var m = (pop ? popMenu : pushMenu)(themesMenu); - function customThemeMenu() { + function showCustomThemeMenu() { function setT(t, v) { let th = g.theme; th[t] = v; @@ -344,7 +344,7 @@ function themeMenu() { } let menu = { '':{title:/*LANG*/'Custom Theme'}, - "< Back": () => popMenu(themeMenu()) + "< Back": () => showThemeMenu(1) }; const labels = { fg: /*LANG*/'Foreground', bg: /*LANG*/'Background', From 83e647ac9b8b0907738468bbd5cd64acf8372458 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 30 Oct 2024 18:24:54 +0000 Subject: [PATCH 05/15] settings: bump version --- apps/setting/ChangeLog | 3 ++- apps/setting/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index 27aa5c90c..e3c0955be 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -82,4 +82,5 @@ of 'Select Clock' 0.71: Minor code improvements 0.72: Add setting for configuring BLE privacy 0.73: Fix `const` bug / work with fastload -0.74: Add extra layer of checks before allowing a factory reset (fix #3476) \ No newline at end of file +0.74: Add extra layer of checks before allowing a factory reset (fix #3476) +0.75: Restore previous menu's scroll positions diff --git a/apps/setting/metadata.json b/apps/setting/metadata.json index 67ca847d9..9383e7343 100644 --- a/apps/setting/metadata.json +++ b/apps/setting/metadata.json @@ -1,7 +1,7 @@ { "id": "setting", "name": "Settings", - "version": "0.74", + "version": "0.75", "description": "A menu for setting up Bangle.js", "icon": "settings.png", "tags": "tool,system", From 516e17d0d86c6ea244c0f8d3bd9b20bf3729390f Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 12 Nov 2024 17:49:56 +0000 Subject: [PATCH 06/15] settings: return the new menu from popMenu (for theme) --- apps/setting/settings.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 723f420c5..9b1895760 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -34,7 +34,9 @@ function restoreMenu(menu) { function popMenu(menu) { if(!menu[""]) menu[""] = {}; menu[""].scroll = scrolls.pop() | 0; - menuScroller = E.showMenu(menu).scroller; + const m = E.showMenu(menu); + menuScroller = m.scroller; + return m; } function updateOptions() { From 726807b0f82f1b95551df06fcb3656ca58e49c9c Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 12 Nov 2024 17:51:34 +0000 Subject: [PATCH 07/15] settings: fix missing call for touch calibration menu --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 9b1895760..9f49cc920 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -997,7 +997,7 @@ function showTouchscreenCalibration() { g.setFont("6x8:2").setFontAlign(0,0).drawString(/*LANG*/"Calibrated!", g.getWidth()/2, g.getHeight()/2); } // now load the main menu again - setTimeout(() => restoreMenu(LCDMenu), 500); + setTimeout(() => restoreMenu(LCDMenu()), 500); } function touchHandler(_,e) { From 3bdde4d629d2b556cf972113be088a3b24273417 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 19 Nov 2024 22:11:13 +0000 Subject: [PATCH 08/15] settings: fix missing call on reset menu --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 9f49cc920..80701af6c 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -710,7 +710,7 @@ function utilMenu() { if (v) { E.showMessage(/*LANG*/'Resetting'); resetSettings(); - setTimeout(() => popMenu(mainMenu), 50); + setTimeout(() => popMenu(mainMenu()), 50); } else restoreMenu(utilMenu()); }); }; From 6c00324db6f47ad34004148f7704c99d2bf4371f Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 12 Nov 2024 17:53:42 +0000 Subject: [PATCH 09/15] settings: restore ble menu after connectable ... rather than going back to the main menu --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 80701af6c..a8503c6ed 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -771,7 +771,7 @@ function makeConnectable() { } if (!r) try { NRF.sleep(); } catch (e) { } delete NRF.ignoreWhitelist; - popMenu(mainMenu()); + restoreMenu(BLEMenu()); }); } function clockMenu() { From 6c1596de1daca916ea7751ee8e38bb4cb34b0357 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 12 Nov 2024 18:01:10 +0000 Subject: [PATCH 10/15] settings: restoreMenu reuses the current menu's scroll ... not the one from the level up --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index a8503c6ed..2b43b1f1f 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -27,7 +27,7 @@ function pushMenu(menu) { function restoreMenu(menu) { if(!menu[""]) menu[""] = {}; - menu[""].scroll = scrolls[scrolls.length - 1] | 0; + menu[""].scroll = menuScroller.scroll; menuScroller = E.showMenu(menu).scroller; } From 9c9de9b063ce0cad758def4fa78221ed18b686db Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 12 Nov 2024 18:01:16 +0000 Subject: [PATCH 11/15] settings: fix main menu comment --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 2b43b1f1f..9fc4801eb 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -996,7 +996,7 @@ function showTouchscreenCalibration() { storage.writeJSON("setting.json",s); g.setFont("6x8:2").setFontAlign(0,0).drawString(/*LANG*/"Calibrated!", g.getWidth()/2, g.getHeight()/2); } - // now load the main menu again + // now load the menu again setTimeout(() => restoreMenu(LCDMenu()), 500); } From c63e940ddd85593decf516fac1180774ae93d51b Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 19 Nov 2024 22:13:08 +0000 Subject: [PATCH 12/15] settings: whitelist menu restores itself ... rather than pushing --- apps/setting/settings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 9fc4801eb..9b0027904 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -426,14 +426,14 @@ function whitelistMenu() { settings.whitelist.splice(settings.whitelist.indexOf(d),1); updateSettings(); } - setTimeout(() => pushMenu(whitelistMenu()), 50); + setTimeout(() => restoreMenu(whitelistMenu()), 50); }); } }); menu[/*LANG*/'Add Device']=function() { E.showAlert(/*LANG*/"Connect device\nto add to\nwhitelist",/*LANG*/"Whitelist").then(function() { NRF.removeAllListeners('connect'); - pushMenu(whitelistMenu()); + restoreMenu(whitelistMenu()); }); NRF.removeAllListeners('connect'); NRF.on('connect', function(addr) { @@ -448,7 +448,7 @@ function whitelistMenu() { settings.whitelist.push(addr); updateSettings(); NRF.removeAllListeners('connect'); - pushMenu(whitelistMenu()); + restoreMenu(whitelistMenu()); }); }; return menu; From ba1506d1baf5a3cf9796899071543766cfd592e6 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 19 Nov 2024 22:10:19 +0000 Subject: [PATCH 13/15] settings: add restoreMenu comment --- apps/setting/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 9b0027904..db3150f00 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -26,6 +26,7 @@ function pushMenu(menu) { } function restoreMenu(menu) { + // equivalent to pushMenu(null); popMenu(menu); if(!menu[""]) menu[""] = {}; menu[""].scroll = menuScroller.scroll; menuScroller = E.showMenu(menu).scroller; From 24d92f4f03cf0f5f48def4e61b1eec2438bdd663 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 19 Nov 2024 22:10:41 +0000 Subject: [PATCH 14/15] settings: charge calibration restores util menu --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index db3150f00..13aa611b5 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -702,7 +702,7 @@ function utilMenu() { storage.writeJSON("setting.json",s); E.showAlert(/*LANG*/"Calibrated!").then(() => load("setting.app.js")); } else { - E.showAlert(/*LANG*/"Please charge Bangle.js for 3 hours and try again").then(() => load("setting.app.js")); + E.showAlert(/*LANG*/"Please charge Bangle.js for 3 hours and try again").then(back); } }); }; From 308956b17b2cdd298650145535391cfc11cc0271 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 19 Nov 2024 22:05:30 +0000 Subject: [PATCH 15/15] settings: note push/pop/restoreMenu in README --- apps/setting/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/setting/README.md b/apps/setting/README.md index 81a37adfe..177a5891a 100644 --- a/apps/setting/README.md +++ b/apps/setting/README.md @@ -67,3 +67,13 @@ The exact effects depend on the app. In general the watch will not wake up by i * **Reset Settings** Reset the settings (as set in this app) to defaults. Does not reset settings for other apps. * **Factory Reset** (not available on Bangle.js 1) - wipe **everything** and return to a factory state * **Turn Off** Turn Bangle.js off + +# Development + +The settings code uses `push/pop/restoreMenu` to navigate different levels of menus. These functions are used as follows: + +- `pushMenu`: enter a new level of menu, one deeper than the current (e.g. a submenu) +- `popMenu`: return to the previous menu level, one more shallow than the current (e.g. returning from a submenu) +- `restoreMenu`: redraw the current menu (e.g. after an alert) + +These functions will keep track of outer menu's scroll positions, to avoid the user being returned to the very first entry as they navigate.