80 lines
2.7 KiB
TypeScript
80 lines
2.7 KiB
TypeScript
// This file handles the "Add an instance" dialog
|
|
|
|
import { FormDialog, ONCE } from "./dialog.mjs";
|
|
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;
|
|
if (!/https?:/.test(parsedInstance.protocol)) return null;
|
|
return {
|
|
host: parsedInstance.host,
|
|
secure: parsedInstance.protocol === "https:"
|
|
};
|
|
}
|
|
|
|
export 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();
|
|
}
|
|
|
|
protected override initializeDOM() {
|
|
super.initializeDOM();
|
|
|
|
this.instanceHost.addEventListener("input", e => this.#getDataIfValid());
|
|
this.closeButton.addEventListener("click", e => this.close());
|
|
}
|
|
|
|
#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);
|
|
}
|
|
|
|
async present(): Promise<AddInstanceDialogData> {
|
|
return new Promise((resolve, reject) => {
|
|
this.cancelOnceClosed(reject);
|
|
this.#handleSubmit(resolve);
|
|
this.open();
|
|
});
|
|
}
|
|
}
|