// 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, hostSecure: boolean, software: string, 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.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; 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(); } protected override initializeDOM() { super.initializeDOM(); for (const [name, software] of Object.entries(knownSoftware.software)) { const option = new Option(software.name, name); this.instanceSoftware.appendChild(option); } this.instanceIcon.src = blankImage; this.closeButton.addEventListener("click", e => this.close()); } #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; resolve(data); this.close(); }, ONCE); } async present(data: InstanceDetailsDialogData): Promise { 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(); }); } }