This commit is contained in:
@@ -1806,6 +1806,7 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
setup: { switch_time: "10", custom_panel: false, specs_enabled: false, memes_enabled: false },
|
setup: { switch_time: "10", custom_panel: false, specs_enabled: false, memes_enabled: false },
|
||||||
display: {},
|
display: {},
|
||||||
system: {},
|
system: {},
|
||||||
|
dirty: false,
|
||||||
};
|
};
|
||||||
const el = {
|
const el = {
|
||||||
gallery: document.getElementById("gallery"),
|
gallery: document.getElementById("gallery"),
|
||||||
@@ -1859,6 +1860,7 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
const [item] = next.splice(index, 1);
|
const [item] = next.splice(index, 1);
|
||||||
next.splice(target, 0, item);
|
next.splice(target, 0, item);
|
||||||
state.activeImages = next;
|
state.activeImages = next;
|
||||||
|
markDirty();
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1868,9 +1870,25 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
} else {
|
} else {
|
||||||
state.activeImages = [...state.activeImages, name];
|
state.activeImages = [...state.activeImages, name];
|
||||||
}
|
}
|
||||||
|
markDirty();
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function markDirty() {
|
||||||
|
state.dirty = true;
|
||||||
|
updateDirtyUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearDirty() {
|
||||||
|
state.dirty = false;
|
||||||
|
updateDirtyUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDirtyUi() {
|
||||||
|
el.apply.textContent = state.dirty ? "Apply Rotation *" : "Apply Rotation";
|
||||||
|
el.imageCountValue.textContent = `${state.activeImages.length}${state.dirty ? " *" : ""}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function request(url, options = {}) {
|
async function request(url, options = {}) {
|
||||||
const res = await fetch(url, options);
|
const res = await fetch(url, options);
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
@@ -1878,24 +1896,39 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load() {
|
async function load(options = {}) {
|
||||||
|
const force = !!options.force;
|
||||||
|
const preserveDraft = !!options.preserveDraft;
|
||||||
|
if (state.dirty && !force) return;
|
||||||
|
|
||||||
|
const draftActiveImages = [...state.activeImages];
|
||||||
const data = await request("/api/state");
|
const data = await request("/api/state");
|
||||||
state.images = data.images;
|
state.images = data.images;
|
||||||
state.activeImages = data.active_images;
|
state.activeImages = preserveDraft
|
||||||
state.setup = data.setup;
|
? draftActiveImages.filter((name) => data.images.some((image) => image.name === name))
|
||||||
|
: data.active_images;
|
||||||
|
state.setup = preserveDraft
|
||||||
|
? {
|
||||||
|
...data.setup,
|
||||||
|
switch_time: el.switchTime.value || data.setup.switch_time || "10",
|
||||||
|
specs_enabled: el.specsEnabled.checked,
|
||||||
|
memes_enabled: el.memesEnabled.checked,
|
||||||
|
}
|
||||||
|
: data.setup;
|
||||||
state.display = data.display || {};
|
state.display = data.display || {};
|
||||||
state.system = data.system || {};
|
state.system = data.system || {};
|
||||||
|
if (!preserveDraft) {
|
||||||
el.switchTime.value = data.setup.switch_time || "10";
|
el.switchTime.value = data.setup.switch_time || "10";
|
||||||
el.specsEnabled.checked = !!data.setup.specs_enabled;
|
el.specsEnabled.checked = !!data.setup.specs_enabled;
|
||||||
el.memesEnabled.checked = !!data.setup.memes_enabled;
|
el.memesEnabled.checked = !!data.setup.memes_enabled;
|
||||||
|
}
|
||||||
const enabledModes = [
|
const enabledModes = [
|
||||||
data.setup.specs_enabled ? "Specs" : "",
|
state.setup.specs_enabled ? "Specs" : "",
|
||||||
data.setup.memes_enabled ? "Memes" : "",
|
state.setup.memes_enabled ? "Memes" : "",
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
el.customPanelValue.textContent = data.setup.custom_panel
|
el.customPanelValue.textContent = state.setup.custom_panel
|
||||||
? (enabledModes.join(" + ") || "Active")
|
? (enabledModes.join(" + ") || "Active")
|
||||||
: "Disabled";
|
: "Disabled";
|
||||||
el.imageCountValue.textContent = String(data.active_images.length);
|
|
||||||
el.displayStatusValue.textContent = state.display.connected
|
el.displayStatusValue.textContent = state.display.connected
|
||||||
? `Connected (${state.display.mode || "native"})`
|
? `Connected (${state.display.mode || "native"})`
|
||||||
: (state.display.native_enabled ? "Disconnected" : "Disabled");
|
: (state.display.native_enabled ? "Disconnected" : "Disabled");
|
||||||
@@ -1915,6 +1948,7 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
el.uptimeValue.textContent = `Uptime ${state.system.uptime || "-"}`;
|
el.uptimeValue.textContent = `Uptime ${state.system.uptime || "-"}`;
|
||||||
el.tempCpuValue.textContent = `CPU ${state.system.temperature_cpu || "-"}`;
|
el.tempCpuValue.textContent = `CPU ${state.system.temperature_cpu || "-"}`;
|
||||||
el.tempGpuValue.textContent = `GPU ${state.system.temperature_gpu || "-"}`;
|
el.tempGpuValue.textContent = `GPU ${state.system.temperature_gpu || "-"}`;
|
||||||
|
updateDirtyUi();
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1926,7 +1960,7 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
await request("/api/upload", { method: "POST", body: form });
|
await request("/api/upload", { method: "POST", body: form });
|
||||||
event.target.value = "";
|
event.target.value = "";
|
||||||
toast("Upload complete");
|
toast("Upload complete");
|
||||||
await load();
|
await load({ force: true, preserveDraft: state.dirty });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function apply() {
|
async function apply() {
|
||||||
@@ -1940,14 +1974,16 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
memes_enabled: el.memesEnabled.checked,
|
memes_enabled: el.memesEnabled.checked,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
clearDirty();
|
||||||
toast("Rotation updated");
|
toast("Rotation updated");
|
||||||
await load();
|
await load({ force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function disablePanels() {
|
async function disablePanels() {
|
||||||
await request("/api/panels/disable", { method: "POST" });
|
await request("/api/panels/disable", { method: "POST" });
|
||||||
|
clearDirty();
|
||||||
toast("Custom panels disabled");
|
toast("Custom panels disabled");
|
||||||
await load();
|
await load({ force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeImage(name) {
|
async function removeImage(name) {
|
||||||
@@ -1956,8 +1992,10 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ name }),
|
body: JSON.stringify({ name }),
|
||||||
});
|
});
|
||||||
|
state.activeImages = state.activeImages.filter((item) => item !== name);
|
||||||
|
clearDirty();
|
||||||
toast("Image deleted");
|
toast("Image deleted");
|
||||||
await load();
|
await load({ force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
@@ -2046,9 +2084,15 @@ const INDEX_HTML: &str = r##"<!DOCTYPE html>
|
|||||||
el.upload.addEventListener("change", (event) => uploadFile(event).catch((err) => toast(err.message)));
|
el.upload.addEventListener("change", (event) => uploadFile(event).catch((err) => toast(err.message)));
|
||||||
el.apply.addEventListener("click", () => apply().catch((err) => toast(err.message)));
|
el.apply.addEventListener("click", () => apply().catch((err) => toast(err.message)));
|
||||||
el.disable.addEventListener("click", () => disablePanels().catch((err) => toast(err.message)));
|
el.disable.addEventListener("click", () => disablePanels().catch((err) => toast(err.message)));
|
||||||
el.refresh.addEventListener("click", () => load().catch((err) => toast(err.message)));
|
el.refresh.addEventListener("click", () => {
|
||||||
|
clearDirty();
|
||||||
|
load({ force: true }).catch((err) => toast(err.message));
|
||||||
|
});
|
||||||
|
el.switchTime.addEventListener("change", markDirty);
|
||||||
|
el.specsEnabled.addEventListener("change", markDirty);
|
||||||
|
el.memesEnabled.addEventListener("change", markDirty);
|
||||||
|
|
||||||
load().catch((err) => toast(err.message));
|
load({ force: true }).catch((err) => toast(err.message));
|
||||||
setInterval(() => load().catch(() => {}), 5000);
|
setInterval(() => load().catch(() => {}), 5000);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user