random-fo76/src/main/js/index.js

221 lines
6.4 KiB
JavaScript

// noinspection JSUnresolvedVariable
const {$, doAfterLoad, footer, header, nav} = window.fwdekker;
const storageKey = "/tools/random-fo76//selected-signatures";
const signatureColCount = 8;
/**
* Fetches the API response given a query.
*
* @param query the query to send to the API
* @param callback the function to execute with the array of signatures
* @param handle the function to execute if signatures could not be downloaded
*/
const fetchFromApi = (query, callback, handle) => {
fetch(`api.php?${query}`)
.then(response => {
if (!response.ok) {
if (handle) handle(response);
console.error(response);
throw new Error(`Failed to execute query '${query}' on API.`);
}
return response.json();
})
.then(response => callback(response));
}
/**
* Returns an array of the signatures that are currently selected.
*/
const getSelectedSignatures = () => {
const signatures = [];
const selectedCheckboxes = document.querySelectorAll("#signatures input:checked");
for (let i = 0; i < selectedCheckboxes.length; i++) {
const selectedCheckbox = selectedCheckboxes[i];
signatures.push(selectedCheckbox.value);
}
return signatures;
};
/**
* Selects the indicated signatures, and deselects all others.
*
* @param signatures the array of signatures to select
*/
const setSelectedSignatures = signatures => {
const checkboxes = document.querySelectorAll("#signatures input");
for (let i = 0; i < checkboxes.length; i++)
checkboxes[i].checked = false;
for (let i = 0; i < signatures.length; i++)
$(`#signature-${signatures[i]}`).checked = true;
updateSignatureToggle();
};
/**
* Selects all signatures.
*/
const setAllSignatures = checked => {
const checkboxes = document.querySelectorAll("#signatures input");
for (let i = 0; i < checkboxes.length; i++)
checkboxes[i].checked = checked;
saveSelectedSignaturesToStorage();
updateSignatureToggle();
};
/**
* (De)selects signatures based on the selection stored in local storage.
*/
const loadSelectedSignaturesFromStorage = () => {
const item = localStorage.getItem(storageKey);
let signatures;
if (item === null)
signatures = [];
else
signatures = item.split(",");
setSelectedSignatures(signatures);
};
/**
* Saves the currently-selected signatures to local storage.
*/
const saveSelectedSignaturesToStorage = () => localStorage.setItem(storageKey, getSelectedSignatures().join(","));
/**
* Updates the button used to toggle all signatures on or off.
*/
const updateSignatureToggle = () => {
const signatureToggle = $("#signatureToggle");
if (getSelectedSignatures().length === document.querySelectorAll("#signatures input").length) {
signatureToggle.innerHTML = "Deselect all signatures";
signatureToggle.addEventListener("click", () => setAllSignatures(false));
} else {
signatureToggle.innerHTML = "Select all signatures";
signatureToggle.addEventListener("click", () => setAllSignatures(true));
}
};
/**
* Creates buttons for the signatures and adds them to the form.
*
* @param signatures an array of signatures to create buttons for
*/
const createSignatureButtons = signatures => {
const form = $("#signatures");
form.innerHTML = "";
let row;
for (let i = 0; i < signatures.length; i++) {
const signature = signatures[i];
if (i % signatureColCount === 0) {
if (row !== undefined)
form.appendChild(row);
row = document.createElement("div");
row.className = "row";
}
const col = document.createElement("div");
col.className = "column";
const label = document.createElement("label");
label.htmlFor = `signature-${signature}`;
label.innerHTML = signature;
col.appendChild(label);
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.id = `signature-${signature}`;
checkbox.name = `signature-${signature}`;
checkbox.value = signature;
checkbox.addEventListener("click", () => {
updateSignatureToggle();
saveSelectedSignaturesToStorage();
});
col.appendChild(checkbox);
row.appendChild(col);
}
if (row !== undefined)
form.appendChild(row);
};
/**
* Displays a record on the page.
*
* @param record the record to display
*/
const showRecord = (record) => {
$("#output").innerHTML = JSON.stringify(record, null, 4);
const scrollingElement = (document.scrollingElement || document.body);
scrollingElement.scrollTop = scrollingElement.scrollHeight;
};
// Apply template
doAfterLoad(() => {
$("#nav").appendChild(nav("/Tools/Random FO76/"));
$("#header").appendChild(header({
title: "Random Fallout 76 record",
description: "" +
"Retrieve a random record from the <i>Fallout 76</i> game files using " +
"<a href=\"https://github.com/FWDekker/fo76-dumps\">&#9099;&nbsp;my data dumps</a>"
}));
$("#footer").appendChild(footer({
vcsURL: "https://git.fwdekker.com/FWDekker/random-fo76/",
version: "v%%VERSION_NUMBER%%"
}));
$("main").classList.remove("hidden");
});
// Load page from API
doAfterLoad(() => {
fetchFromApi("action=get-meta",
meta => {
$("#gameVersion").innerHTML = meta["game_version"];
$("#dumpsVersion").innerHTML = meta["dumps_version"];
},
() => {
$("#gameVersion").innerHTML = "Error";
$("#dumpsVersion").innerHTML = "Error";
}
);
fetchFromApi("action=list-signatures",
signatures => {
createSignatureButtons(signatures);
loadSelectedSignaturesFromStorage();
},
() => {
const form = $("#signatureForm");
form.classList.add("error");
form.innerHTML = "Error: Failed to download signatures. Try reloading the page.";
}
);
});
// Install handlers
doAfterLoad(() => {
$("#submit").addEventListener("click", () => {
$("#output").innerHTML = "Fetching record... please wait";
const selectedSignatures = getSelectedSignatures();
fetchFromApi(`action=get-random&signatures=${selectedSignatures.join(",")}`,
record => showRecord(record)
);
});
});