From 39621bfae0c659e354840b31ff092e51ab6dca26 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 01:18:21 +0200 Subject: [PATCH 1/4] Settings: Add support for app/widget settings Apps and widgets can add a `.settings.js` file which can be opened from the "App/widget settings" submenu. This file should define a single function to configure the app/widget. The function is passed a `back` argument, which can be used to return to the settings menu by calling `back()`. Example `.settings.js`: ``` function settings(back) { const mySettingsMenu = { '': { 'title': 'My Widget' }, '< Back': back, // go back to settings menu 'Sound': { value: false, format: s => s ? 'on' : 'off', onchange: s => {if(s) Bangle.beep()} // TODO: save new value }, }; E.showMenu(mySettingsMenu) } ``` --- apps.json | 2 +- apps/setting/ChangeLog | 1 + apps/setting/settings.js | 47 ++++++++++++++++++++++++++++++++++++++++ js/appinfo.js | 2 ++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 2bd8ef7bf..5b269e44f 100644 --- a/apps.json +++ b/apps.json @@ -117,7 +117,7 @@ { "id": "setting", "name": "Settings", "icon": "settings.png", - "version":"0.07", + "version":"0.08", "description": "A menu for setting up Bangle.js", "tags": "tool,system", "storage": [ diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index d29a312d0..0cfa04bf0 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -4,3 +4,4 @@ 0.05: Fix Settings json 0.06: Remove distance setting as there's a separate app for Locale now 0.07: Added vibrate as beep workaround +0.08: Add support for app/widget settings diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 9d5fa2775..6f399428d 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -114,6 +114,7 @@ function showMainMenu() { } }, 'Set Time': showSetTimeMenu, + 'App/widget settings': showAppSettingsMenu, 'Reset Settings': showResetMenu, 'Turn Off': Bangle.off, '< Back': ()=> {load();} @@ -295,4 +296,50 @@ function showSetTimeMenu() { return E.showMenu(timemenu); } +function showAppSettingsMenu(){ + let appmenu = { + '': { + 'title': 'App Settings', + }, + '< Back': showMainMenu, + } + const apps = storage.list(/\.info$/). + map(app => storage.readJSON(app, 1)). + filter(app => app && app.settings). + sort((a, b) => a.sortorder - b.sortorder) + if (apps.length === 0) { + appmenu['No app has settings'] = () => {}; + } + apps.forEach(function (app) { + appmenu[app.name] = () => {showAppSettings(app)}; + }) + E.showMenu(appmenu) +} +function showAppSettings(app) { + const showError = msg => { + E.showMessage(`${app.name}:\n${msg}!\n\nBTN1 to go back`); + setWatch(showAppSettingsMenu, BTN1, { repeat: false }); + } + let appSettings = storage.read(app.settings); + if (!appSettings) { + return showError('Missing settings'); + } + try { + appSettings = eval(appSettings); + } catch (e) { + console.log(`${app.name} settings error:`, e) + return showError('Error in settings'); + } + if (typeof appSettings !== "function") { + return showError('Invalid settings'); + } + try { + // pass showAppSettingsMenu as "back" argument + appSettings(showAppSettingsMenu); + } catch (e) { + console.log(`${app.name} settings error:`, e) + return showError('Error in settings'); + } +} + showMainMenu(); diff --git a/js/appinfo.js b/js/appinfo.js index 613d15379..f4ab498b1 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -60,6 +60,8 @@ var AppInfo = { if (app.type && app.type!="app") json.type = app.type; if (fileContents.find(f=>f.name==app.id+".app.js")) json.src = app.id+".app.js"; + if (fileContents.find(f=>f.name==app.id+".settings.js")) + json.settings = app.id+".settings.js"; if (fileContents.find(f=>f.name==app.id+".img")) json.icon = app.id+".img"; if (app.sortorder) json.sortorder = app.sortorder; From c135c70f7eb08dd127e909fe943f2a8cd7c47c49 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 19:56:30 +0200 Subject: [PATCH 2/4] Settings: load app settings in their own scope --- 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 6f399428d..f13ad961f 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -325,7 +325,7 @@ function showAppSettings(app) { return showError('Missing settings'); } try { - appSettings = eval(appSettings); + appSettings = eval('('+appSettings+')'); } catch (e) { console.log(`${app.name} settings error:`, e) return showError('Error in settings'); From fc7e61e2caed761458bb3d740cefdd125d800be6 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 19:59:15 +0200 Subject: [PATCH 3/4] Settings: minor reformat --- apps/setting/settings.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index f13ad961f..38ce9f886 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -298,15 +298,13 @@ function showSetTimeMenu() { function showAppSettingsMenu(){ let appmenu = { - '': { - 'title': 'App Settings', - }, + '': {'title': 'App Settings'}, '< Back': showMainMenu, } - const apps = storage.list(/\.info$/). - map(app => storage.readJSON(app, 1)). - filter(app => app && app.settings). - sort((a, b) => a.sortorder - b.sortorder) + const apps = storage.list(/\.info$/) + .map(app => storage.readJSON(app, 1)) + .filter(app => app && app.settings) + .sort((a, b) => a.sortorder - b.sortorder) if (apps.length === 0) { appmenu['No app has settings'] = () => {}; } From 048a042ffa0f6a0254dfbed79ca5281704073496 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 21:32:05 +0200 Subject: [PATCH 4/4] Revert "Settings: load app settings in their own scope" > Actually eval('('+appSettings+')') is significantly worse I'm afraid. > > Basically, if you do Storage.read you get a pointer to external memory > Any functions have their code kept in that memory so it saves loads of > RAM. The second you append to the string it has to copy everything to > RAM - so now every function ends up in RAM, not Flash :( This reverts commit c135c70f --- 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 38ce9f886..dbb03555c 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -323,7 +323,7 @@ function showAppSettings(app) { return showError('Missing settings'); } try { - appSettings = eval('('+appSettings+')'); + appSettings = eval(appSettings); } catch (e) { console.log(`${app.name} settings error:`, e) return showError('Error in settings');