Add JSON import and export
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user