${s.meta.description}
`; this._section.innerHTML = innerHTML; this.update(s); } update = (s: Section) => { for (let setting of s.settings) { if (setting.setting in this._settings) { this._settings[setting.setting].update(setting); } else { if (setting.deprecated) continue; switch (setting.type) { case TextType: setting = new DOMText(setting, this._sectionName, setting.setting); break; case PasswordType: setting = new DOMPassword(setting, this._sectionName, setting.setting); break; case EmailType: setting = new DOMEmail(setting, this._sectionName, setting.setting); break; case NumberType: setting = new DOMNumber(setting, this._sectionName, setting.setting); break; case BoolType: setting = new DOMBool(setting as SBool, this._sectionName, setting.setting); break; case SelectType: setting = new DOMSelect(setting as SSelect, this._sectionName, setting.setting); break; case NoteType: setting = new DOMNote(setting as SNote, this._sectionName); break; case ListType: setting = new DOMList(setting as SList, this._sectionName, setting.setting); break; } if (setting.type != "note") { this.values[setting.setting] = ""+setting.value; // 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}-${setting.setting}`, (event: CustomEvent) => { // const oldValue = this.values[name]; this.values[setting.setting] = event.detail; document.dispatchEvent(new CustomEvent("settings-section-changed")); }); } this._section.appendChild(setting.asElement()); this._settings[setting.setting] = setting; } } } get visible(): boolean { return !this._section.classList.contains("unfocused"); } set visible(s: boolean) { if (s) { this._section.classList.remove("unfocused"); } else { this._section.classList.add("unfocused"); } } asElement = (): HTMLDivElement => { return this._section; } } type Member = { group: string } | { section: string }; class sectionButton extends groupableItem { section: string; private _name: HTMLElement; private _subButton: HTMLElement; private _meta: Meta; update = (section: string, sm: Meta) => { this.section = section; this._meta = sm; this.name = sm.name; this.advanced = sm.advanced; this._registerDependencies(); }; get subButton(): HTMLElement { return this._subButton.children[0] as HTMLElement; } set subButton(v: HTMLElement) { this._subButton.replaceChildren(v); } get name(): string { return this._meta.name; } set name(v: string) { this._meta.name = v; this._name.textContent = v; }; get depends_true(): string { return this._meta.depends_true; } set depends_true(v: string) { this._meta.depends_true = v; this._registerDependencies(); } get depends_false(): string { return this._meta.depends_false; } set depends_false(v: string) { this._meta.depends_false = v; this._registerDependencies(); } get selected(): boolean { return this._el.classList.contains("selected"); } set selected(v: boolean) { if (v) this._el.classList.add("selected"); else this._el.classList.remove("selected"); } select = () => { document.dispatchEvent(new CustomEvent("settings-show-panel", { detail: this.section })); } private _registerDependencies() { // Doesn't re-register dependencies, but that isn't important in this application if (!(this._meta.depends_true || this._meta.depends_false)) return; let [sect, dependant] = splitDependant(this.section, this._meta.depends_true || this._meta.depends_false); let state = !(Boolean(this._meta.depends_false)); document.addEventListener(`settings-${sect}-${dependant}`, (event: settingsChangedEvent) => { console.log(`recieved settings-${sect}-${dependant} = ${event.detail.value} = ${toBool(event.detail.value)} / ${event.detail.hidden}`); const hide = event.detail.hidden || (toBool(event.detail.value) !== state); this.hidden = hide; document.dispatchEvent(new CustomEvent(`settings-${name}`, { detail: !hide })); }); document.addEventListener(`settings-${sect}`, (event: settingsChangedEvent) => { if (event.detail.hidden || toBool(event.detail.value) !== state) { this.hidden = true; document.dispatchEvent(new CustomEvent(`settings-${name}`, { detail: false })); } }); } private _advancedListener = (event: advancedEvent) => { if (!(event.detail)) { this._el.classList.add("unfocused"); } else { this._el.classList.remove("unfocused"); } document.dispatchEvent(new CustomEvent("settings-re-search")); } get advanced(): boolean { return this._meta.advanced } set advanced(v: boolean) { this._meta.advanced = v; if (v) document.addEventListener("settings-advancedState", this._advancedListener); else document.removeEventListener("settings-advancedState", this._advancedListener); } constructor(section?: string, sectionMeta?: Meta) { super(); this._el = document.createElement("span") as HTMLSpanElement; this._el.classList.add("button", "~neutral", "@low", "settings-section-button", "h-11", "justify-between"); this._el.innerHTML = ` `; this._name = this._el.getElementsByClassName("settings-section-button-name")[0] as HTMLElement; this._subButton = this._el.getElementsByClassName("settings-section-button-sub-button")[0] as HTMLElement; this._el.onclick = this.select; if (sectionMeta) this.update(section, sectionMeta); } } interface Settings { groups: Group[]; sections: Section[]; order?: Member[]; } export class settingsList { private _saveButton = document.getElementById("settings-save") as HTMLSpanElement; private _saveNoRestart = document.getElementById("settings-apply-no-restart") as HTMLSpanElement; private _saveRestart = document.getElementById("settings-apply-restart") as HTMLSpanElement; private _loader = document.getElementById("settings-loader") as HTMLDivElement; private _panel = document.getElementById("settings-panel") as HTMLDivElement; private _sidebar = document.getElementById("settings-sidebar-items") as HTMLDivElement; private _visibleSection: string; private _sections: { [name: string]: sectionPanel }; private _buttons: { [name: string]: sectionButton }; private _groups: { [name: string]: Group }; private _groupButtons: { [name: string]: groupButton }; private _needsRestart: boolean = false; private _messageEditor = new MessageEditor(); private _settings: Settings; private _advanced: boolean = false; private _searchbox = document.getElementById("settings-search") as HTMLInputElement; private _clearSearchboxButtons = Array.from(document.getElementsByClassName("settings-search-clear")) as Array${t.description}