1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-11-09 20:00:12 +00:00

settings: dependencies of dependencies

`settings-set-${section}-${name}` is now broadcast when a setting's
value is actually changed, while `settings-${section}-${name}` is
broadcast then or if the setting is hidden, i.e. by its parent (i.e.
some "enabled" bool). This allows chains of dependencies to be resolved
visually. When a setting is hidden, the value sent is "false", and when
a setting is shown again, the actual value of it is sent.
This commit is contained in:
Harvey Tindall 2024-08-23 18:50:50 +01:00
parent 7c808b56f7
commit 32161139b2
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
2 changed files with 60 additions and 10 deletions

1
.gitignore vendored
View File

@ -26,3 +26,4 @@ scripts/langmover/lang2
scripts/langmover/out scripts/langmover/out
tinyproxy.conf tinyproxy.conf
static/banner.svg static/banner.svg
start.sh

View File

@ -62,8 +62,17 @@ class DOMInput {
protected _section: string; protected _section: string;
protected _name: string; protected _name: string;
hide = () => this._input.parentElement.classList.add("unfocused"); hide = () => {
show = () => this._input.parentElement.classList.remove("unfocused"); this._input.parentElement.classList.add("unfocused");
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": false })
document.dispatchEvent(event);
};
show = () => {
this._input.parentElement.classList.remove("unfocused");
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": this.valueAsString() })
document.dispatchEvent(event);
};
private _advancedListener = (event: settingsBoolEvent) => { private _advancedListener = (event: settingsBoolEvent) => {
if (!Boolean(event.detail)) { if (!Boolean(event.detail)) {
@ -123,7 +132,9 @@ class DOMInput {
onValueChange = () => { onValueChange = () => {
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": this.valueAsString() }) const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": this.valueAsString() })
const setEvent = new CustomEvent(`settings-set-${this._section}-${this._name}`, { "detail": this.valueAsString() })
document.dispatchEvent(event); document.dispatchEvent(event);
document.dispatchEvent(setEvent);
if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); } if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); }
}; };
@ -311,9 +322,19 @@ class DOMBool implements SBool {
private _restart: HTMLSpanElement; private _restart: HTMLSpanElement;
type: string = "bool"; type: string = "bool";
private _advanced: boolean; private _advanced: boolean;
protected _section: string;
protected _name: string;
hide = () => this._input.parentElement.classList.add("unfocused"); hide = () => {
show = () => this._input.parentElement.classList.remove("unfocused"); this._input.parentElement.classList.add("unfocused");
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": false })
document.dispatchEvent(event);
};
show = () => {
this._input.parentElement.classList.remove("unfocused");
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": this.valueAsString() })
document.dispatchEvent(event);
};
private _advancedListener = (event: settingsBoolEvent) => { private _advancedListener = (event: settingsBoolEvent) => {
if (!Boolean(event.detail)) { if (!Boolean(event.detail)) {
@ -375,6 +396,8 @@ class DOMBool implements SBool {
set value(state: boolean) { this._input.checked = state; } set value(state: boolean) { this._input.checked = state; }
constructor(setting: SBool, section: string, name: string) { constructor(setting: SBool, section: string, name: string) {
this._section = section;
this._name = name;
this._container = document.createElement("div"); this._container = document.createElement("div");
this._container.classList.add("setting"); this._container.classList.add("setting");
this._container.setAttribute("data-name", name) this._container.setAttribute("data-name", name)
@ -394,7 +417,9 @@ class DOMBool implements SBool {
this._input = this._container.querySelector("input[type=checkbox]") as HTMLInputElement; this._input = this._container.querySelector("input[type=checkbox]") as HTMLInputElement;
const onValueChange = () => { const onValueChange = () => {
const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.valueAsString() }) const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.valueAsString() })
const setEvent = new CustomEvent(`settings-set-${section}-${name}`, { "detail": this.valueAsString() })
document.dispatchEvent(event); document.dispatchEvent(event);
document.dispatchEvent(setEvent);
}; };
this._input.onchange = () => { this._input.onchange = () => {
onValueChange(); onValueChange();
@ -406,7 +431,9 @@ class DOMBool implements SBool {
let dependant = splitDependant(section, setting.depends_true || setting.depends_false); let dependant = splitDependant(section, setting.depends_true || setting.depends_false);
let state = true; let state = true;
if (setting.depends_false) { state = false; } if (setting.depends_false) { state = false; }
console.log(`I, ${section}-${name}, am adding a listener for ${dependant[0]}-${dependant[1]}`);
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => { document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
console.log(`I, ${section}-${name}, was triggered by a listener for ${dependant[0]}-${dependant[1]}`);
if (Boolean(event.detail) !== state) { if (Boolean(event.detail) !== state) {
this.hide(); this.hide();
} else { } else {
@ -441,9 +468,19 @@ class DOMSelect implements SSelect {
private _options: string[][]; private _options: string[][];
type: string = "bool"; type: string = "bool";
private _advanced: boolean; private _advanced: boolean;
protected _section: string;
protected _name: string;
hide = () => this._container.classList.add("unfocused"); hide = () => {
show = () => this._container.classList.remove("unfocused"); this._container.classList.add("unfocused");
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": false })
document.dispatchEvent(event);
};
show = () => {
this._container.classList.remove("unfocused");
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": this.valueAsString() })
document.dispatchEvent(event);
};
private _advancedListener = (event: settingsBoolEvent) => { private _advancedListener = (event: settingsBoolEvent) => {
if (!Boolean(event.detail)) { if (!Boolean(event.detail)) {
@ -515,6 +552,8 @@ class DOMSelect implements SSelect {
} }
constructor(setting: SSelect, section: string, name: string) { constructor(setting: SSelect, section: string, name: string) {
this._section = section;
this._name = name;
this._options = []; this._options = [];
this._container = document.createElement("div"); this._container = document.createElement("div");
this._container.classList.add("setting"); this._container.classList.add("setting");
@ -548,8 +587,10 @@ class DOMSelect implements SSelect {
}); });
} }
const onValueChange = () => { const onValueChange = () => {
const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.valueAsString() }) const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.valueAsString() });
const setEvent = new CustomEvent(`settings-${section}-${name}`, { "detail": this.valueAsString() });
document.dispatchEvent(event); document.dispatchEvent(event);
document.dispatchEvent(setEvent);
if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); } if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); }
}; };
this._select.onchange = onValueChange; this._select.onchange = onValueChange;
@ -588,8 +629,14 @@ class DOMNote implements SNote {
type: string = "note"; type: string = "note";
private _style: string; private _style: string;
hide = () => this._container.classList.add("unfocused"); hide = () => {
show = () => this._container.classList.remove("unfocused"); this._container.classList.add("unfocused");
// We're a note, no one depends on us so we don't need to broadcast a state change.
};
show = () => {
this._container.classList.remove("unfocused");
// We're a note, no one depends on us so we don't need to broadcast a state change.
};
get name(): string { return this._name.textContent; } get name(): string { return this._name.textContent; }
set name(n: string) { this._name.textContent = n; } set name(n: string) { this._name.textContent = n; }
@ -724,7 +771,9 @@ class sectionPanel {
} }
if (setting.type != "note") { if (setting.type != "note") {
this.values[name] = ""+setting.value; this.values[name] = ""+setting.value;
document.addEventListener(`settings-${this._sectionName}-${name}`, (event: CustomEvent) => { // settings-section-name: Implies the setting changed or was shown/hidden.
// settings-set-section-name: Implies the setting changed.
document.addEventListener(`settings-set-${this._sectionName}-${name}`, (event: CustomEvent) => {
// const oldValue = this.values[name]; // const oldValue = this.values[name];
this.values[name] = event.detail; this.values[name] = event.detail;
document.dispatchEvent(new CustomEvent("settings-section-changed")); document.dispatchEvent(new CustomEvent("settings-section-changed"));