Editing & saving changes & fixes
This commit is contained in:
parent
f451b1fbc3
commit
7e1416a721
5 changed files with 75 additions and 30 deletions
|
@ -1,5 +1,5 @@
|
|||
import { AddInstanceDialog } from "./add_an_instance.mjs";
|
||||
import { InstanceDetailsDialog, InstanceDetailsDialogData } from "./confirm_instance_details.mjs";
|
||||
import { dialogDetailsToInstance, InstanceDetailsDialog, InstanceDetailsDialogData } from "./confirm_instance_details.mjs";
|
||||
import { Dialog } from "./dialog.mjs";
|
||||
import storageManager, { Instance } from "./storage_manager.mjs";
|
||||
|
||||
|
@ -26,14 +26,14 @@ export class AddInstanceFlow {
|
|||
this.detailsDialog = new InstanceDetailsDialog(detailsDialog, true);
|
||||
}
|
||||
|
||||
async start() {
|
||||
async start(autoSave: boolean) {
|
||||
const {
|
||||
autoQueryMetadata,
|
||||
host,
|
||||
secure,
|
||||
} = await this.addDialog.present();
|
||||
|
||||
let detailsDialogData: InstanceDetailsDialogData = {
|
||||
const detailsDialogData: InstanceDetailsDialogData = {
|
||||
name: host,
|
||||
host,
|
||||
hostSecure: secure,
|
||||
|
@ -62,17 +62,11 @@ export class AddInstanceFlow {
|
|||
} catch { }
|
||||
this.spinnerDialog.close();
|
||||
|
||||
detailsDialogData = await this.detailsDialog.present(detailsDialogData);
|
||||
|
||||
const instance: Instance = {
|
||||
name: detailsDialogData.name,
|
||||
origin: `http${detailsDialogData.hostSecure ? "s" : ""}://${detailsDialogData.host}`,
|
||||
software: detailsDialogData.software,
|
||||
iconURL: detailsDialogData.iconURL ?? undefined
|
||||
};
|
||||
const finalData = await this.detailsDialog.present(detailsDialogData);
|
||||
const instance = dialogDetailsToInstance(finalData, {});
|
||||
|
||||
storageManager.storage.instances.push(instance);
|
||||
storageManager.save();
|
||||
if (autoSave) storageManager.save();
|
||||
console.log("Successfully added new instance:", instance);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { parseHost } from "./add_an_instance.mjs";
|
||||
import { AddInstanceFlow } from "./add_instance_flow.mjs";
|
||||
import { InstanceDetailsDialog } from "./confirm_instance_details.mjs";
|
||||
import { dialogDetailsFromInstance, dialogDetailsToInstance, InstanceDetailsDialog, InstanceDetailsDialogData } from "./confirm_instance_details.mjs";
|
||||
import { findButtonOrFail, findDialogOrFail, findOlOrFail } from "./dom.mjs";
|
||||
import storageManager from "./storage_manager.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;
|
||||
|
||||
|
@ -20,12 +21,12 @@ const reorderButton = findButtonOrFail(document.body, "#reorder");
|
|||
let instanceDetailsDialog = new InstanceDetailsDialog(detailsDialog, true);
|
||||
let addInstanceFlow = new AddInstanceFlow(addDialog, spinnerDialog, instanceDetailsDialog);
|
||||
|
||||
startAddInstanceFlowButton.addEventListener("click", e => addInstanceFlow.start());
|
||||
|
||||
saveButton.addEventListener("click", e => {
|
||||
storageManager.save();
|
||||
startAddInstanceFlowButton.addEventListener("click", e => {
|
||||
addInstanceFlow.start(false).then(_ => unsavedChanges());
|
||||
});
|
||||
|
||||
saveButton.addEventListener("click", e => saveChanges());
|
||||
|
||||
reorderButton.addEventListener("click", () => {
|
||||
reordering = !reordering;
|
||||
if (!reordering) applyReordering();
|
||||
|
@ -38,6 +39,26 @@ 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);
|
||||
unsavedChanges();
|
||||
}
|
||||
|
||||
function updateInstanceList() {
|
||||
instanceList.replaceChildren(); // Erase all child nodes
|
||||
instanceList.style.listStyleType = reordering ? "\"≡ \"" : "disc";
|
||||
|
@ -83,17 +104,7 @@ function updateInstanceList() {
|
|||
const editLink = document.createElement("a");
|
||||
editLink.innerText = `Edit`;
|
||||
editLink.href = "#";
|
||||
editLink.addEventListener("click", e => {
|
||||
const host = parseHost(instance.origin)!;
|
||||
populateInstanceDetailsDialog(
|
||||
instance.name,
|
||||
host.host,
|
||||
host.secure,
|
||||
instance.software,
|
||||
instance.iconURL ?? null
|
||||
);
|
||||
showInstanceDetailsDialog();
|
||||
});
|
||||
editLink.addEventListener("click", e => editInstance(instance));
|
||||
const deleteLink = document.createElement("a");
|
||||
deleteLink.innerText = `Delete`;
|
||||
deleteLink.href = "#";
|
||||
|
@ -127,4 +138,5 @@ function applyReordering() {
|
|||
indices.push(parseInt(option));
|
||||
}
|
||||
storageManager.storage.instances = indices.map(i => storageManager.storage.instances[i]);
|
||||
unsavedChanges();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
// This file handles the "Confirm instance details" dialog
|
||||
|
||||
import { parseHost } from "./add_an_instance.mjs";
|
||||
import { FormDialog, ONCE } from "./dialog.mjs";
|
||||
import { findButtonOrFail, findFormOrFail, findImageOrFail, findInputOrFail, findSelectOrFail } from "./dom.mjs";
|
||||
import knownSoftware from "./known_software.mjs";
|
||||
import { Instance } from "./storage_manager.mjs";
|
||||
|
||||
const blankImage = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
||||
|
||||
export function mergeHost(host: string, secure: boolean): string {
|
||||
return `http${secure ? "s" : ""}://${host}`;
|
||||
}
|
||||
|
||||
export type InstanceDetailsDialogData = {
|
||||
name: string,
|
||||
host: string,
|
||||
|
@ -14,6 +20,25 @@ export type InstanceDetailsDialogData = {
|
|||
iconURL: string | null
|
||||
};
|
||||
|
||||
export function dialogDetailsFromInstance(instance: Instance): InstanceDetailsDialogData {
|
||||
const host = parseHost(instance.origin)!;
|
||||
return {
|
||||
name: instance.name,
|
||||
host: host.host,
|
||||
hostSecure: host.secure,
|
||||
software: instance.software,
|
||||
iconURL: instance.iconURL ?? null
|
||||
};
|
||||
}
|
||||
|
||||
export function dialogDetailsToInstance(data: InstanceDetailsDialogData, instance: Partial<Instance>): Instance {
|
||||
instance.name = data.name;
|
||||
instance.origin = mergeHost(data.host, data.hostSecure);
|
||||
instance.software = data.software;
|
||||
instance.iconURL = data.iconURL ?? undefined;
|
||||
return instance as Instance;
|
||||
}
|
||||
|
||||
export class InstanceDetailsDialog extends FormDialog {
|
||||
protected instanceName: HTMLInputElement;
|
||||
protected instanceHost: HTMLInputElement;
|
||||
|
|
|
@ -31,7 +31,7 @@ if (!autoRedirect()) {
|
|||
mainDialog.show();
|
||||
};
|
||||
|
||||
startAddInstanceFlowButton.addEventListener("click", e => addInstanceFlow?.start());
|
||||
startAddInstanceFlowButton.addEventListener("click", e => addInstanceFlow?.start(true));
|
||||
|
||||
redirectButton.addEventListener("click", e => {
|
||||
// Can be assumed to not fail because the button is disabled if there are no options and the first one is selected by default
|
||||
|
|
|
@ -184,4 +184,18 @@ abbr[title] {
|
|||
|
||||
.buttonPanel>* {
|
||||
margin-top: min(var(--xl), 6vh);
|
||||
}
|
||||
|
||||
.pulse-red {
|
||||
animation: 1s ease-in-out 0s infinite alternate both running pulse-red-anim;
|
||||
}
|
||||
|
||||
@keyframes pulse-red-anim {
|
||||
0% {
|
||||
box-shadow: 0px 0px 0px var(--red);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: 0px 0px 20px var(--red);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue