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

200 lines
5.8 KiB
JavaScript

// noinspection JSUnresolvedVariable
const {$, $a, doAfterLoad} = window.fwdekker;
/**
* The key to store the selected signatures under in local storage.
* @type {string}
*/
const storageKey = "/tools/random-fo76//selected-signatures";
/**
* 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 = $a("#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 = $a("#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 = $a("#signatures input");
for (let i = 0; i < checkboxes.length; i++)
checkboxes[i].checked = checked; // Does not invoke callback
saveSelectedSignaturesToStorage();
updateSignatureToggle();
};
/**
* (De)selects signatures based on the selection stored in local storage.
*/
const loadSelectedSignaturesFromStorage = () => {
const item = localStorage.getItem(storageKey);
const signatures = (item == null || item.trim() === "") ? [] : 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 = $("#signature-toggle");
if (getSelectedSignatures().length === $a("#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 = "";
for (let i = 0; i < signatures.length; i++) {
const signature = signatures[i];
const cell = document.createElement("div");
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.id = `signature-${signature}`;
checkbox.name = `signature-${signature}`;
checkbox.value = signature;
checkbox.addEventListener("click", () => {
updateSignatureToggle();
saveSelectedSignaturesToStorage();
});
cell.appendChild(checkbox);
const label = document.createElement("label");
label.htmlFor = `signature-${signature}`;
label.innerHTML = signature;
cell.appendChild(label);
form.appendChild(cell);
}
};
/**
* 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;
};
// Load page from API
doAfterLoad(() => {
const gameVersion = $("#game-version");
const dumpsVersion = $("#dumps-version");
fetchFromApi("action=get-meta",
meta => {
gameVersion.innerHTML = meta["game_version"];
gameVersion.removeAttribute("aria-busy");
dumpsVersion.innerHTML = meta["dumps_version"];
dumpsVersion.removeAttribute("aria-busy");
},
() => {
gameVersion.innerHTML = "Error";
gameVersion.removeAttribute("aria-busy");
dumpsVersion.innerHTML = "Error";
dumpsVersion.removeAttribute("aria-busy");
}
);
fetchFromApi("action=list-signatures",
signatures => {
$("#signatures").removeAttribute("aria-busy");
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)
);
});
});