FeDirect/static/add_an_instance.mts

80 lines
2.7 KiB
TypeScript
Raw Normal View History

// This file handles the "Add an instance" dialog
import { FormDialog, ONCE } from "./dialog.mjs";
2025-01-14 14:52:31 +01:00
import { findButtonOrFail, findFormOrFail, findInputOrFail } from "./dom.mjs";
export function parseHost(host: string): { host: string, secure: boolean } | null {
let parsedInstance = URL.parse(host);
parsedInstance ??= URL.parse("https://" + host);
if (!parsedInstance?.host) return null;
2025-01-14 13:10:29 +01:00
if (!/https?:/.test(parsedInstance.protocol)) return null;
return {
host: parsedInstance.host,
secure: parsedInstance.protocol === "https:"
};
}
type AddInstanceDialogData = {
host: string,
secure: boolean,
autoQueryMetadata: boolean,
};
export class AddInstanceDialog extends FormDialog {
protected instanceHost: HTMLInputElement;
protected autoQueryMetadata: HTMLInputElement;
protected closeButton: HTMLButtonElement;
constructor(dialog: HTMLDialogElement, initializeDOM: boolean = true) {
super(dialog, findFormOrFail(dialog, ".addInstanceForm"));
this.instanceHost = findInputOrFail(this.form, "#instanceHost");
this.autoQueryMetadata = findInputOrFail(this.form, "#autoQueryMetadata");
this.closeButton = findButtonOrFail(this.form, ".close");
if (initializeDOM) this.initializeDOM();
}
#getDataIfValid(): AddInstanceDialogData | null {
const parsedHost = parseHost(this.instanceHost.value);
if (parsedHost === null) {
this.instanceHost.setCustomValidity("Invalid instance hostname or URL");
return null;
}
this.instanceHost.setCustomValidity("");
return {
host: parsedHost.host,
secure: parsedHost.secure,
autoQueryMetadata: this.autoQueryMetadata.checked
};
}
#handleSubmit(resolve: (data: AddInstanceDialogData) => void) {
this.form.addEventListener("submit", e => {
const data = this.#getDataIfValid();
if (data === null) {
// Prevent the user from submitting the form if it's invalid and let them try again
e.preventDefault();
this.#handleSubmit(resolve);
return;
}
resolve(data);
this.close();
}, ONCE);
}
protected override initializeDOM() {
super.initializeDOM();
this.instanceHost.addEventListener("input", e => this.#getDataIfValid());
this.closeButton.addEventListener("click", e => this.close());
}
async prompt(): Promise<AddInstanceDialogData> {
return new Promise((resolve, reject) => {
this.dialog.addEventListener("close", e => reject(), ONCE);
this.#handleSubmit(resolve);
this.open();
});
}
}