From 51e1f9e7da7cfd402e561347cca9d2144ca13e47 Mon Sep 17 00:00:00 2001 From: stweedo Date: Fri, 16 Jun 2023 19:04:20 -0500 Subject: [PATCH] Add menu for multiple configs, update README --- apps/boxclk/README.md | 19 +++++++--- apps/boxclk/metadata.json | 1 + apps/boxclk/settings.js | 75 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 apps/boxclk/settings.js diff --git a/apps/boxclk/README.md b/apps/boxclk/README.md index 613c74fe0..7a0f3bb81 100644 --- a/apps/boxclk/README.md +++ b/apps/boxclk/README.md @@ -10,13 +10,15 @@ This intuitive feature allows you to reposition any element (box) on the clock f __JSON Configuration:__ -Each box can be customized extensively via a simple JSON configuration. You can also add a custom text string to your configuration with the "string": "Your custom text here", attribute. Here's what an example configuration might look like: +Each box can be customized extensively via a simple JSON configuration. You can also add a custom text string to your configuration with the "string" attribute. Here's what an example configuration might look like: + +## Config File Structure ``` { - "customBox": { - "string": "Your custom text here", - "font": "CustomFont", + "customBox": { // + "string": "Your text here", + "font": "CustomFont", // Custom fonts must be in main program and removed in setUI "fontSize": 1, "outline": 2, "color": "#FF9900", @@ -28,11 +30,12 @@ Each box can be customized extensively via a simple JSON configuration. You can "yOffset": 3, "boxPos": { "x": 0.5, "y": 0.5 } }, - "bg": { + "bg": { // Can also be removed for no backround "img": "YourImageName.img" } } ``` + * **string:** The text string to be displayed inside the box. * **font:** The font name given to g.setFont() @@ -55,6 +58,12 @@ Each box can be customized extensively via a simple JSON configuration. You can * **bg:** This specifies a custom background image, with the img property defining the name of the image file on the Bangle.js storage. +## Multiple Configurations + +The app includes a settings menu that allows you to switch between different configurations. The selected configuration is stored in the default JSON file alongside the other configuration data using the selectedConfig property. + +If the selectedConfig property is not present or is set to 0, the app will use the default configuration. To create additional configurations, create separate JSON files with the naming convention boxclk-N.json, where N is the configuration number. The settings menu will list all available configurations. + ## Compatibility This app was built and tested with Bangle.js 2. diff --git a/apps/boxclk/metadata.json b/apps/boxclk/metadata.json index 8ec9f1bba..351686fe7 100644 --- a/apps/boxclk/metadata.json +++ b/apps/boxclk/metadata.json @@ -15,6 +15,7 @@ "allow_emulator": true, "storage": [ {"name":"boxclk.app.js","url":"app.js"}, + {"name": "boxclk.settings.js","url":"settings.js"}, {"name":"boxclk.img","url":"icon.js","evaluate":true}, {"name":"boxclk.beachhouse.img","url":"beachhouse.js","evaluate":true} ], diff --git a/apps/boxclk/settings.js b/apps/boxclk/settings.js new file mode 100644 index 000000000..7d6262a65 --- /dev/null +++ b/apps/boxclk/settings.js @@ -0,0 +1,75 @@ +let storage = require("Storage"); +let fileRegex = /^boxclk-(\d+)\.json$/; +let selectedConfig; + +function getNextConfigNumber() { + let maxNumber = 0; + storage.list().forEach(file => { + let match = file.match(fileRegex); + if (match) { + let number = parseInt(match[1]); + if (number > maxNumber) { + maxNumber = number; + } + } + }); + return maxNumber + 1; +} + +(function () { + let configs = {}; + let hasDefaultConfig = false; + + function handleSelection(config) { + return function () { + selectedConfig = config === "Default" ? 0 : config; + menu["Cfg:"].value = selectedConfig === 0 ? "Default" : selectedConfig; + E.showMenu(menu); + + // Retrieve existing data and update selectedConfig + let defaultConfig = storage.readJSON("boxclk.json", 1) || {}; + defaultConfig.selectedConfig = selectedConfig; + storage.writeJSON("boxclk.json", defaultConfig); + }; + } + + storage.list().forEach(file => { + let match = file.match(fileRegex); + if (match) { + let configNumber = match[1]; + configs[configNumber] = handleSelection(configNumber); + } else if (file === "boxclk.json") { + hasDefaultConfig = true; + let defaultConfig = storage.readJSON(file, 1); + if (defaultConfig && defaultConfig.selectedConfig) { + selectedConfig = defaultConfig.selectedConfig === 0 ? 0 : defaultConfig.selectedConfig; + } + } + }); + + if (!selectedConfig) { + if (hasDefaultConfig) { + selectedConfig = "Default"; + } else { + let nextConfigNumber = getNextConfigNumber(); + selectedConfig = nextConfigNumber.toString(); + configs[selectedConfig] = handleSelection(selectedConfig); + } + } + + let menu = { + '': { 'title': '-- Box Clock --' }, + '< Back': () => Bangle.showLauncher(), + 'Cfg:': { value: selectedConfig === 0 ? "Default" : selectedConfig, format: () => selectedConfig === 0 ? "Default" : selectedConfig }, + }; + + if (hasDefaultConfig) { + menu['Default'] = handleSelection('Default'); + } + + Object.keys(configs).forEach(config => { + menu[config] = handleSelection(config); + }); + + E.showMenu(menu); +})();