diff --git a/static/add_instance_flow.mts b/static/add_instance_flow.mts new file mode 100644 index 0000000..14ac6f7 --- /dev/null +++ b/static/add_instance_flow.mts @@ -0,0 +1,69 @@ +import { initializeAddInstanceDialog } from "./add_an_instance.mjs"; +import { initializeInstanceDetailsDialog } from "./confirm_instance_details.mjs"; +import storageManager, { Instance } from "./storage_manager.mjs"; + +export function initializeAddInstanceFlow( + detailsDialog: HTMLDialogElement, + addDialog: HTMLDialogElement +): { + showAddInstanceDialog: () => void, + hideAddInstanceDialog: () => void +} { + const instanceDetailsDialogCallback = ( + name: string, + host: string, + hostSecure: boolean, + software: string, + icon: string | null + ) => { + const instance: Instance = { + name, + origin: `http${hostSecure ? "s" : ""}://${host}`, + software, + iconURL: icon ?? undefined + }; + storageManager.storage.instances.push(instance); + storageManager.save(); + console.log("Successfully added new instance:", instance); + }; + + const { + showInstanceDetailsDialog, + hideInstanceDetailsDialog, + populateInstanceDetailsDialog + } = initializeInstanceDetailsDialog(detailsDialog, instanceDetailsDialogCallback); + + const addInstanceDialogCallback = async ( + host: string, + secure: boolean, + autoQueryMetadata: boolean, + ) => { + try { + if (!autoQueryMetadata) throw new Error("Don't"); + const { name, software, iconURL } = + await fetch(`/api/instance_info/${secure}/${encodeURIComponent(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); + } catch { + populateInstanceDetailsDialog("", host, secure, "", null); + } finally { + showInstanceDetailsDialog(); + } + } + + const { + showAddInstanceDialog, + hideAddInstanceDialog + } = initializeAddInstanceDialog(addDialog, addInstanceDialogCallback); + + return { + showAddInstanceDialog, + hideAddInstanceDialog + }; +} diff --git a/static/crossroad.mts b/static/crossroad.mts index 852b3e0..8d212c4 100644 --- a/static/crossroad.mts +++ b/static/crossroad.mts @@ -1,70 +1,14 @@ -import { initializeAddInstanceDialog } from "./add_an_instance.mjs"; -import { initializeInstanceDetailsDialog } from "./confirm_instance_details.mjs"; -import knownSoftware from "./known_software.mjs"; -import storageManager, { Instance } from "./storage_manager.mjs"; -console.log(knownSoftware); - -console.log(storageManager.storage.instances); +import { initializeAddInstanceFlow } from "./add_instance_flow.mjs"; +import { findDialogOrFail } from "./dom.mjs"; export function getMainDialog(): HTMLDialogElement { return document.getElementById('mainDialog') as HTMLDialogElement; } -const instanceDetailsDialogCallback = ( - name: string, - host: string, - hostSecure: boolean, - software: string, - icon: string | null -) => { - const instance: Instance = { - name, - origin: `http${hostSecure ? "s" : ""}://${host}`, - software, - iconURL: icon ?? undefined - }; - storageManager.storage.instances.push(instance); - storageManager.save(); - console.log("Successfully added new instance:", instance); -}; +const detailsDialog = findDialogOrFail(document.body, "#instanceDetails"); +const addDialog = findDialogOrFail(document.body, "#addInstance"); -const detailsDialog = document.querySelector("#instanceDetails"); -if (!(detailsDialog instanceof HTMLDialogElement)) - throw new Error("Couldn't find instanceDetails dialog"); -export const { - showInstanceDetailsDialog, - hideInstanceDetailsDialog, - populateInstanceDetailsDialog -} = initializeInstanceDetailsDialog(detailsDialog, instanceDetailsDialogCallback); - -const addInstanceDialogCallback = async ( - host: string, - secure: boolean, - autoQueryMetadata: boolean, -) => { - try { - if (!autoQueryMetadata) throw new Error("Don't"); - const { name, software, iconURL } = - await fetch(`/api/instance_info/${secure}/${encodeURIComponent(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); - } catch { - populateInstanceDetailsDialog("", host, secure, "", null); - } finally { - showInstanceDetailsDialog(); - } -} - -const addDialog = document.querySelector("#addInstance"); -if (!(addDialog instanceof HTMLDialogElement)) - throw new Error("Couldn't find addInstance dialog"); export const { showAddInstanceDialog, hideAddInstanceDialog -} = initializeAddInstanceDialog(addDialog, addInstanceDialogCallback); +} = initializeAddInstanceFlow(detailsDialog, addDialog); diff --git a/static/dom.mts b/static/dom.mts index 0d013fa..7a7aff5 100644 --- a/static/dom.mts +++ b/static/dom.mts @@ -1,6 +1,13 @@ // I would've LOVED to use generics for this but unfortunately that's not possible. // Type safety, but at what cost... >~< thanks TypeScript +export function findDialogOrFail(on: Element, selector: string): HTMLDialogElement { + const element = on.querySelector(selector); + if (!(element instanceof HTMLDialogElement)) + throw new Error(`${selector} isn't a dialog`); + return element; +} + export function findFormOrFail(on: Element, selector: string): HTMLFormElement { const element = on.querySelector(selector); if (!(element instanceof HTMLFormElement))