feat(webui): automatically commit toggle changes (#2198)

Closes #2197

Reviewed-on: OpenWF/SpaceNinjaServer#2198
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2025-06-18 11:05:07 -07:00 committed by Sainan
parent 7819d87bbe
commit dabca46e88
11 changed files with 52 additions and 52 deletions

View File

@ -1,15 +1,21 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { updateConfig } from "@/src/services/configWatcherService"; import { saveConfig } from "@/src/services/configWatcherService";
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
import { config, IConfig } from "@/src/services/configService";
const updateConfigDataController: RequestHandler = async (req, res) => { export const updateConfigDataController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req); const account = await getAccountForRequest(req);
if (isAdministrator(account)) { if (isAdministrator(account)) {
await updateConfig(String(req.body)); const data = req.body as IUpdateConfigDataRequest;
config[data.key] = data.value;
await saveConfig();
res.end(); res.end();
} else { } else {
res.status(401).end(); res.status(401).end();
} }
}; };
export { updateConfigDataController }; interface IUpdateConfigDataRequest {
key: keyof IConfig;
value: never;
}

View File

@ -2,7 +2,7 @@ import fs from "fs";
import path from "path"; import path from "path";
import { repoDir } from "@/src/helpers/pathHelper"; import { repoDir } from "@/src/helpers/pathHelper";
interface IConfig { export interface IConfig {
mongodbUrl: string; mongodbUrl: string;
logger: { logger: {
files: boolean; files: boolean;

View File

@ -46,12 +46,6 @@ export const validateConfig = (): void => {
} }
}; };
export const updateConfig = async (data: string): Promise<void> => {
amnesia = true;
await fsPromises.writeFile(configPath, data);
Object.assign(config, JSON.parse(data));
};
export const saveConfig = async (): Promise<void> => { export const saveConfig = async (): Promise<void> => {
amnesia = true; amnesia = true;
await fsPromises.writeFile(configPath, JSON.stringify(config, null, 2)); await fsPromises.writeFile(configPath, JSON.stringify(config, null, 2));

View File

@ -571,7 +571,7 @@
<div id="server-settings-no-perms" class="d-none"> <div id="server-settings-no-perms" class="d-none">
<p class="card-text" data-loc="cheats_administratorRequirement"></p> <p class="card-text" data-loc="cheats_administratorRequirement"></p>
</div> </div>
<form id="server-settings" class="d-none" onsubmit="doChangeSettings();return false;"> <div id="server-settings" class="d-none">
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="skipTutorial" /> <input class="form-check-input" type="checkbox" id="skipTutorial" />
<label class="form-check-label" for="skipTutorial" data-loc="cheats_skipTutorial"></label> <label class="form-check-label" for="skipTutorial" data-loc="cheats_skipTutorial"></label>
@ -732,16 +732,21 @@
<input class="form-check-input" type="checkbox" id="fastClanAscension" /> <input class="form-check-input" type="checkbox" id="fastClanAscension" />
<label class="form-check-label" for="fastClanAscension" data-loc="cheats_fastClanAscension"></label> <label class="form-check-label" for="fastClanAscension" data-loc="cheats_fastClanAscension"></label>
</div> </div>
<div class="form-group mt-2"> <form class="form-group mt-2" onsubmit="doSaveConfig('spoofMasteryRank'); return false;">
<label class="form-label" for="spoofMasteryRank" data-loc="cheats_spoofMasteryRank"></label> <label class="form-label" for="spoofMasteryRank" data-loc="cheats_spoofMasteryRank"></label>
<div class="input-group">
<input class="form-control" id="spoofMasteryRank" type="number" min="-1" max="65535" /> <input class="form-control" id="spoofMasteryRank" type="number" min="-1" max="65535" />
<button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
</div> </div>
<div class="form-group mt-2">
<label class="form-label" for="nightwaveStandingMultiplier" data-loc="cheats_nightwaveStandingMultiplier"></label>
<input class="form-control" id="nightwaveStandingMultiplier" type="number" min="1" max="1000000" value="1" />
</div>
<button class="btn btn-primary mt-3" type="submit" data-loc="cheats_saveSettings"></button>
</form> </form>
<form class="form-group mt-2" onsubmit="doSaveConfig('nightwaveStandingMultiplier'); return false;">
<label class="form-label" for="nightwaveStandingMultiplier" data-loc="cheats_nightwaveStandingMultiplier"></label>
<div class="input-group">
<input class="form-control" id="nightwaveStandingMultiplier" type="number" min="1" max="1000000" value="1" />
<button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1761,34 +1761,29 @@ function doAcquireMod() {
const uiConfigs = [...$("#server-settings input[id]")].map(x => x.id); const uiConfigs = [...$("#server-settings input[id]")].map(x => x.id);
function doChangeSettings() { for (const id of uiConfigs) {
revalidateAuthz(() => { const elm = document.getElementById(id);
fetch("/custom/config?" + window.authz) if (elm.type == "checkbox") {
.then(response => response.json()) elm.onchange = function () {
.then(json => {
for (const i of uiConfigs) {
var x = document.getElementById(i);
if (x != null) {
if (x.type == "checkbox") {
if (x.checked === true) {
json[i] = true;
} else {
json[i] = false;
}
} else if (x.type == "number") {
json[i] = parseInt(x.value);
}
}
}
$.post({ $.post({
url: "/custom/config?" + window.authz, url: "/custom/config?" + window.authz,
contentType: "text/plain", contentType: "application/json",
data: JSON.stringify(json, null, 2) data: JSON.stringify({ key: id, value: this.checked })
}).then(() => { }).then(() => {
// A few cheats affect the inventory response which in turn may change what values we need to show if (["infiniteCredits", "infinitePlatinum", "infiniteEndo", "infiniteRegalAya"].indexOf(id) != -1) {
updateInventory(); updateInventory();
}
}); });
}); };
}
}
function doSaveConfig(id) {
const elm = document.getElementById(id);
$.post({
url: "/custom/config?" + window.authz,
contentType: "application/json",
data: JSON.stringify({ key: id, value: parseInt(elm.value) })
}); });
} }

View File

@ -167,7 +167,7 @@ dict = {
cheats_fastClanAscension: `Schneller Clan-Aufstieg`, cheats_fastClanAscension: `Schneller Clan-Aufstieg`,
cheats_spoofMasteryRank: `Gefälschter Meisterschaftsrang (-1 zum deaktivieren)`, cheats_spoofMasteryRank: `Gefälschter Meisterschaftsrang (-1 zum deaktivieren)`,
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`, cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
cheats_saveSettings: `Einstellungen speichern`, cheats_save: `[UNTRANSLATED] Save`,
cheats_account: `Account`, cheats_account: `Account`,
cheats_unlockAllFocusSchools: `Alle Fokus-Schulen freischalten`, cheats_unlockAllFocusSchools: `Alle Fokus-Schulen freischalten`,
cheats_helminthUnlockAll: `Helminth vollständig aufleveln`, cheats_helminthUnlockAll: `Helminth vollständig aufleveln`,

View File

@ -166,7 +166,7 @@ dict = {
cheats_fastClanAscension: `Fast Clan Ascension`, cheats_fastClanAscension: `Fast Clan Ascension`,
cheats_spoofMasteryRank: `Spoofed Mastery Rank (-1 to disable)`, cheats_spoofMasteryRank: `Spoofed Mastery Rank (-1 to disable)`,
cheats_nightwaveStandingMultiplier: `Nightwave Standing Multiplier`, cheats_nightwaveStandingMultiplier: `Nightwave Standing Multiplier`,
cheats_saveSettings: `Save Settings`, cheats_save: `Save`,
cheats_account: `Account`, cheats_account: `Account`,
cheats_unlockAllFocusSchools: `Unlock All Focus Schools`, cheats_unlockAllFocusSchools: `Unlock All Focus Schools`,
cheats_helminthUnlockAll: `Fully Level Up Helminth`, cheats_helminthUnlockAll: `Fully Level Up Helminth`,

View File

@ -167,7 +167,7 @@ dict = {
cheats_fastClanAscension: `Ascenso rápido del clan`, cheats_fastClanAscension: `Ascenso rápido del clan`,
cheats_spoofMasteryRank: `Rango de maestría simulado (-1 para desactivar)`, cheats_spoofMasteryRank: `Rango de maestría simulado (-1 para desactivar)`,
cheats_nightwaveStandingMultiplier: `Multiplicador de Reputación de Onda Nocturna`, cheats_nightwaveStandingMultiplier: `Multiplicador de Reputación de Onda Nocturna`,
cheats_saveSettings: `Guardar configuración`, cheats_save: `[UNTRANSLATED] Save`,
cheats_account: `Cuenta`, cheats_account: `Cuenta`,
cheats_unlockAllFocusSchools: `Desbloquear todas las escuelas de enfoque`, cheats_unlockAllFocusSchools: `Desbloquear todas las escuelas de enfoque`,
cheats_helminthUnlockAll: `Subir al máximo el Helminto`, cheats_helminthUnlockAll: `Subir al máximo el Helminto`,

View File

@ -167,7 +167,7 @@ dict = {
cheats_fastClanAscension: `Ascension de clan rapide`, cheats_fastClanAscension: `Ascension de clan rapide`,
cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`, cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`, cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
cheats_saveSettings: `Sauvegarder les paramètres`, cheats_save: `[UNTRANSLATED] Save`,
cheats_account: `Compte`, cheats_account: `Compte`,
cheats_unlockAllFocusSchools: `Débloquer toutes les écoles de focus`, cheats_unlockAllFocusSchools: `Débloquer toutes les écoles de focus`,
cheats_helminthUnlockAll: `Helminth niveau max`, cheats_helminthUnlockAll: `Helminth niveau max`,

View File

@ -167,7 +167,7 @@ dict = {
cheats_fastClanAscension: `Мгновенное Вознесение Клана`, cheats_fastClanAscension: `Мгновенное Вознесение Клана`,
cheats_spoofMasteryRank: `Подделанный ранг мастерства (-1 для отключения)`, cheats_spoofMasteryRank: `Подделанный ранг мастерства (-1 для отключения)`,
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`, cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
cheats_saveSettings: `Сохранить настройки`, cheats_save: `[UNTRANSLATED] Save`,
cheats_account: `Аккаунт`, cheats_account: `Аккаунт`,
cheats_unlockAllFocusSchools: `Разблокировать все школы фокуса`, cheats_unlockAllFocusSchools: `Разблокировать все школы фокуса`,
cheats_helminthUnlockAll: `Полностью улучшить Гельминта`, cheats_helminthUnlockAll: `Полностью улучшить Гельминта`,

View File

@ -167,7 +167,7 @@ dict = {
cheats_fastClanAscension: `快速升级氏族`, cheats_fastClanAscension: `快速升级氏族`,
cheats_spoofMasteryRank: `伪造精通段位(-1为禁用)`, cheats_spoofMasteryRank: `伪造精通段位(-1为禁用)`,
cheats_nightwaveStandingMultiplier: `午夜电波声望倍率`, cheats_nightwaveStandingMultiplier: `午夜电波声望倍率`,
cheats_saveSettings: `保存设置`, cheats_save: `[UNTRANSLATED] Save`,
cheats_account: `账户`, cheats_account: `账户`,
cheats_unlockAllFocusSchools: `解锁所有专精学派`, cheats_unlockAllFocusSchools: `解锁所有专精学派`,
cheats_helminthUnlockAll: `完全升级Helminth`, cheats_helminthUnlockAll: `完全升级Helminth`,