clean up settings constructor

This commit is contained in:
Matt Walsh
2025-04-08 10:40:36 -05:00
parent 8678d9f053
commit 0a388cdb83
4 changed files with 94 additions and 38 deletions

3
.vscode/launch.json vendored
View File

@@ -15,6 +15,9 @@
"**/*.min.js", "**/*.min.js",
"**/vendor/**" "**/vendor/**"
], ],
"runtimeArgs": [
"--autoplay-policy=no-user-gesture-required"
]
}, },
{ {
"name": "Data:stations", "name": "Data:stations",

View File

@@ -5,7 +5,12 @@ let playlist;
let currentTrack = 0; let currentTrack = 0;
let player; let player;
const mediaPlaying = new Setting('mediaPlaying', 'Media Playing', 'boolean', false, null, true); const mediaPlaying = new Setting('mediaPlaying', {
name: 'Media Playing',
type: 'boolean',
defaultValue: false,
sticky: true,
});
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
// add the event handler to the page // add the event handler to the page

View File

@@ -8,27 +8,54 @@ document.addEventListener('DOMContentLoaded', () => {
const settings = { speed: { value: 1.0 } }; const settings = { speed: { value: 1.0 } };
const init = () => { const init = () => {
// create settings // create settings see setting.mjs for defaults
settings.wide = new Setting('wide', 'Widescreen', 'checkbox', false, wideScreenChange, true); settings.wide = new Setting('wide', {
settings.kiosk = new Setting('kiosk', 'Kiosk', 'checkbox', false, kioskChange, false); name: 'Widescreen',
settings.speed = new Setting('speed', 'Speed', 'select', 1.0, null, true, [ defaultValue: false,
[0.5, 'Very Fast'], changeAction: wideScreenChange,
[0.75, 'Fast'], sticky: true,
[1.0, 'Normal'], });
[1.25, 'Slow'], settings.kiosk = new Setting('kiosk', {
[1.5, 'Very Slow'], name: 'Kiosk',
]); defaultValue: false,
settings.units = new Setting('units', 'Units', 'select', 'us', unitChange, true, [ changeAction: kioskChange,
['us', 'US'], sticky: false,
['si', 'Metric'], });
]); settings.speed = new Setting('speed', {
settings.refreshTime = new Setting('refreshTime', 'Refresh Time', 'select', 600_000, null, false, [ name: 'Speed',
[30_000, 'TESTING'], type: 'select',
[300_000, '5 minutes'], defaultValue: 1.0,
[600_000, '10 minutes'], values: [
[900_000, '15 minutes'], [0.5, 'Very Fast'],
[1_800_000, '30 minutes'], [0.75, 'Fast'],
]); [1.0, 'Normal'],
[1.25, 'Slow'],
[1.5, 'Very Slow'],
],
});
settings.units = new Setting('units', {
name: 'Units',
type: 'select',
defaultValue: 'us',
changeAction: unitChange,
values: [
['us', 'US'],
['si', 'Metric'],
],
});
settings.refreshTime = new Setting('refreshTime', {
type: 'select',
defaultValue: 600_000,
sticky: false,
values: [
[30_000, 'TESTING'],
[300_000, '5 minutes'],
[600_000, '10 minutes'],
[900_000, '15 minutes'],
[1_800_000, '30 minutes'],
],
visible: false,
});
// generate html objects // generate html objects
const settingHtml = Object.values(settings).map((d) => d.generate()); const settingHtml = Object.values(settings).map((d) => d.generate());

View File

@@ -2,41 +2,58 @@ import { parseQueryString } from '../share.mjs';
const SETTINGS_KEY = 'Settings'; const SETTINGS_KEY = 'Settings';
const DEFAULTS = {
shortName: undefined,
name: undefined,
type: 'checkbox',
defaultValue: undefined,
changeAction: () => { },
sticky: true,
values: [],
visible: true,
};
class Setting { class Setting {
constructor(shortName, name, type, defaultValue, changeAction, sticky, values) { constructor(shortName, _options) {
// store values if (shortName === undefined) {
throw new Error('No name provided for setting');
}
// merge options with defaults
const options = { ...DEFAULTS, ...(_options ?? {}) };
// store values and combine with defaults
this.shortName = shortName; this.shortName = shortName;
this.name = name; this.name = options.name ?? shortName;
this.defaultValue = defaultValue; this.defaultValue = options.defaultValue;
this.myValue = defaultValue; this.myValue = this.defaultValue;
this.type = type ?? 'checkbox'; this.type = options?.type;
this.sticky = sticky; this.sticky = options.sticky;
this.values = values; this.values = options.values;
// a default blank change function is provided this.visible = options.visible;
this.changeAction = changeAction ?? (() => { }); this.changeAction = options.changeAction;
// get value from url // get value from url
const urlValue = parseQueryString()?.[`settings-${shortName}-${type}`]; const urlValue = parseQueryString()?.[`settings-${shortName}-${this.type}`];
let urlState; let urlState;
if (type === 'checkbox' && urlValue !== undefined) { if (this.type === 'checkbox' && urlValue !== undefined) {
urlState = urlValue === 'true'; urlState = urlValue === 'true';
} }
if (type === 'select' && urlValue !== undefined) { if (this.type === 'select' && urlValue !== undefined) {
urlState = parseFloat(urlValue); urlState = parseFloat(urlValue);
} }
if (type === 'select' && urlValue !== undefined && Number.isNaN(urlState)) { if (this.type === 'select' && urlValue !== undefined && Number.isNaN(urlState)) {
// couldn't parse as a float, store as a string // couldn't parse as a float, store as a string
urlState = urlValue; urlState = urlValue;
} }
// get existing value if present // get existing value if present
const storedValue = urlState ?? this.getFromLocalStorage(); const storedValue = urlState ?? this.getFromLocalStorage();
if (sticky && storedValue !== null) { if ((this.sticky || urlValue !== undefined) && storedValue !== null) {
this.myValue = storedValue; this.myValue = storedValue;
} }
// call the change function on startup // call the change function on startup
switch (type) { switch (this.type) {
case 'select': case 'select':
this.selectChange({ target: { value: this.myValue } }); this.selectChange({ target: { value: this.myValue } });
break; break;
@@ -142,6 +159,7 @@ class Setting {
if (storedValue !== undefined) { if (storedValue !== undefined) {
switch (this.type) { switch (this.type) {
case 'boolean': case 'boolean':
case 'checkbox':
return storedValue; return storedValue;
case 'select': case 'select':
return storedValue; return storedValue;
@@ -187,6 +205,9 @@ class Setting {
} }
generate() { generate() {
// don't generate a control for not visible items
if (!this.visible) return '';
// call the appropriate control generator
switch (this.type) { switch (this.type) {
case 'select': case 'select':
return this.generateSelect(); return this.generateSelect();