"use strict"; import * as USIMP from "usimp"; export class App { account: USIMP.Account | null; defaultLocation: string; main: HTMLElement; windows: HTMLElement; session: USIMP.Session | null; constructor() { this.defaultLocation = '/welcome'; this.account = null; this.session = null; const main = document.getElementsByTagName("main")[0]; if (!main) throw Error("Element
not found"); this.main = main; const windows = document.getElementById("windows"); if (!windows) throw Error("Element #windows not found"); this.windows = windows; window.addEventListener("hashchange", event => { this.handleUrl(event.newURL); }); this.handleUrl(document.URL); } setHash(hash: string) { const url = new URL(document.URL); url.hash = hash; location.href = url.toString(); } handleUrl(url: string) { this.handleHash(new URL(url).hash); } handleHash(hash: string) { if (hash[0] === '#') hash = hash.substr(1); const defaultCase = () => { history.replaceState(null, document.title, `#${this.defaultLocation}`); this.handleHash(this.defaultLocation); } switch (hash) { case "/": if (!this.session) { return defaultCase(); } this.hideWindows(); this.showMain(); this.removeAllWindows(); this.setupMain(); break; case "/welcome": this.hideMain(); this.showWindows(); this.removeAllWindows(); this.addWelcomeWindow(); break; case "/login": if (this.session) { return defaultCase(); } this.hideMain(); this.showWindows(); this.removeAllWindows(); this.addLoginWindow(); break; default: console.warn(`Invalid url hash #${hash}`); return defaultCase(); } } async login(accountName: string, domainName: string, password: string) { let domain; try { domain = await USIMP.Domain.fromName(domainName); } catch (error) { if (error instanceof DOMException) { throw Error("Connection timed out"); } else { throw Error("Invalid USIMP domain"); } } const session = new USIMP.Session(domain); const rtt = await session.chooseDomainServer(); console.log(rtt); const response = await session.authenticate(accountName, password); if (response.status === "success") { this.session = session; this.defaultLocation = "/"; this.setHash("/"); } else { throw Error(response.message); } } hideMain() { this.main.style.visibility = "hidden"; } showMain() { this.main.style.visibility = "visible"; } hideWindows() { this.windows.style.visibility = "hidden"; } showWindows() { this.windows.style.visibility = "visible"; } removeAllWindows() { while (this.windows.lastChild) this.windows.removeChild(this.windows.lastChild); } addWelcomeWindow() { const win = document.createElement("div"); win.classList.add("window-welcome"); win.innerHTML = `

Welcome to Locutus!

Login`; this.windows.appendChild(win); } addMessage(message: string) { const msg = document.createElement("div"); msg.classList.add("message"); msg.innerText = message; const chat = this.main.getElementsByClassName("chat-history")[0]; if (!chat) throw Error("Element .chat-history not found"); chat.appendChild(msg); chat.scrollTop = chat.scrollHeight; } addLoginWindow() { const win = document.createElement("div"); win.classList.add("window-login"); win.innerHTML = `

Login to USIMP Account

`; const form = win.getElementsByTagName("form")[0]; if (!form) throw Error("Element
not found"); form.addEventListener("submit", async event => { event.preventDefault(); for (const e of form.getElementsByTagName("button")) e.disabled = false; for (const e of form.getElementsByTagName("input")) { e.disabled = true; e.removeAttribute("invalid"); } try { try { await this.login(form['account'].value, form['domain'].value, form['password'].value); } finally { for (const d of form.getElementsByTagName("div")) form.removeChild(d); for (const e of form.getElementsByTagName("input")) e.disabled = false; for (const e of form.getElementsByTagName("button")) e.disabled = false; } } catch (error) { if (error.toString() === "Error: unable to authenticate") { const account = document.getElementsByName("account")[0]; if (account) account.setAttribute("invalid", "invalid"); } else { const domain = document.getElementsByName("domain")[0]; if (domain) domain.setAttribute("invalid", "invalid"); } const div = document.createElement("div"); div.classList.add("error"); div.innerText = error.toString(); form.appendChild(div); } }); this.windows.appendChild(win); const domain = document.getElementsByName("domain")[0]; if (!domain) throw Error("Element name=domain not found"); domain.addEventListener("input", (event) => { domain.removeAttribute("invalid"); }); const account = document.getElementsByName("account")[0]; if (!account) throw Error("Element name=account not found"); account.addEventListener("input", (event) => { account.removeAttribute("invalid"); }); account.focus(); } setupMain() { if (!this.session) throw Error("Invalid state"); this.main.innerHTML = `
`; const input = document.getElementsByTagName("input")[0]; if (!input) throw Error("Element not found"); input.addEventListener("keyup", async event => { if (event.key === "Enter" && input.value.length > 0) { if (!this.session) throw Error("No session found"); this.addMessage(input.value); const val = input.value; input.value = ""; await this.session.sendEvent("60nc0XXDIYUh6QzX4p0rMpCdzDmxghZLZk8dLuQh628", { message: val, }); } }); this.session.subscribe(response => { this.addMessage(response.data.event.data.message); }); } }