mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 00:50:12 +00:00
config: add support for "list" type
"list" is a list of strings, represented in the .ini as repeated entries for a field, e.g. url = myurl1 url = myurl2 Shown in the UI as multiple inputs with delete buttons.
This commit is contained in:
parent
b2771e6cc5
commit
6bad293f74
@ -585,7 +585,7 @@ func (app *appContext) MatrixLogin(gc *gin.Context) {
|
|||||||
respond(401, "Unauthorized", gc)
|
respond(401, "Unauthorized", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tempConfig, _ := ini.Load(app.configPath)
|
tempConfig, _ := ini.ShadowLoad(app.configPath)
|
||||||
matrix := tempConfig.Section("matrix")
|
matrix := tempConfig.Section("matrix")
|
||||||
matrix.Key("enabled").SetValue("true")
|
matrix.Key("enabled").SetValue("true")
|
||||||
matrix.Key("homeserver").SetValue(req.Homeserver)
|
matrix.Key("homeserver").SetValue(req.Homeserver)
|
||||||
|
15
api.go
15
api.go
@ -290,6 +290,8 @@ func (app *appContext) GetConfig(gc *gin.Context) {
|
|||||||
val := app.config.Section(sectName).Key(settingName)
|
val := app.config.Section(sectName).Key(settingName)
|
||||||
s := resp.Sections[sectName].Settings[settingName]
|
s := resp.Sections[sectName].Settings[settingName]
|
||||||
switch setting.Type {
|
switch setting.Type {
|
||||||
|
case "list":
|
||||||
|
s.Value = val.StringsWithShadows("|")
|
||||||
case "text", "email", "select", "password", "note":
|
case "text", "email", "select", "password", "note":
|
||||||
s.Value = val.MustString("")
|
s.Value = val.MustString("")
|
||||||
case "number":
|
case "number":
|
||||||
@ -327,7 +329,7 @@ func (app *appContext) GetConfig(gc *gin.Context) {
|
|||||||
|
|
||||||
// @Summary Modify app config.
|
// @Summary Modify app config.
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param appConfig body configDTO true "Config split into sections as in config.ini, all values as strings."
|
// @Param appConfig body configDTO true "Config split into sections as in config.ini, all values as strings (lists split with | delimiter)."
|
||||||
// @Success 200 {object} boolResponse
|
// @Success 200 {object} boolResponse
|
||||||
// @Failure 500 {object} stringResponse
|
// @Failure 500 {object} stringResponse
|
||||||
// @Router /config [post]
|
// @Router /config [post]
|
||||||
@ -337,7 +339,7 @@ func (app *appContext) ModifyConfig(gc *gin.Context) {
|
|||||||
var req configDTO
|
var req configDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
// Load a new config, as we set various default values in app.config that shouldn't be stored.
|
// Load a new config, as we set various default values in app.config that shouldn't be stored.
|
||||||
tempConfig, _ := ini.Load(app.configPath)
|
tempConfig, _ := ini.ShadowLoad(app.configPath)
|
||||||
for section, settings := range req {
|
for section, settings := range req {
|
||||||
if section != "restart-program" {
|
if section != "restart-program" {
|
||||||
_, err := tempConfig.GetSection(section)
|
_, err := tempConfig.GetSection(section)
|
||||||
@ -350,6 +352,15 @@ func (app *appContext) ModifyConfig(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
if (section == "discord" || section == "matrix") && setting == "language" {
|
if (section == "discord" || section == "matrix") && setting == "language" {
|
||||||
tempConfig.Section("telegram").Key("language").SetValue(value.(string))
|
tempConfig.Section("telegram").Key("language").SetValue(value.(string))
|
||||||
|
} else if app.configBase.Sections[section].Settings[setting].Type == "list" {
|
||||||
|
splitValues := strings.Split(value.(string), "|")
|
||||||
|
for i, v := range splitValues {
|
||||||
|
if i == 0 {
|
||||||
|
tempConfig.Section(section).Key(setting).SetValue(v)
|
||||||
|
} else {
|
||||||
|
tempConfig.Section(section).Key(setting).AddShadow(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if value.(string) != app.config.Section(section).Key(setting).MustString("") {
|
} else if value.(string) != app.config.Section(section).Key(setting).MustString("") {
|
||||||
tempConfig.Section(section).Key(setting).SetValue(value.(string))
|
tempConfig.Section(section).Key(setting).SetValue(value.(string))
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ func (app *appContext) MustSetValue(section, key, val string) {
|
|||||||
|
|
||||||
func (app *appContext) loadConfig() error {
|
func (app *appContext) loadConfig() error {
|
||||||
var err error
|
var err error
|
||||||
app.config, err = ini.Load(app.configPath)
|
app.config, err = ini.ShadowLoad(app.configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
2
main.go
2
main.go
@ -232,7 +232,7 @@ func start(asDaemon, firstCall bool) {
|
|||||||
app.err.Fatalf(lm.FailedCopyConfig, app.configPath, err)
|
app.err.Fatalf(lm.FailedCopyConfig, app.configPath, err)
|
||||||
}
|
}
|
||||||
app.info.Printf(lm.CopyConfig, app.configPath)
|
app.info.Printf(lm.CopyConfig, app.configPath)
|
||||||
tempConfig, _ := ini.Load(app.configPath)
|
tempConfig, _ := ini.ShadowLoad(app.configPath)
|
||||||
tempConfig.Section("").Key("first_run").SetValue("true")
|
tempConfig.Section("").Key("first_run").SetValue("true")
|
||||||
tempConfig.SaveTo(app.configPath)
|
tempConfig.SaveTo(app.configPath)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func migrateBootstrap(app *appContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func migrateEmailConfig(app *appContext) {
|
func migrateEmailConfig(app *appContext) {
|
||||||
tempConfig, _ := ini.Load(app.configPath)
|
tempConfig, _ := ini.ShadowLoad(app.configPath)
|
||||||
fmt.Println(warning("Part of your email configuration will be migrated to the new \"messages\" section.\nA backup will be made."))
|
fmt.Println(warning("Part of your email configuration will be migrated to the new \"messages\" section.\nA backup will be made."))
|
||||||
err := tempConfig.SaveTo(app.configPath + "_" + commit + ".bak")
|
err := tempConfig.SaveTo(app.configPath + "_" + commit + ".bak")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -111,7 +111,7 @@ func migrateEmailStorage(app *appContext) error {
|
|||||||
return fmt.Errorf("email address was type %T, not string: \"%+v\"\n", addr, addr)
|
return fmt.Errorf("email address was type %T, not string: \"%+v\"\n", addr, addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config, err := ini.Load(app.configPath)
|
config, err := ini.ShadowLoad(app.configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -467,7 +467,7 @@ func intialiseCustomContent(app *appContext) {
|
|||||||
|
|
||||||
// Migrate poorly-named and duplicate "url_base" settings to the single "external jfa-go URL" setting.
|
// Migrate poorly-named and duplicate "url_base" settings to the single "external jfa-go URL" setting.
|
||||||
func migrateExternalURL(app *appContext) {
|
func migrateExternalURL(app *appContext) {
|
||||||
tempConfig, _ := ini.Load(app.configPath)
|
tempConfig, _ := ini.ShadowLoad(app.configPath)
|
||||||
err := tempConfig.SaveTo(app.configPath + "_" + commit + ".bak")
|
err := tempConfig.SaveTo(app.configPath + "_" + commit + ".bak")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Fatalf("Failed to backup config: %v", err)
|
app.err.Fatalf("Failed to backup config: %v", err)
|
||||||
|
@ -29,7 +29,7 @@ interface Setting {
|
|||||||
requires_restart: boolean;
|
requires_restart: boolean;
|
||||||
advanced?: boolean;
|
advanced?: boolean;
|
||||||
type: string;
|
type: string;
|
||||||
value: string | boolean | number;
|
value: string | boolean | number | string[];
|
||||||
depends_true?: string;
|
depends_true?: string;
|
||||||
depends_false?: string;
|
depends_false?: string;
|
||||||
wiki_link?: string;
|
wiki_link?: string;
|
||||||
@ -37,6 +37,11 @@ interface Setting {
|
|||||||
|
|
||||||
asElement: () => HTMLElement;
|
asElement: () => HTMLElement;
|
||||||
update: (s: Setting) => void;
|
update: (s: Setting) => void;
|
||||||
|
|
||||||
|
hide: () => void;
|
||||||
|
show: () => void;
|
||||||
|
|
||||||
|
valueAsString: () => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const splitDependant = (section: string, dep: string): string[] => {
|
const splitDependant = (section: string, dep: string): string[] => {
|
||||||
@ -49,17 +54,22 @@ const splitDependant = (section: string, dep: string): string[] => {
|
|||||||
|
|
||||||
class DOMInput {
|
class DOMInput {
|
||||||
protected _input: HTMLInputElement;
|
protected _input: HTMLInputElement;
|
||||||
private _container: HTMLDivElement;
|
protected _container: HTMLDivElement;
|
||||||
private _tooltip: HTMLDivElement;
|
protected _tooltip: HTMLDivElement;
|
||||||
private _required: HTMLSpanElement;
|
protected _required: HTMLSpanElement;
|
||||||
private _restart: HTMLSpanElement;
|
protected _restart: HTMLSpanElement;
|
||||||
private _advanced: boolean;
|
protected _advanced: boolean;
|
||||||
|
protected _section: string;
|
||||||
|
protected _name: string;
|
||||||
|
|
||||||
|
hide = () => this._input.parentElement.classList.add("unfocused");
|
||||||
|
show = () => this._input.parentElement.classList.remove("unfocused");
|
||||||
|
|
||||||
private _advancedListener = (event: settingsBoolEvent) => {
|
private _advancedListener = (event: settingsBoolEvent) => {
|
||||||
if (!Boolean(event.detail)) {
|
if (!Boolean(event.detail)) {
|
||||||
this._input.parentElement.classList.add("unfocused");
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
this._input.parentElement.classList.remove("unfocused");
|
this.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,10 +119,23 @@ class DOMInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(inputType: string, setting: Setting, section: string, name: string) {
|
valueAsString = (): string => { return ""+this.value; };
|
||||||
|
|
||||||
|
onValueChange = () => {
|
||||||
|
const event = new CustomEvent(`settings-${this._section}-${this._name}`, { "detail": this.valueAsString() })
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); }
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(inputType: string, setting: Setting, section: string, name: string, customInput?: 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)
|
||||||
|
const defaultInput = `
|
||||||
|
<input type="${inputType}" class="input setting-input ~neutral @low mt-2 mb-2">
|
||||||
|
`;
|
||||||
this._container.innerHTML = `
|
this._container.innerHTML = `
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="setting-label"></span> <span class="setting-required"></span> <span class="setting-restart"></span>
|
<span class="setting-label"></span> <span class="setting-required"></span> <span class="setting-restart"></span>
|
||||||
@ -120,31 +143,26 @@ class DOMInput {
|
|||||||
<i class="icon ri-information-line"></i>
|
<i class="icon ri-information-line"></i>
|
||||||
<span class="content sm"></span>
|
<span class="content sm"></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="${inputType}" class="input ~neutral @low mt-2 mb-2">
|
${customInput ? customInput : defaultInput}
|
||||||
</label>
|
</label>
|
||||||
`;
|
`;
|
||||||
this._tooltip = this._container.querySelector("div.setting-tooltip") as HTMLDivElement;
|
this._tooltip = this._container.querySelector("div.setting-tooltip") as HTMLDivElement;
|
||||||
this._required = this._container.querySelector("span.setting-required") as HTMLSpanElement;
|
this._required = this._container.querySelector("span.setting-required") as HTMLSpanElement;
|
||||||
this._restart = this._container.querySelector("span.setting-restart") as HTMLSpanElement;
|
this._restart = this._container.querySelector("span.setting-restart") as HTMLSpanElement;
|
||||||
this._input = this._container.querySelector("input[type=" + inputType + "]") as HTMLInputElement;
|
this._input = this._container.querySelector(".setting-input") as HTMLInputElement;
|
||||||
if (setting.depends_false || setting.depends_true) {
|
if (setting.depends_false || setting.depends_true) {
|
||||||
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; }
|
||||||
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
||||||
if (Boolean(event.detail) !== state) {
|
if (Boolean(event.detail) !== state) {
|
||||||
this._input.parentElement.classList.add("unfocused");
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
this._input.parentElement.classList.remove("unfocused");
|
this.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const onValueChange = () => {
|
this._input.onchange = this.onValueChange;
|
||||||
const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.value })
|
|
||||||
document.dispatchEvent(event);
|
|
||||||
if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); }
|
|
||||||
};
|
|
||||||
this._input.onchange = onValueChange;
|
|
||||||
this.update(setting);
|
this.update(setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,6 +191,85 @@ class DOMText extends DOMInput implements SText {
|
|||||||
set value(v: string) { this._input.value = v; }
|
set value(v: string) { this._input.value = v; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SList extends Setting {
|
||||||
|
value: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class DOMList extends DOMInput implements SList {
|
||||||
|
protected _inputs: HTMLDivElement;
|
||||||
|
type: string = "list";
|
||||||
|
|
||||||
|
valueAsString = (): string => { return this.value.join("|"); };
|
||||||
|
|
||||||
|
get value(): string[] {
|
||||||
|
let values = [];
|
||||||
|
const inputs = this._input.querySelectorAll("input") as NodeListOf<HTMLInputElement>;
|
||||||
|
for (let i in inputs) {
|
||||||
|
if (inputs[i].value) values.push(inputs[i].value);
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
set value(v: string[]) {
|
||||||
|
this._input.textContent = ``;
|
||||||
|
for (let val of v) {
|
||||||
|
let input = this.inputRow(val);
|
||||||
|
this._input.appendChild(input);
|
||||||
|
}
|
||||||
|
const addDummy = () => {
|
||||||
|
const dummyRow = this.inputRow();
|
||||||
|
const input = dummyRow.querySelector("input") as HTMLInputElement;
|
||||||
|
input.placeholder = window.lang.strings("Add");
|
||||||
|
const onDummyChange = () => {
|
||||||
|
if (!(input.value)) return;
|
||||||
|
addDummy();
|
||||||
|
input.removeEventListener("change", onDummyChange);
|
||||||
|
input.placeholder = ``;
|
||||||
|
}
|
||||||
|
input.addEventListener("change", onDummyChange);
|
||||||
|
this._input.appendChild(dummyRow);
|
||||||
|
};
|
||||||
|
addDummy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private inputRow(v: string = ""): HTMLDivElement {
|
||||||
|
let container = document.createElement("div") as HTMLDivElement;
|
||||||
|
container.classList.add("flex", "flex-row", "justify-between");
|
||||||
|
container.innerHTML = `
|
||||||
|
<input type="text" class="input ~neutral @low">
|
||||||
|
<button class="button ~neutral @low center -ml-10 rounded-s-none aria-label="${window.lang.strings("delete")}" title="${window.lang.strings("delete")}">
|
||||||
|
<i class="ri-close-line"></i>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
const input = container.querySelector("input") as HTMLInputElement;
|
||||||
|
input.value = v;
|
||||||
|
input.onchange = this.onValueChange;
|
||||||
|
const removeRow = container.querySelector("button") as HTMLButtonElement;
|
||||||
|
removeRow.onclick = () => {
|
||||||
|
if (!(container.nextElementSibling)) return;
|
||||||
|
container.remove();
|
||||||
|
this.onValueChange();
|
||||||
|
}
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
update = (s: Setting) => {
|
||||||
|
this.name = s.name;
|
||||||
|
this.description = s.description;
|
||||||
|
this.required = s.required;
|
||||||
|
this.requires_restart = s.requires_restart;
|
||||||
|
this.value = s.value as string[];
|
||||||
|
this.advanced = s.advanced;
|
||||||
|
}
|
||||||
|
|
||||||
|
asElement = (): HTMLDivElement => { return this._container; }
|
||||||
|
|
||||||
|
constructor(setting: Setting, section: string, name: string) {
|
||||||
|
super("list", setting, section, name,
|
||||||
|
`<div class="setting-input flex flex-col gap-2 mt-2 mb-2"></div>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface SPassword extends Setting {
|
interface SPassword extends Setting {
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
@ -214,12 +311,15 @@ class DOMBool implements SBool {
|
|||||||
private _restart: HTMLSpanElement;
|
private _restart: HTMLSpanElement;
|
||||||
type: string = "bool";
|
type: string = "bool";
|
||||||
private _advanced: boolean;
|
private _advanced: boolean;
|
||||||
|
|
||||||
|
hide = () => this._input.parentElement.classList.add("unfocused");
|
||||||
|
show = () => this._input.parentElement.classList.remove("unfocused");
|
||||||
|
|
||||||
private _advancedListener = (event: settingsBoolEvent) => {
|
private _advancedListener = (event: settingsBoolEvent) => {
|
||||||
if (!Boolean(event.detail)) {
|
if (!Boolean(event.detail)) {
|
||||||
this._input.parentElement.classList.add("unfocused");
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
this._input.parentElement.classList.remove("unfocused");
|
this.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,8 +368,12 @@ class DOMBool implements SBool {
|
|||||||
this._restart.textContent = "";
|
this._restart.textContent = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
valueAsString = (): string => { return ""+this.value; };
|
||||||
|
|
||||||
get value(): boolean { return this._input.checked; }
|
get value(): boolean { return this._input.checked; }
|
||||||
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._container = document.createElement("div");
|
this._container = document.createElement("div");
|
||||||
this._container.classList.add("setting");
|
this._container.classList.add("setting");
|
||||||
@ -289,7 +393,7 @@ class DOMBool implements SBool {
|
|||||||
this._restart = this._container.querySelector("span.setting-restart") as HTMLSpanElement;
|
this._restart = this._container.querySelector("span.setting-restart") as HTMLSpanElement;
|
||||||
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.value })
|
const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.valueAsString() })
|
||||||
document.dispatchEvent(event);
|
document.dispatchEvent(event);
|
||||||
};
|
};
|
||||||
this._input.onchange = () => {
|
this._input.onchange = () => {
|
||||||
@ -304,9 +408,9 @@ class DOMBool implements SBool {
|
|||||||
if (setting.depends_false) { state = false; }
|
if (setting.depends_false) { state = false; }
|
||||||
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
||||||
if (Boolean(event.detail) !== state) {
|
if (Boolean(event.detail) !== state) {
|
||||||
this._input.parentElement.classList.add("unfocused");
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
this._input.parentElement.classList.remove("unfocused");
|
this.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -338,11 +442,14 @@ class DOMSelect implements SSelect {
|
|||||||
type: string = "bool";
|
type: string = "bool";
|
||||||
private _advanced: boolean;
|
private _advanced: boolean;
|
||||||
|
|
||||||
|
hide = () => this._container.classList.add("unfocused");
|
||||||
|
show = () => this._container.classList.remove("unfocused");
|
||||||
|
|
||||||
private _advancedListener = (event: settingsBoolEvent) => {
|
private _advancedListener = (event: settingsBoolEvent) => {
|
||||||
if (!Boolean(event.detail)) {
|
if (!Boolean(event.detail)) {
|
||||||
this._container.classList.add("unfocused");
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
this._container.classList.remove("unfocused");
|
this.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,6 +498,9 @@ class DOMSelect implements SSelect {
|
|||||||
this._restart.textContent = "";
|
this._restart.textContent = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
valueAsString = (): string => { return ""+this.value; };
|
||||||
|
|
||||||
get value(): string { return this._select.value; }
|
get value(): string { return this._select.value; }
|
||||||
set value(v: string) { this._select.value = v; }
|
set value(v: string) { this._select.value = v; }
|
||||||
|
|
||||||
@ -431,14 +541,14 @@ class DOMSelect implements SSelect {
|
|||||||
if (setting.depends_false) { state = false; }
|
if (setting.depends_false) { state = false; }
|
||||||
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
||||||
if (Boolean(event.detail) !== state) {
|
if (Boolean(event.detail) !== state) {
|
||||||
this._container.classList.add("unfocused");
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
this._container.classList.remove("unfocused");
|
this.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const onValueChange = () => {
|
const onValueChange = () => {
|
||||||
const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.value })
|
const event = new CustomEvent(`settings-${section}-${name}`, { "detail": this.valueAsString() })
|
||||||
document.dispatchEvent(event);
|
document.dispatchEvent(event);
|
||||||
if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); }
|
if (this.requires_restart) { document.dispatchEvent(new CustomEvent("settings-requires-restart")); }
|
||||||
};
|
};
|
||||||
@ -478,6 +588,9 @@ class DOMNote implements SNote {
|
|||||||
type: string = "note";
|
type: string = "note";
|
||||||
private _style: string;
|
private _style: string;
|
||||||
|
|
||||||
|
hide = () => this._container.classList.add("unfocused");
|
||||||
|
show = () => this._container.classList.remove("unfocused");
|
||||||
|
|
||||||
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; }
|
||||||
|
|
||||||
@ -486,6 +599,8 @@ class DOMNote implements SNote {
|
|||||||
this._description.innerHTML = d;
|
this._description.innerHTML = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
valueAsString = (): string => { return ""; };
|
||||||
|
|
||||||
get value(): string { return ""; }
|
get value(): string { return ""; }
|
||||||
set value(v: string) { return; }
|
set value(v: string) { return; }
|
||||||
|
|
||||||
@ -521,9 +636,9 @@ class DOMNote implements SNote {
|
|||||||
if (setting.depends_false) { state = false; }
|
if (setting.depends_false) { state = false; }
|
||||||
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
document.addEventListener(`settings-${dependant[0]}-${dependant[1]}`, (event: settingsBoolEvent) => {
|
||||||
if (Boolean(event.detail) !== state) {
|
if (Boolean(event.detail) !== state) {
|
||||||
this._container.classList.add("unfocused");
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
this._container.classList.remove("unfocused");
|
this.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -603,12 +718,15 @@ class sectionPanel {
|
|||||||
case "note":
|
case "note":
|
||||||
setting = new DOMNote(setting as SNote, this._sectionName);
|
setting = new DOMNote(setting as SNote, this._sectionName);
|
||||||
break;
|
break;
|
||||||
|
case "list":
|
||||||
|
setting = new DOMList(setting as SList, this._sectionName, name);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
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) => {
|
document.addEventListener(`settings-${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"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user