From 47738927ded92bc6dc494f256984ef023e365f8e Mon Sep 17 00:00:00 2001 From: Robert Blackhart Date: Fri, 25 Oct 2024 17:16:17 -0400 Subject: [PATCH 1/2] add setting save/load to local storage --- src/ViperIDE.html | 2 +- src/app.js | 33 +++++++------ src/settings.js | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 17 deletions(-) create mode 100644 src/settings.js diff --git a/src/ViperIDE.html b/src/ViperIDE.html index bd0cbe6..9369232 100644 --- a/src/ViperIDE.html +++ b/src/ViperIDE.html @@ -134,7 +134,7 @@ or : ${settingElement}`) + } + + // set our local cache + settings[setting] = newValue + + // inform any subscribers + _notify(setting, newValue) + + // persist to local storage + _persistSettings(settings) +} + + +/** + * + * @param {string} setting The name of the setting to set a callback for + * @param {function(string):void} callback A callback function that will receive the new value of the setting + */ +export function onSettingChange(setting, callback) { + if (!callbacks.has(setting)) { + callbacks.set(setting, []) + } + callbacks.get(setting).push(callback) +} + + +settingsElement.addEventListener("change", (event) => { + settings = _persistSettings() + _notify(event.target.id, settings[event.target.id]) +}) + + +function _loadSettings() { + // get settings from either localstorage or read from the DOM (and populate local storage) + let loadedSettings = JSON.parse(localStorage.getItem("settings")) + if (!loadedSettings) { + _persistSettings() + loadedSettings = JSON.parse(localStorage.getItem("settings")) + } + + function _setLoadedValue(setting, loadedValue, setter) { + // if we loaded nothing, then do nothing + if (loadedValue == undefined) { + return + } + + // set the loaded value to the DOM + setter(loadedValue) + + // notify any code that might need to know about what we loaded + _notify(setting, loadedValue) + } + + // loop over all DOM settings elements and load them with the value from local storage + settingsElement.querySelectorAll("input[type='checkbox']").forEach(element => { + _setLoadedValue(element.id, loadedSettings[element.id], (value) => element.checked = value) + }) + settingsElement.querySelectorAll("select").forEach(element => { + _setLoadedValue(element.id, loadedSettings[element.id], (value) => element.value = value) + }) + + return loadedSettings +} + + +function _persistSettings(newSettings = undefined) { + if (!newSettings) { + // nothing passed into us, so lets read from the DOM and persist that + newSettings = new Object() + settingsElement.querySelectorAll("input[type='checkbox']").forEach(element => { + newSettings[element.id] = element.checked + }) + settingsElement.querySelectorAll("select").forEach(element => { + newSettings[element.id] = element.value + }) + } + + localStorage.setItem("settings", JSON.stringify(newSettings)) + return newSettings +} + + +function _notify(setting, newValue) { + // If there are any callbacks for this setting update, then let's call them + if (callbacks.has(setting)) { + for (let callback of callbacks.get(setting)) { + callback(newValue) + } + } +} From 0a94fdc05a427f0c0d7cb3315e0b31956d5084fd Mon Sep 17 00:00:00 2001 From: Robert Blackhart Date: Fri, 25 Oct 2024 17:34:08 -0400 Subject: [PATCH 2/2] make sure to load brand new settings and merge with existing saved ones --- src/settings.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/settings.js b/src/settings.js index 89b5dc7..b0ae166 100644 --- a/src/settings.js +++ b/src/settings.js @@ -69,25 +69,27 @@ function _loadSettings() { loadedSettings = JSON.parse(localStorage.getItem("settings")) } - function _setLoadedValue(setting, loadedValue, setter) { - // if we loaded nothing, then do nothing - if (loadedValue == undefined) { - return + function _setLoadedValue(setting, loadedValue, domValue, setter) { + // if we loaded nothing, then don't try to set the DOM (perhaps a brand new setting and + // therefore should use the default) + if (loadedValue != undefined) { + // set the loaded value to the DOM + setter(loadedValue) + } else { + loadedSettings[setting] = domValue + loadedValue = domValue } - // set the loaded value to the DOM - setter(loadedValue) - // notify any code that might need to know about what we loaded _notify(setting, loadedValue) } // loop over all DOM settings elements and load them with the value from local storage settingsElement.querySelectorAll("input[type='checkbox']").forEach(element => { - _setLoadedValue(element.id, loadedSettings[element.id], (value) => element.checked = value) + _setLoadedValue(element.id, loadedSettings[element.id], element.checked, (value) => element.checked = value) }) settingsElement.querySelectorAll("select").forEach(element => { - _setLoadedValue(element.id, loadedSettings[element.id], (value) => element.value = value) + _setLoadedValue(element.id, loadedSettings[element.id], element.value, (value) => element.value = value) }) return loadedSettings