FeDirect/static/confirm_instance_details.mts

102 lines
3.7 KiB
TypeScript
Raw Permalink Normal View History

2025-01-14 10:49:44 +01:00
// This file handles the "Confirm instance details" dialog
2025-02-03 19:00:15 +01:00
import { parseHost } from "./add_an_instance.mjs";
import { FormDialog, ONCE } from "./dialog.mjs";
2025-01-14 14:52:31 +01:00
import { findButtonOrFail, findFormOrFail, findImageOrFail, findInputOrFail, findSelectOrFail } from "./dom.mjs";
2025-01-14 10:49:44 +01:00
import knownSoftware from "./known_software.mjs";
2025-02-03 19:00:15 +01:00
import { Instance } from "./storage_manager.mjs";
2025-01-14 10:49:44 +01:00
const blankImage = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
2025-02-03 19:00:15 +01:00
export function mergeHost(host: string, secure: boolean): string {
return `http${secure ? "s" : ""}://${host}`;
}
export type InstanceDetailsDialogData = {
name: string,
host: string,
hostSecure: boolean,
software: string,
iconURL: string | null
};
2025-01-14 10:49:44 +01:00
2025-02-03 19:00:15 +01:00
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;
protected instanceHostSecure: HTMLInputElement;
protected instanceSoftware: HTMLSelectElement;
protected instanceIcon: HTMLImageElement;
protected closeButton: HTMLButtonElement;
2025-01-14 10:49:44 +01:00
constructor(dialog: HTMLDialogElement, initializeDOM: boolean = true) {
super(dialog, findFormOrFail(dialog, ".instanceDetailsForm"));
this.instanceName = findInputOrFail(this.form, "#instanceName");
this.instanceHost = findInputOrFail(this.form, "#instanceHost");
this.instanceHostSecure = findInputOrFail(this.form, "#instanceHostSecure");
this.instanceSoftware = findSelectOrFail(this.form, "#instanceSoftware");
this.instanceIcon = findImageOrFail(this.form, "#instanceIcon");
this.closeButton = findButtonOrFail(this.form, ".close");
if (initializeDOM) this.initializeDOM();
2025-01-14 10:49:44 +01:00
}
protected override initializeDOM() {
super.initializeDOM();
2025-01-14 10:49:44 +01:00
for (const [name, software] of Object.entries(knownSoftware.software)) {
const option = new Option(software.name, name);
this.instanceSoftware.appendChild(option);
}
2025-01-14 10:49:44 +01:00
this.instanceIcon.src = blankImage;
2025-01-14 10:49:44 +01:00
this.closeButton.addEventListener("click", e => this.close());
}
2025-01-14 10:49:44 +01:00
#handleSubmit(data: InstanceDetailsDialogData, resolve: (data: InstanceDetailsDialogData) => void) {
this.form.addEventListener("submit", e => {
data.name = this.instanceName.value;
data.host = this.instanceHost.value;
data.hostSecure = this.instanceHostSecure.checked;
data.software = this.instanceSoftware.value;
2025-02-03 20:07:19 +01:00
resolve(data);
this.close();
}, ONCE);
}
async present(data: InstanceDetailsDialogData): Promise<InstanceDetailsDialogData> {
this.instanceName.value = data.name;
this.instanceHost.value = data.host;
this.instanceHostSecure.checked = data.hostSecure;
this.instanceSoftware.value = data.software;
this.instanceIcon.src = data.iconURL ?? blankImage;
return new Promise((resolve, reject) => {
this.cancelOnceClosed(reject);
this.#handleSubmit(data, resolve);
this.open();
});
}
2025-01-14 10:49:44 +01:00
}