mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-14 07:39:29 -07:00
201 lines
5.0 KiB
JavaScript
201 lines
5.0 KiB
JavaScript
import { parseQueryString } from '../share.mjs';
|
|
|
|
const SETTINGS_KEY = 'Settings';
|
|
|
|
class Setting {
|
|
constructor(shortName, name, type, defaultValue, changeAction, sticky, values) {
|
|
// store values
|
|
this.shortName = shortName;
|
|
this.name = name;
|
|
this.defaultValue = defaultValue;
|
|
this.myValue = defaultValue;
|
|
this.type = type ?? 'checkbox';
|
|
this.sticky = sticky;
|
|
this.values = values;
|
|
// a default blank change function is provided
|
|
this.changeAction = changeAction ?? (() => { });
|
|
|
|
// get value from url
|
|
const urlValue = parseQueryString()?.[`settings-${shortName}-${type}`];
|
|
let urlState;
|
|
if (type === 'checkbox' && urlValue !== undefined) {
|
|
urlState = urlValue === 'true';
|
|
}
|
|
if (type === 'select' && urlValue !== undefined) {
|
|
urlState = parseFloat(urlValue);
|
|
}
|
|
if (type === 'select' && urlValue !== undefined && Number.isNaN(urlState)) {
|
|
// couldn't parse as a float, store as a string
|
|
urlState = urlValue;
|
|
}
|
|
|
|
// get existing value if present
|
|
const storedValue = urlState ?? this.getFromLocalStorage();
|
|
if (sticky && storedValue !== null) {
|
|
this.myValue = storedValue;
|
|
}
|
|
|
|
// call the change function on startup
|
|
switch (type) {
|
|
case 'select':
|
|
this.selectChange({ target: { value: this.myValue } });
|
|
break;
|
|
case 'checkbox':
|
|
default:
|
|
this.checkboxChange({ target: { checked: this.myValue } });
|
|
}
|
|
}
|
|
|
|
generateSelect() {
|
|
// create a radio button set in the selected displays area
|
|
const label = document.createElement('label');
|
|
label.for = `settings-${this.shortName}-select`;
|
|
label.id = `settings-${this.shortName}-label`;
|
|
|
|
const span = document.createElement('span');
|
|
span.innerHTML = `${this.name} `;
|
|
label.append(span);
|
|
|
|
const select = document.createElement('select');
|
|
select.id = `settings-${this.shortName}-select`;
|
|
select.name = `settings-${this.shortName}-select`;
|
|
select.addEventListener('change', (e) => this.selectChange(e));
|
|
|
|
this.values.forEach(([value, text]) => {
|
|
const option = document.createElement('option');
|
|
if (typeof value === 'number') {
|
|
option.value = value.toFixed(2);
|
|
} else {
|
|
option.value = value;
|
|
}
|
|
|
|
option.innerHTML = text;
|
|
select.append(option);
|
|
});
|
|
label.append(select);
|
|
|
|
this.element = label;
|
|
|
|
// set the initial value
|
|
this.selectHighlight(this.myValue);
|
|
|
|
return label;
|
|
}
|
|
|
|
generateCheckbox() {
|
|
// create a checkbox in the selected displays area
|
|
const label = document.createElement('label');
|
|
label.for = `settings-${this.shortName}-checkbox`;
|
|
label.id = `settings-${this.shortName}-label`;
|
|
const checkbox = document.createElement('input');
|
|
checkbox.type = 'checkbox';
|
|
checkbox.value = true;
|
|
checkbox.id = `settings-${this.shortName}-checkbox`;
|
|
checkbox.name = `settings-${this.shortName}-checkbox`;
|
|
checkbox.checked = this.myValue;
|
|
checkbox.addEventListener('change', (e) => this.checkboxChange(e));
|
|
const span = document.createElement('span');
|
|
span.innerHTML = this.name;
|
|
|
|
label.append(checkbox, span);
|
|
|
|
this.element = label;
|
|
|
|
return label;
|
|
}
|
|
|
|
checkboxChange(e) {
|
|
// update the state
|
|
this.myValue = e.target.checked;
|
|
this.storeToLocalStorage(this.myValue);
|
|
|
|
// call change action
|
|
this.changeAction(this.myValue);
|
|
}
|
|
|
|
selectChange(e) {
|
|
// update the value
|
|
this.myValue = parseFloat(e.target.value);
|
|
if (Number.isNaN(this.myValue)) {
|
|
// was a string, store as such
|
|
this.myValue = e.target.value;
|
|
}
|
|
this.storeToLocalStorage(this.myValue);
|
|
|
|
// call the change action
|
|
this.changeAction(this.myValue);
|
|
}
|
|
|
|
storeToLocalStorage(value) {
|
|
if (!this.sticky) return;
|
|
const allSettingsString = localStorage?.getItem(SETTINGS_KEY) ?? '{}';
|
|
const allSettings = JSON.parse(allSettingsString);
|
|
allSettings[this.shortName] = value;
|
|
localStorage?.setItem(SETTINGS_KEY, JSON.stringify(allSettings));
|
|
}
|
|
|
|
getFromLocalStorage() {
|
|
const allSettings = localStorage?.getItem(SETTINGS_KEY);
|
|
try {
|
|
if (allSettings) {
|
|
const storedValue = JSON.parse(allSettings)?.[this.shortName];
|
|
if (storedValue !== undefined) {
|
|
switch (this.type) {
|
|
case 'boolean':
|
|
return storedValue;
|
|
case 'select':
|
|
return storedValue;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
get value() {
|
|
return this.myValue;
|
|
}
|
|
|
|
set value(newValue) {
|
|
// update the state
|
|
this.myValue = newValue;
|
|
switch (this.type) {
|
|
case 'select':
|
|
this.selectHighlight(newValue);
|
|
break;
|
|
case 'boolean':
|
|
break;
|
|
case 'checkbox':
|
|
default:
|
|
this.element.checked = newValue;
|
|
}
|
|
this.storeToLocalStorage(this.myValue);
|
|
|
|
// call change action
|
|
this.changeAction(this.myValue);
|
|
}
|
|
|
|
selectHighlight(newValue) {
|
|
// set the dropdown to the provided value
|
|
this.element.querySelectorAll('option').forEach((elem) => {
|
|
elem.selected = (newValue?.toFixed?.(2) === elem.value) || (newValue === elem.value);
|
|
});
|
|
}
|
|
|
|
generate() {
|
|
switch (this.type) {
|
|
case 'select':
|
|
return this.generateSelect();
|
|
case 'checkbox':
|
|
default:
|
|
return this.generateCheckbox();
|
|
}
|
|
}
|
|
}
|
|
|
|
export default Setting;
|