Add JSON import and export

This commit is contained in:
Jan Bader
2026-06-16 15:12:12 +02:00
parent 690faf6c57
commit 02e63d10dd
4 changed files with 156 additions and 2 deletions
+99
View File
@@ -43,6 +43,7 @@ const PROFILES = {
const STORAGE_KEY = "forgeMasterOptimizer.v1";
const DRAFT_KEY = "forgeMasterOptimizer.draft.v1";
const EXPORT_VERSION = 1;
const slots = [
...Array.from({ length: 8 }, (_, i) => ({ type: "item", title: `Item ${i + 1}` })),
{ type: "mount", title: "Mount" },
@@ -358,6 +359,100 @@ function setStatus(message, danger = false) {
node.style.color = danger ? "var(--danger)" : "var(--good)";
}
function setImportExportStatus(message, danger = false) {
const node = $("#importExportStatus");
node.textContent = message;
node.style.color = danger ? "var(--danger)" : "var(--good)";
}
function createExportPayload() {
return {
app: "forge-master-strategy-optimizer",
version: EXPORT_VERSION,
exportedAt: new Date().toISOString(),
build: normalizeState(state),
};
}
function createExportJson() {
return JSON.stringify(createExportPayload(), null, 2);
}
async function generateExportJson() {
const json = createExportJson();
const textarea = $("#jsonTransfer");
textarea.value = json;
textarea.focus();
textarea.select();
try {
await navigator.clipboard.writeText(json);
setImportExportStatus("Export JSON generated and copied to clipboard.");
} catch {
setImportExportStatus("Export JSON generated. Copy it from the text box or download it as a file.");
}
}
function downloadExportJson() {
const json = createExportJson();
$("#jsonTransfer").value = json;
const blob = new Blob([json], { type: "application/json" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = `forge-master-build-${new Date().toISOString().slice(0, 10)}.json`;
document.body.appendChild(link);
link.click();
link.remove();
URL.revokeObjectURL(url);
setImportExportStatus("Downloaded current build as JSON.");
}
function parseImportedState(jsonText) {
if (!jsonText.trim()) throw new Error("Paste JSON first or upload a JSON file.");
let parsed;
try {
parsed = JSON.parse(jsonText);
} catch {
throw new Error("Invalid JSON. Check that the full export was copied.");
}
const build = parsed?.build || parsed;
if (!build || typeof build !== "object" || !Array.isArray(build.pieces)) {
throw new Error("JSON does not look like a Forge Master build export.");
}
return normalizeState(build);
}
function importJsonText(jsonText, sourceLabel = "JSON") {
try {
state = parseImportedState(jsonText);
render();
setImportExportStatus(`Imported ${sourceLabel}. Draft autosaved.`);
} catch (error) {
setImportExportStatus(error.message, true);
}
}
function importPastedJson() {
importJsonText($("#jsonTransfer").value, "pasted JSON");
}
function importUploadedJson(event) {
const file = event.target.files?.[0];
if (!file) return;
const reader = new FileReader();
reader.addEventListener("load", () => {
const text = String(reader.result || "");
$("#jsonTransfer").value = text;
importJsonText(text, file.name);
event.target.value = "";
});
reader.addEventListener("error", () => {
setImportExportStatus("Could not read the selected file.", true);
event.target.value = "";
});
reader.readAsText(file);
}
function bindEvents() {
$("#profileSelect").addEventListener("change", (event) => {
state.profile = event.target.value;
@@ -381,6 +476,10 @@ function bindEvents() {
$("#saveSlot").addEventListener("click", saveNamedSlot);
$("#loadSlot").addEventListener("click", loadNamedSlot);
$("#deleteSlot").addEventListener("click", deleteNamedSlot);
$("#copyExport").addEventListener("click", generateExportJson);
$("#downloadExport").addEventListener("click", downloadExportJson);
$("#importJson").addEventListener("click", importPastedJson);
$("#importFile").addEventListener("change", importUploadedJson);
}
function handleGearInput(event) {