diff --git a/static/add_an_instance.mts b/static/add_an_instance.mts index 5503dc1..44af221 100644 --- a/static/add_an_instance.mts +++ b/static/add_an_instance.mts @@ -4,6 +4,7 @@ export function parseHost(host: string): { host: string, secure: boolean } | nul 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:" diff --git a/static/confirm_instance_details.mts b/static/confirm_instance_details.mts index 0a19609..889f891 100644 --- a/static/confirm_instance_details.mts +++ b/static/confirm_instance_details.mts @@ -9,6 +9,8 @@ export function initializeInstanceDetailsDialog(dialog: HTMLDialogElement): { hideInstanceDetailsDialog: () => void, populateInstanceDetailsDialog: ( instanceNameValue: string, + instanceHostValue: string, + instanceHostSecureValue: boolean, instanceSoftwareValue: string, instanceIconValue: string | null ) => void, @@ -24,6 +26,14 @@ export function initializeInstanceDetailsDialog(dialog: HTMLDialogElement): { if (!(instanceName instanceof HTMLInputElement)) throw new Error("#instanceName isn't an input"); + const instanceHost = form.querySelector("#instanceHost"); + if (!(instanceHost instanceof HTMLInputElement)) + throw new Error("#instanceHost isn't an input"); + + const instanceHostSecure = form.querySelector("#instanceHostSecure"); + if (!(instanceHostSecure instanceof HTMLInputElement)) + throw new Error("#instanceHostSecure isn't an input"); + const instanceSoftware = form.querySelector("#instanceSoftware"); if (!(instanceSoftware instanceof HTMLSelectElement)) throw new Error("#instanceSoftware isn't a select"); @@ -41,12 +51,17 @@ export function initializeInstanceDetailsDialog(dialog: HTMLDialogElement): { const populateInstanceDetailsDialog = ( instanceNameValue: string, + instanceHostValue: string, + instanceHostSecureValue: boolean, instanceSoftwareValue: string, instanceIconValue: string | null ) => { instanceName.value = instanceNameValue; + instanceHost.value = instanceHostValue; + instanceHostSecure.checked = instanceHostSecureValue; instanceSoftware.value = instanceSoftwareValue; instanceIcon.src = instanceIconValue ?? blankImage; + }; form.addEventListener("submit", e => { diff --git a/static/crossroad.html b/static/crossroad.html index 7dd8312..e6a32d6 100644 --- a/static/crossroad.html +++ b/static/crossroad.html @@ -65,7 +65,19 @@ We do not track or save any requests or data.">

- + +

+ +
+ +
+ +


diff --git a/static/crossroad.mts b/static/crossroad.mts index 0585374..7f3dffb 100644 --- a/static/crossroad.mts +++ b/static/crossroad.mts @@ -24,21 +24,22 @@ const addInstanceDialogCallback = async ( secure: boolean, autoQueryMetadata: boolean, ) => { - if (!autoQueryMetadata) { + try { + if (!autoQueryMetadata) throw new Error("Don't"); + const { name, software, iconURL } = + await fetch(`/api/instance_info/${secure}/${encodeURI(host)}`) + .then(r => r.json()); + if ( + typeof name !== "string" + || typeof software !== "string" + || !(typeof iconURL === "string" || iconURL === null) + ) + throw new Error("Invalid API response"); + populateInstanceDetailsDialog(name, host, secure, software, iconURL as string | null); + } finally { + populateInstanceDetailsDialog("", host, secure, "", null); showInstanceDetailsDialog(); - return; } - const { name, software, iconURL } = - await fetch(`/api/instance_info/${secure}/${encodeURI(host)}`) - .then(r => r.json()); - if ( - typeof name !== "string" - || typeof software !== "string" - || !(typeof iconURL === "string" || iconURL === null) - ) - throw new Error("Invalid API response"); - populateInstanceDetailsDialog(name, software, iconURL as string | null); - showInstanceDetailsDialog(); } const addDialog = document.querySelector("#addInstance"); diff --git a/static/image.mts b/static/image.mts new file mode 100644 index 0000000..e85e407 --- /dev/null +++ b/static/image.mts @@ -0,0 +1,15 @@ +export function resize(image: HTMLImageElement, width: number = 16, height: number = 16): string { + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + canvas.style.display = "none"; + document.body.appendChild(canvas); + const ctx = canvas.getContext("2d"); + if (ctx === null) throw Error("Resize failed"); + const w = Math.min(image.width / image.height, 1) * width; + const h = Math.min(image.height / image.width, 1) * height; + ctx.drawImage(image, (width - w) / 2, (height - h) / 2, w, h); + const url = canvas.toDataURL(); + document.body.removeChild(canvas); + return url; +} \ No newline at end of file