Skip to content

Commit

Permalink
Refactor config storage to use modules
Browse files Browse the repository at this point in the history
  • Loading branch information
chmelevskij committed Dec 31, 2022
1 parent b287361 commit c1d3fee
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 117 deletions.
113 changes: 68 additions & 45 deletions src/js/ConfigStorage.js
@@ -1,48 +1,71 @@
'use strict';
/**
* Gets one or more items from localStorage
* @param {string | string[]} key string or array of strings
* @returns {object}
*/
export function get(key) {
let result = {};
if (Array.isArray(key)) {
key.forEach(function (element) {
try {
result = { ...result, ...JSON.parse(localStorage.getItem(element)) };
} catch (e) {
console.error(e);
}
});
} else {
const keyValue = localStorage.getItem(key);
if (keyValue) {
try {
result = JSON.parse(keyValue);
} catch (e) {
console.error(e);
}
}
}

// idea here is to abstract around the use of chrome.storage.local as it functions differently from "localStorage" and IndexedDB
// localStorage deals with strings, not objects, so the objects have been serialized.
const ConfigStorage = {
// key can be one string, or array of strings
get: function(key) {
let result = {};
if (Array.isArray(key)) {
key.forEach(function (element) {
try {
result = {...result, ...JSON.parse(localStorage.getItem(element))};
} catch (e) {
console.error(e);
}
});
} else {
const keyValue = localStorage.getItem(key);
if (keyValue) {
try {
result = JSON.parse(keyValue);
} catch (e) {
console.error(e);
}
}
}
return result;
}

// set takes an object like {'userLanguageSelect':'DEFAULT'}
/**
* Save dictionary of key/value pairs to localStorage
* @param {object} input object which keys are strings and values are serializable objects
*/
export function set(input) {
Object.keys(input).forEach(function (element) {
const tmpObj = {};
tmpObj[element] = input[element];
try {
localStorage.setItem(element, JSON.stringify(tmpObj));
} catch (e) {
console.error(e);
}
});
}

/**
* Remove item from localStorage
* @param {string} item key to remove from storage
*/
export function remove(item) {
localStorage.removeItem(item);
}

return result;
},
// set takes an object like {'userLanguageSelect':'DEFAULT'}
set: function(input) {
Object.keys(input).forEach(function (element) {
const tmpObj = {};
tmpObj[element] = input[element];
try {
localStorage.setItem(element, JSON.stringify(tmpObj));
} catch (e) {
console.error(e);
}
});
},
remove: function(item) {
localStorage.removeItem(item);
},
clear: function() {
localStorage.clear();
},
/**
* Clear localStorage
*/
export function clear() {
localStorage.clear();
}

/**
* @deprecated this is a temporary solution to allow the use of the ConfigStorage module in old way
*/
const ConfigStorage = {
get,
set,
remove,
clear,
};
window.ConfigStorage = ConfigStorage;
4 changes: 3 additions & 1 deletion src/js/gui.js
@@ -1,3 +1,5 @@
import { get as getConfig } from './ConfigStorage';

window.TABS = {}; // filled by individual tab js file

const GUI_MODES = {
Expand Down Expand Up @@ -358,7 +360,7 @@ class GuiControl {
}
}
selectDefaultTabWhenConnected() {
const result = ConfigStorage.get(['rememberLastTab', 'lastTab']);
const result = getConfig(['rememberLastTab', 'lastTab']);
const tab = result.rememberLastTab && result.lastTab ? result.lastTab : 'tab_setup';

$(`#tabs ul.mode-connected .${tab} a`).trigger('click');
Expand Down
15 changes: 6 additions & 9 deletions src/js/localization.js
@@ -1,6 +1,7 @@
import i18next from 'i18next';
import i18nextXHRBackend from 'i18next-xhr-backend';
import GUI from './gui.js';
import { get as getConfig, set as setConfig } from './ConfigStorage.js';

const i18n = {};
/*
Expand Down Expand Up @@ -80,9 +81,7 @@ i18n.parseInputFile = function(data) {
};

i18n.changeLanguage = function(languageSelected) {
if (typeof ConfigStorage !== 'undefined') {
ConfigStorage.set({'userLanguageSelect': languageSelected});
}
setConfig({'userLanguageSelect': languageSelected});
i18next.changeLanguage(getValidLocale(languageSelected));
i18n.selectedLanguage = languageSelected;
GUI.log(i18n.getMessage('language_changed'));
Expand Down Expand Up @@ -192,13 +191,11 @@ i18n.localizePage = function(forceReTranslate) {
*/
function getStoredUserLocale(cb) {
let userLanguage = 'DEFAULT';
if (typeof ConfigStorage !== 'undefined') {
const result = ConfigStorage.get('userLanguageSelect');
if (result.userLanguageSelect) {
userLanguage = result.userLanguageSelect;
}
i18n.selectedLanguage = userLanguage;
const result = getConfig('userLanguageSelect');
if (result.userLanguageSelect) {
userLanguage = result.userLanguageSelect;
}
i18n.selectedLanguage = userLanguage;
userLanguage = getValidLocale(userLanguage);
cb(userLanguage);
}
Expand Down
17 changes: 9 additions & 8 deletions src/js/main.js
@@ -1,6 +1,7 @@
import '../components/init.js';
import { i18n } from './localization.js';
import GUI from './gui.js';
import { get as getConfig, set as setConfig } from './ConfigStorage.js';

$(document).ready(function () {

Expand Down Expand Up @@ -191,7 +192,7 @@ function startProcess() {
const tabNameWithoutPrefix = tabName.substring(4);
if (tabNameWithoutPrefix !== "cli") {
// Don't store 'cli' otherwise you can never connect to another tab.
ConfigStorage.set(
setConfig(
{lastTab: tabName},
);
}
Expand Down Expand Up @@ -487,27 +488,27 @@ function startProcess() {
$("#log").removeClass('active');
$("#tab-content-container").removeClass('logopen');
$("#scrollicon").removeClass('active');
ConfigStorage.set({'logopen': false});
setConfig({'logopen': false});

state = false;
} else {
$("#log").addClass('active');
$("#tab-content-container").addClass('logopen');
$("#scrollicon").addClass('active');
ConfigStorage.set({'logopen': true});
setConfig({'logopen': true});

state = true;
}
$(this).text(state ? i18n.getMessage('logActionHide') : i18n.getMessage('logActionShow'));
$(this).data('state', state);
});

let result = ConfigStorage.get('logopen');
let result = getConfig('logopen');
if (result.logopen) {
$("#showlog").trigger('click');
}

result = ConfigStorage.get('permanentExpertMode');
result = getConfig('permanentExpertMode');
const expertModeCheckbox = 'input[name="expertModeCheckbox"]';
if (result.permanentExpertMode) {
$(expertModeCheckbox).prop('checked', true);
Expand All @@ -527,10 +528,10 @@ function startProcess() {

$(expertModeCheckbox).trigger("change");

result = ConfigStorage.get('cliAutoComplete');
result = getConfig('cliAutoComplete');
CliAutoComplete.setEnabled(typeof result.cliAutoComplete === "undefined" || result.cliAutoComplete); // On by default

result = ConfigStorage.get('darkTheme');
result = getConfig('darkTheme');
if (result.darkTheme === undefined || typeof result.darkTheme !== "number") {
// sets dark theme to auto if not manually changed
setDarkTheme(2);
Expand Down Expand Up @@ -568,7 +569,7 @@ function checkForConfiguratorUpdates() {
}

function notifyOutdatedVersion(releaseData) {
const result = ConfigStorage.get('checkForConfiguratorUnstableVersions');
const result = getConfig('checkForConfiguratorUnstableVersions');
let showUnstableReleases = false;
if (result.checkForConfiguratorUnstableVersions) {
showUnstableReleases = true;
Expand Down
5 changes: 3 additions & 2 deletions src/js/tabs/auxiliary.js
@@ -1,5 +1,6 @@
import { i18n } from '../localization';
import GUI from '../gui';
import { get as getConfig, set as setConfig } from '../ConfigStorage';

const auxiliary = {};

Expand Down Expand Up @@ -529,11 +530,11 @@ auxiliary.initialize = function (callback) {
}

let hideUnusedModes = false;
const result = ConfigStorage.get('hideUnusedModes');
const result = getConfig('hideUnusedModes');
$("input#switch-toggle-unused")
.change(function() {
hideUnusedModes = $(this).prop("checked");
ConfigStorage.set({ hideUnusedModes: hideUnusedModes });
setConfig({ hideUnusedModes: hideUnusedModes });
update_ui();
})
.prop("checked", !!result.hideUnusedModes)
Expand Down
29 changes: 15 additions & 14 deletions src/js/tabs/firmware_flasher.js
@@ -1,5 +1,6 @@
import { i18n } from '../localization';
import GUI from '../gui';
import { get as getConfig, set as setConfig } from '../ConfigStorage';

const firmware_flasher = {
targets: null,
Expand Down Expand Up @@ -218,11 +219,11 @@ firmware_flasher.initialize = function (callback) {
buildBuildTypeOptionsList();
buildType_e.val(0).trigger('change');

ConfigStorage.set({'selected_expert_mode': expertModeChecked});
setConfig({'selected_expert_mode': expertModeChecked});
}

const expertMode_e = $('.tab-firmware_flasher input.expert_mode');
const expertMode = ConfigStorage.get('selected_expert_mode');
const expertMode = getConfig('selected_expert_mode');
expertMode_e.prop('checked', expertMode.selected_expert_mode ?? false);
$('input.show_development_releases').change(showOrHideBuildTypes).change();
expertMode_e.change(showOrHideExpertMode).change();
Expand All @@ -248,7 +249,7 @@ firmware_flasher.initialize = function (callback) {
}
}

ConfigStorage.set({'selected_build_type': build_type});
setConfig({'selected_build_type': build_type});
});

function selectFirmware(release) {
Expand Down Expand Up @@ -590,29 +591,29 @@ firmware_flasher.initialize = function (callback) {
detectBoardElement.toggleClass('disabled', isButtonDisabled);
}

let result = ConfigStorage.get('erase_chip');
let result = getConfig('erase_chip');
if (result.erase_chip) {
$('input.erase_chip').prop('checked', true);
} else {
$('input.erase_chip').prop('checked', false);
}

$('input.erase_chip').change(function () {
ConfigStorage.set({'erase_chip': $(this).is(':checked')});
setConfig({'erase_chip': $(this).is(':checked')});
}).change();

result = ConfigStorage.get('show_development_releases');
result = getConfig('show_development_releases');
$('input.show_development_releases')
.prop('checked', result.show_development_releases)
.change(function () {
ConfigStorage.set({'show_development_releases': $(this).is(':checked')});
setConfig({'show_development_releases': $(this).is(':checked')});
}).change();

result = ConfigStorage.get('selected_build_type');
result = getConfig('selected_build_type');
// ensure default build type is selected
buildType_e.val(result.selected_build_type || 0).trigger('change');

result = ConfigStorage.get('no_reboot_sequence');
result = getConfig('no_reboot_sequence');
if (result.no_reboot_sequence) {
$('input.updating').prop('checked', true);
$('.flash_on_connect_wrapper').show();
Expand All @@ -631,12 +632,12 @@ firmware_flasher.initialize = function (callback) {
$('.flash_on_connect_wrapper').hide();
}

ConfigStorage.set({'no_reboot_sequence': status});
setConfig({'no_reboot_sequence': status});
});

$('input.updating').change();

result = ConfigStorage.get('flash_manual_baud');
result = getConfig('flash_manual_baud');
if (result.flash_manual_baud) {
$('input.flash_manual_baud').prop('checked', true);
} else {
Expand All @@ -653,18 +654,18 @@ firmware_flasher.initialize = function (callback) {
// bind UI hook so the status is saved on change
$('input.flash_manual_baud').change(function() {
const status = $(this).is(':checked');
ConfigStorage.set({'flash_manual_baud': status});
setConfig({'flash_manual_baud': status});
});

$('input.flash_manual_baud').change();

result = ConfigStorage.get('flash_manual_baud_rate');
result = getConfig('flash_manual_baud_rate');
$('#flash_manual_baud_rate').val(result.flash_manual_baud_rate);

// bind UI hook so the status is saved on change
$('#flash_manual_baud_rate').change(function() {
const baud = parseInt($('#flash_manual_baud_rate').val());
ConfigStorage.set({'flash_manual_baud_rate': baud});
setConfig({'flash_manual_baud_rate': baud});
});

$('input.flash_manual_baud_rate').change();
Expand Down
1 change: 1 addition & 0 deletions src/js/tabs/help.js
@@ -1,4 +1,5 @@
import GUI from '../gui';
import { i18n } from '../localization';

const help = {};
help.initialize = function (callback) {
Expand Down
1 change: 1 addition & 0 deletions src/js/tabs/landing.js
@@ -1,4 +1,5 @@
import GUI from '../gui';
import { i18n } from '../localization';

const landing = {};
landing.initialize = function (callback) {
Expand Down

0 comments on commit c1d3fee

Please sign in to comment.