CenTdemeern1
f0617522e3
All checks were successful
Build & Test / build-run (push) Successful in 49s
Which resets the storage manager, not the entire localstorage. Not that localstorage should be touched outside of the storage manager, but it means I can keep my backups for debugging in there.
157 lines
6 KiB
TypeScript
157 lines
6 KiB
TypeScript
import { parseHost } from "./add_an_instance.mjs";
|
|
import { AddInstanceFlow } from "./add_instance_flow.mjs";
|
|
import { dialogDetailsFromInstance, dialogDetailsToInstance, InstanceDetailsDialog, InstanceDetailsDialogData } from "./confirm_instance_details.mjs";
|
|
import { findButtonOrFail, findDialogOrFail, findOlOrFail } from "./dom.mjs";
|
|
import storageManager, { Instance } from "./storage_manager.mjs";
|
|
|
|
let reordering = false;
|
|
let unsaved = false;
|
|
// Dragging code is a heavily modified version of https://stackoverflow.com/a/28962290
|
|
let elementBeingDragged: HTMLLIElement | undefined;
|
|
|
|
const mainDialog = findDialogOrFail(document.body, "#mainDialog");
|
|
const startAddInstanceFlowButton = findButtonOrFail(document.body, "#startAddInstanceFlow");
|
|
const addDialog = findDialogOrFail(document.body, "#addInstance");
|
|
const spinnerDialog = findDialogOrFail(document.body, "#spinner");
|
|
const detailsDialog = findDialogOrFail(document.body, "#instanceDetails");
|
|
const instanceList = findOlOrFail(document.body, "#instanceList");
|
|
const saveButton = findButtonOrFail(document.body, "#save");
|
|
const reorderButton = findButtonOrFail(document.body, "#reorder");
|
|
const resetButton = findButtonOrFail(document.body, "#reset");
|
|
|
|
let instanceDetailsDialog = new InstanceDetailsDialog(detailsDialog, true);
|
|
let addInstanceFlow = new AddInstanceFlow(addDialog, spinnerDialog, instanceDetailsDialog);
|
|
|
|
startAddInstanceFlowButton.addEventListener("click", e => {
|
|
addInstanceFlow.start(false).then(_ => {
|
|
updateInstanceList();
|
|
unsavedChanges();
|
|
});
|
|
});
|
|
|
|
saveButton.addEventListener("click", e => saveChanges());
|
|
|
|
reorderButton.addEventListener("click", () => {
|
|
reordering = !reordering;
|
|
if (!reordering) applyReordering();
|
|
updateInstanceList();
|
|
reorderButton.innerText = reordering ? "Finish reordering" : "Reorder";
|
|
});
|
|
|
|
resetButton.addEventListener("click", e => {
|
|
storageManager.reset();
|
|
updateInstanceList();
|
|
unsavedChanges();
|
|
});
|
|
|
|
updateInstanceList();
|
|
storageManager.addSaveCallback(updateInstanceList);
|
|
|
|
mainDialog.show();
|
|
|
|
function saveChanges() {
|
|
storageManager.save();
|
|
unsaved = false;
|
|
saveButton.classList.remove("pulse-red");
|
|
}
|
|
|
|
function unsavedChanges() {
|
|
if (!unsaved) {
|
|
unsaved = true;
|
|
saveButton.classList.add("pulse-red");
|
|
}
|
|
}
|
|
|
|
async function editInstance(instance: Instance) {
|
|
const data = dialogDetailsFromInstance(instance);
|
|
const newData = await instanceDetailsDialog.present(data);
|
|
dialogDetailsToInstance(newData, instance);
|
|
updateInstanceList();
|
|
unsavedChanges();
|
|
}
|
|
|
|
function deleteInstance(instance: Instance) {
|
|
storageManager.storage.instances.splice(
|
|
storageManager.storage.instances.indexOf(instance),
|
|
1
|
|
);
|
|
updateInstanceList();
|
|
unsavedChanges();
|
|
}
|
|
|
|
function updateInstanceList() {
|
|
instanceList.replaceChildren(); // Erase all child nodes
|
|
instanceList.style.listStyleType = reordering ? "\"≡ \"" : "disc";
|
|
for (let n = 0; n < storageManager.storage.instances.length; n++) {
|
|
const instance = storageManager.storage.instances[n];
|
|
const li = document.createElement("li");
|
|
li.setAttribute("x-option", n.toString());
|
|
const label = document.createElement("label");
|
|
label.htmlFor = instance.origin;
|
|
label.innerText = instance.name + " ";
|
|
label.style.cursor = "inherit";
|
|
if (instance.iconURL) {
|
|
const img = new Image();
|
|
img.src = instance.iconURL;
|
|
img.alt = `${instance.name} icon`;
|
|
img.className = "inlineIcon medium-height";
|
|
label.append(img, " ");
|
|
}
|
|
if (reordering) {
|
|
li.draggable = true;
|
|
li.addEventListener("dragstart", e => {
|
|
if (e.dataTransfer === null) return;
|
|
if (!(e.target instanceof HTMLLIElement)) return;
|
|
e.dataTransfer.effectAllowed = "move";
|
|
e.dataTransfer.setData("text/plain", "");
|
|
elementBeingDragged = e.target;
|
|
});
|
|
li.addEventListener("dragover", e => {
|
|
if (elementBeingDragged === undefined) return;
|
|
if (!(e.target instanceof HTMLElement)) return;
|
|
const listElement = e.target.closest("li");
|
|
if (listElement === null) return;
|
|
if (listElement.parentNode === null) return;
|
|
if (isBefore(elementBeingDragged, listElement))
|
|
listElement.parentNode.insertBefore(elementBeingDragged, listElement);
|
|
else
|
|
listElement.parentNode.insertBefore(elementBeingDragged, listElement.nextSibling);
|
|
e.preventDefault();
|
|
});
|
|
li.addEventListener("dragenter", e => e.preventDefault());
|
|
li.style.cursor = "grab";
|
|
} else {
|
|
const editLink = document.createElement("a");
|
|
editLink.innerText = `Edit`;
|
|
editLink.href = "#";
|
|
editLink.addEventListener("click", e => editInstance(instance));
|
|
const deleteLink = document.createElement("a");
|
|
deleteLink.innerText = `Delete`;
|
|
deleteLink.href = "#";
|
|
deleteLink.addEventListener("click", e => deleteInstance(instance));
|
|
label.append(editLink, " ", deleteLink);
|
|
}
|
|
li.appendChild(label);
|
|
instanceList.appendChild(li);
|
|
}
|
|
}
|
|
|
|
function isBefore(el1: HTMLLIElement, el2: HTMLLIElement) {
|
|
if (el2.parentNode === el1.parentNode)
|
|
for (let cur = el1.previousSibling; cur && cur.nodeType !== 9; cur = cur.previousSibling)
|
|
if (cur === el2)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
function applyReordering() {
|
|
const indices: number[] = [];
|
|
for (const el of instanceList.children) {
|
|
if (!(el instanceof HTMLLIElement)) continue;
|
|
const option = el.getAttribute("x-option");
|
|
if (option === null) continue;
|
|
indices.push(parseInt(option));
|
|
}
|
|
storageManager.storage.instances = indices.map(i => storageManager.storage.instances[i]);
|
|
unsavedChanges();
|
|
}
|