diff --git a/build.ts b/build.ts index ca89f19..6007528 100644 --- a/build.ts +++ b/build.ts @@ -18,6 +18,12 @@ if (urlMaybe && URL.canParse(urlMaybe)) { } let entryPoints: {sPath: string; newPath: string}[] = []; async function bundleFiles() { + const filter = new Set(); + entryPoints = entryPoints.filter((_) => { + if (filter.has(_.sPath)) return false; + filter.add(_.sPath); + return true; + }); let mod = await swc.bundle( entryPoints.map(({sPath}) => { return { diff --git a/src/webpage/404.html b/src/webpage/404.html index 2ec8a3c..1c77c2e 100644 --- a/src/webpage/404.html +++ b/src/webpage/404.html @@ -1,6 +1,7 @@ + It seems you're lost @@ -49,6 +50,6 @@ - + diff --git a/src/webpage/404.ts b/src/webpage/404.ts index c84aae0..c1f941c 100644 --- a/src/webpage/404.ts +++ b/src/webpage/404.ts @@ -1,37 +1,38 @@ import {I18n} from "./i18n"; import {setTheme, SW} from "./utils/utils"; +if (document.getElementById("404-page")) { + await setTheme(); + await I18n.done; + I18n.translatePage(); -await setTheme(); -await I18n.done; -I18n.translatePage(); + const easterEvents = [ + () => { + window.open("https://youtube.com/watch?v=dQw4w9WgXcQ"); + }, + () => { + window.open("https://youtube.com/watch?v=fC7oUOUEEi4"); + }, + () => { + alert(I18n[404].whatelse()); + }, + ]; -const easterEvents = [ - () => { - window.open("https://youtube.com/watch?v=dQw4w9WgXcQ"); - }, - () => { - window.open("https://youtube.com/watch?v=fC7oUOUEEi4"); - }, - () => { - alert(I18n[404].whatelse()); - }, -]; + const where = document.getElementById("whereever"); + if (where) { + where.onclick = () => { + const event = easterEvents[Math.floor(Math.random() * easterEvents.length)]; + event(); + }; + } + while (true) { + await new Promise((res) => setTimeout(res, 100)); -const where = document.getElementById("whereever"); -if (where) { - where.onclick = () => { - const event = easterEvents[Math.floor(Math.random() * easterEvents.length)]; - event(); - }; -} -while (true) { - await new Promise((res) => setTimeout(res, 100)); - - if (SW.worker) { - const valid = await SW.isValid(window.location.href); - if (valid) { - window.location.reload(); + if (SW.worker) { + const valid = await SW.isValid(window.location.href); + if (valid) { + window.location.reload(); + } + break; } - break; } } diff --git a/src/webpage/audio/index.html b/src/webpage/audio/index.html index 9f4932e..7dcf8bd 100644 --- a/src/webpage/audio/index.html +++ b/src/webpage/audio/index.html @@ -35,5 +35,5 @@

- + diff --git a/src/webpage/audio/page.ts b/src/webpage/audio/page.ts index 16e7f34..2f1945d 100644 --- a/src/webpage/audio/page.ts +++ b/src/webpage/audio/page.ts @@ -1,167 +1,167 @@ import {BinWrite} from "../utils/binaryUtils.js"; import {setTheme} from "../utils/utils.js"; import {Play} from "./play.js"; +if (window.location.pathname.startsWith("/audio")) { + await setTheme(); + const w = new BinWrite(2 ** 12); + w.writeStringNo("jasf"); + w.write8(4); -await setTheme(); -const w = new BinWrite(2 ** 12); -w.writeStringNo("jasf"); -w.write8(4); - -w.writeString8("sin"); -w.write32Float(0); -w.writeString8("triangle"); -w.write32Float(0); -w.writeString8("square"); -w.write32Float(0); - -w.writeString8("custom"); -w.write32Float(150); -//return Math.sin(((t + 2) ** Math.cos(t * 4)) * Math.PI * 2 * freq); -//Math.sin((((t+2)**Math.cos((t*4)))*((Math.PI*2)*f))) -w.write8(4); //sin -w.write8(5); //times -{ - w.write8(9); //Power + w.writeString8("sin"); + w.write32Float(0); + w.writeString8("triangle"); + w.write32Float(0); + w.writeString8("square"); + w.write32Float(0); + w.writeString8("custom"); + w.write32Float(150); + //return Math.sin(((t + 2) ** Math.cos(t * 4)) * Math.PI * 2 * freq); + //Math.sin((((t+2)**Math.cos((t*4)))*((Math.PI*2)*f))) + w.write8(4); //sin + w.write8(5); //times { - w.write8(6); //adding + w.write8(9); //Power + + { + w.write8(6); //adding + w.write8(1); //t + w.write8(0); + w.write32Float(2); //2 + } + w.write8(13); //cos + w.write8(5); // times w.write8(1); //t w.write8(0); - w.write32Float(2); //2 + w.write32Float(4); //4 + } + { + w.write8(5); //times + w.write8(5); //times + w.write8(3); //PI + w.write8(0); + w.write32Float(2); //2 + w.write8(2); //freq } - w.write8(13); //cos - w.write8(5); // times - w.write8(1); //t - w.write8(0); - w.write32Float(4); //4 -} -{ - w.write8(5); //times - w.write8(5); //times - w.write8(3); //PI - w.write8(0); - w.write32Float(2); //2 - w.write8(2); //freq -} -w.write16(5); //5 tracks + w.write16(5); //5 tracks -w.write16(1); //zip -w.write8(4); -w.write32Float(1); -w.write32Float(640); - -w.write16(3); //beep -{ - w.write8(1); + w.write16(1); //zip + w.write8(4); w.write32Float(1); - w.write32Float(700); - w.write32Float(50); + w.write32Float(640); - w.write8(0); - w.write32Float(100); + w.write16(3); //beep + { + w.write8(1); + w.write32Float(1); + w.write32Float(700); + w.write32Float(50); - w.write8(1); - w.write32Float(1); - w.write32Float(700); - w.write32Float(50); -} + w.write8(0); + w.write32Float(100); -w.write16(5); //three -{ - w.write8(1); - w.write32Float(1); - w.write32Float(800); - w.write32Float(50); + w.write8(1); + w.write32Float(1); + w.write32Float(700); + w.write32Float(50); + } - w.write8(0); - w.write32Float(50); + w.write16(5); //three + { + w.write8(1); + w.write32Float(1); + w.write32Float(800); + w.write32Float(50); - w.write8(1); - w.write32Float(1); - w.write32Float(1000); - w.write32Float(50); + w.write8(0); + w.write32Float(50); - w.write8(0); - w.write32Float(50); + w.write8(1); + w.write32Float(1); + w.write32Float(1000); + w.write32Float(50); - w.write8(1); - w.write32Float(1); - w.write32Float(1300); - w.write32Float(50); -} + w.write8(0); + w.write32Float(50); -w.write16(5); //square -{ - w.write8(3); - w.write32Float(1); - w.write32Float(600); - w.write32Float(50); + w.write8(1); + w.write32Float(1); + w.write32Float(1300); + w.write32Float(50); + } - w.write8(0); - w.write32Float(50); + w.write16(5); //square + { + w.write8(3); + w.write32Float(1); + w.write32Float(600); + w.write32Float(50); - w.write8(3); - w.write32Float(1); - w.write32Float(800); - w.write32Float(50); + w.write8(0); + w.write32Float(50); - w.write8(0); - w.write32Float(50); + w.write8(3); + w.write32Float(1); + w.write32Float(800); + w.write32Float(50); - w.write8(3); - w.write32Float(1); - w.write32Float(1000); - w.write32Float(50); -} -w.write16(5); //three -{ - w.write8(1); - w.write32Float(1); - w.write32Float(600); - w.write32Float(75); + w.write8(0); + w.write32Float(50); - w.write8(0); - w.write32Float(75); + w.write8(3); + w.write32Float(1); + w.write32Float(1000); + w.write32Float(50); + } + w.write16(5); //three + { + w.write8(1); + w.write32Float(1); + w.write32Float(600); + w.write32Float(75); - w.write8(1); - w.write32Float(1); - w.write32Float(800); - w.write32Float(75); + w.write8(0); + w.write32Float(75); - w.write8(0); - w.write32Float(75); + w.write8(1); + w.write32Float(1); + w.write32Float(800); + w.write32Float(75); - w.write8(1); - w.write32Float(1); - w.write32Float(1000); - w.write32Float(50); -} + w.write8(0); + w.write32Float(75); -w.write16(5); //5 audio + w.write8(1); + w.write32Float(1); + w.write32Float(1000); + w.write32Float(50); + } -w.writeString8("zip"); -w.write16(1); -w.write16(1); + w.write16(5); //5 audio -w.writeString8("beep"); -w.write16(1); -w.write16(2); + w.writeString8("zip"); + w.write16(1); + w.write16(1); -w.writeString8("three"); -w.write16(1); -w.write16(3); + w.writeString8("beep"); + w.write16(1); + w.write16(2); -w.writeString8("square"); -w.write16(1); -w.write16(4); + w.writeString8("three"); + w.write16(1); + w.write16(3); -w.writeString8("join"); -w.write16(1); -w.write16(5); -const buff = w.getBuffer(); -const play = new Play(buff); -/* + w.writeString8("square"); + w.write16(1); + w.write16(4); + + w.writeString8("join"); + w.write16(1); + w.write16(5); + const buff = w.getBuffer(); + const play = new Play(buff); + /* const zip=play.audios.get("square"); if(zip){ setInterval(()=>{ @@ -171,21 +171,22 @@ if(zip){ console.log(play.voices[3][0].info.wave) }; */ -console.log(play, buff); -document.onclick = () => { - play.play("join", 15); -}; - -const download = document.getElementById("download"); -if (download) { - download.onclick = () => { - const blob = new Blob([buff], {type: "binary"}); - const downloadUrl = URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = downloadUrl; - a.download = "sounds.jasf"; - document.body.appendChild(a); - a.click(); - URL.revokeObjectURL(downloadUrl); + console.log(play, buff); + document.onclick = () => { + play.play("join", 15); }; + + const download = document.getElementById("download"); + if (download) { + download.onclick = () => { + const blob = new Blob([buff], {type: "binary"}); + const downloadUrl = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = downloadUrl; + a.download = "sounds.jasf"; + document.body.appendChild(a); + a.click(); + URL.revokeObjectURL(downloadUrl); + }; + } } diff --git a/src/webpage/home.ts b/src/webpage/home.ts index 2a44036..ac5c695 100644 --- a/src/webpage/home.ts +++ b/src/webpage/home.ts @@ -1,196 +1,198 @@ import {I18n} from "./i18n.js"; import {makeRegister} from "./register.js"; import {mobile} from "./utils/utils.js"; -console.log(mobile); -const serverbox = document.getElementById("instancebox") as HTMLDivElement; +if (window.location.pathname === "/" || window.location.pathname.startsWith("/index")) { + console.log(mobile); + const serverbox = document.getElementById("instancebox") as HTMLDivElement; -(async () => { - await I18n.done; - const box1Items = document.getElementById("box1Items"); - I18n.translatePage(); + (async () => { + await I18n.done; + const box1Items = document.getElementById("box1Items"); + I18n.translatePage(); - if (box1Items) { - const items = I18n.htmlPages.box1Items().split("|"); - let i = 0; - //@ts-ignore ts is being dumb here - for (const item of box1Items.children) { - (item as HTMLElement).textContent = items[i]; - i++; - } - } -})(); -const recent = document.getElementById("recentBlog"); -if (recent) { - fetch("https://blog.fermi.chat/feed_json_created.json") - .then((_) => _.json()) - .then( - (json: { - items: { - url: string; - title: string; - content_html: string; - }[]; - }) => { - for (const thing of json.items.slice(0, 5)) { - const a = document.createElement("a"); - a.href = thing.url; - a.textContent = thing.title; - recent.append(a); - } - }, - ); -} -fetch("/instances.json") - .then((_) => _.json()) - .then( - async ( - json: { - name: string; - description?: string; - descriptionLong?: string; - image?: string; - url?: string; - display?: boolean; - online?: boolean; - uptime: {alltime: number; daytime: number; weektime: number}; - urls: { - wellknown: string; - api: string; - cdn: string; - gateway: string; - login?: string; - }; - }[], - ) => { - await I18n.done; - console.warn(json); - for (const instance of json) { - if (instance.display === false) { - continue; - } - const div = document.createElement("div"); - div.classList.add("flexltr", "instance"); - if (instance.image) { - const img = document.createElement("img"); - img.alt = I18n.home.icon(instance.name); - img.src = instance.image; - div.append(img); - } - const statbox = document.createElement("div"); - statbox.classList.add("flexttb", "flexgrow"); - - { - const textbox = document.createElement("div"); - textbox.classList.add("flexttb", "instancetextbox"); - const title = document.createElement("h2"); - title.innerText = instance.name; - if (instance.online !== undefined) { - const status = document.createElement("span"); - status.innerText = instance.online ? "Online" : "Offline"; - status.classList.add("instanceStatus"); - title.append(status); - } - textbox.append(title); - if (instance.description || instance.descriptionLong) { - const p = document.createElement("p"); - if (instance.descriptionLong) { - p.innerText = instance.descriptionLong; - } else if (instance.description) { - p.innerText = instance.description; - } - textbox.append(p); - } - statbox.append(textbox); - } - if (instance.uptime) { - const stats = document.createElement("div"); - stats.classList.add("flexltr"); - const span = document.createElement("span"); - span.innerText = I18n.home.uptimeStats( - Math.round(instance.uptime.alltime * 100) + "", - Math.round(instance.uptime.weektime * 100) + "", - Math.round(instance.uptime.daytime * 100) + "", - ); - stats.append(span); - statbox.append(stats); - } - div.append(statbox); - div.onclick = (_) => { - if (instance.online !== false) { - makeRegister(true, instance.name); - } else { - alert(I18n.home.warnOffiline()); - } - }; - serverbox.append(div); - } - }, - ); - -const slides = document.getElementById("ScreenshotSlides"); -if (slides) { - const images = Array.from(slides.getElementsByTagName("img")); - const left = slides.getElementsByClassName("leftArrow").item(0) as HTMLElement; - const right = slides.getElementsByClassName("rightArrow").item(0) as HTMLElement; - let index = 0; - let timeout: NodeJS.Timeout | undefined = setTimeout(() => {}); - function slideShow() { - let cleared = false; - if (timeout !== undefined) { - cleared = true; - clearTimeout(timeout); - } - let i = 0; - for (const img of images) { - if (i !== index) { - img.classList.add("hidden"); - } else { - img.classList.remove("hidden"); - } - i++; - } - const count = document.getElementById("slideCount"); - if (count) { - if (count.children.length !== images.length) { - count.innerHTML = ""; - for (let i = 0; i < images.length; i++) { - const dot = document.createElement("span"); - const outer = document.createElement("div"); - outer.onclick = () => { - index = i; - slideShow(); - }; - outer.append(dot); - count.append(outer); - } - } + if (box1Items) { + const items = I18n.htmlPages.box1Items().split("|"); let i = 0; - for (const child of Array.from(count.children)) { - if (i === index) { - child.classList.add("selected"); - } else { - child.classList.remove("selected"); - } + //@ts-ignore ts is being dumb here + for (const item of box1Items.children) { + (item as HTMLElement).textContent = items[i]; i++; } } - - timeout = setTimeout( - () => { - index = (index + 1) % images.length; - timeout = undefined; - slideShow(); - }, - cleared ? 15000 : 30000, - ); + })(); + const recent = document.getElementById("recentBlog"); + if (recent) { + fetch("https://blog.fermi.chat/feed_json_created.json") + .then((_) => _.json()) + .then( + (json: { + items: { + url: string; + title: string; + content_html: string; + }[]; + }) => { + for (const thing of json.items.slice(0, 5)) { + const a = document.createElement("a"); + a.href = thing.url; + a.textContent = thing.title; + recent.append(a); + } + }, + ); } - slideShow(); - left.onclick = () => { - index = (index - 1 + images.length) % images.length; + fetch("/instances.json") + .then((_) => _.json()) + .then( + async ( + json: { + name: string; + description?: string; + descriptionLong?: string; + image?: string; + url?: string; + display?: boolean; + online?: boolean; + uptime: {alltime: number; daytime: number; weektime: number}; + urls: { + wellknown: string; + api: string; + cdn: string; + gateway: string; + login?: string; + }; + }[], + ) => { + await I18n.done; + console.warn(json); + for (const instance of json) { + if (instance.display === false) { + continue; + } + const div = document.createElement("div"); + div.classList.add("flexltr", "instance"); + if (instance.image) { + const img = document.createElement("img"); + img.alt = I18n.home.icon(instance.name); + img.src = instance.image; + div.append(img); + } + const statbox = document.createElement("div"); + statbox.classList.add("flexttb", "flexgrow"); + + { + const textbox = document.createElement("div"); + textbox.classList.add("flexttb", "instancetextbox"); + const title = document.createElement("h2"); + title.innerText = instance.name; + if (instance.online !== undefined) { + const status = document.createElement("span"); + status.innerText = instance.online ? "Online" : "Offline"; + status.classList.add("instanceStatus"); + title.append(status); + } + textbox.append(title); + if (instance.description || instance.descriptionLong) { + const p = document.createElement("p"); + if (instance.descriptionLong) { + p.innerText = instance.descriptionLong; + } else if (instance.description) { + p.innerText = instance.description; + } + textbox.append(p); + } + statbox.append(textbox); + } + if (instance.uptime) { + const stats = document.createElement("div"); + stats.classList.add("flexltr"); + const span = document.createElement("span"); + span.innerText = I18n.home.uptimeStats( + Math.round(instance.uptime.alltime * 100) + "", + Math.round(instance.uptime.weektime * 100) + "", + Math.round(instance.uptime.daytime * 100) + "", + ); + stats.append(span); + statbox.append(stats); + } + div.append(statbox); + div.onclick = (_) => { + if (instance.online !== false) { + makeRegister(true, instance.name); + } else { + alert(I18n.home.warnOffiline()); + } + }; + serverbox.append(div); + } + }, + ); + + const slides = document.getElementById("ScreenshotSlides"); + if (slides) { + const images = Array.from(slides.getElementsByTagName("img")); + const left = slides.getElementsByClassName("leftArrow").item(0) as HTMLElement; + const right = slides.getElementsByClassName("rightArrow").item(0) as HTMLElement; + let index = 0; + let timeout: NodeJS.Timeout | undefined = setTimeout(() => {}); + function slideShow() { + let cleared = false; + if (timeout !== undefined) { + cleared = true; + clearTimeout(timeout); + } + let i = 0; + for (const img of images) { + if (i !== index) { + img.classList.add("hidden"); + } else { + img.classList.remove("hidden"); + } + i++; + } + const count = document.getElementById("slideCount"); + if (count) { + if (count.children.length !== images.length) { + count.innerHTML = ""; + for (let i = 0; i < images.length; i++) { + const dot = document.createElement("span"); + const outer = document.createElement("div"); + outer.onclick = () => { + index = i; + slideShow(); + }; + outer.append(dot); + count.append(outer); + } + } + let i = 0; + for (const child of Array.from(count.children)) { + if (i === index) { + child.classList.add("selected"); + } else { + child.classList.remove("selected"); + } + i++; + } + } + + timeout = setTimeout( + () => { + index = (index + 1) % images.length; + timeout = undefined; + slideShow(); + }, + cleared ? 15000 : 30000, + ); + } slideShow(); - }; - right.onclick = () => { - index = (index + 1) % images.length; - slideShow(); - }; + left.onclick = () => { + index = (index - 1 + images.length) % images.length; + slideShow(); + }; + right.onclick = () => { + index = (index + 1) % images.length; + slideShow(); + }; + } } diff --git a/src/webpage/index.html b/src/webpage/index.html index 1d2738c..d3eaaa5 100644 --- a/src/webpage/index.html +++ b/src/webpage/index.html @@ -105,5 +105,5 @@ - + diff --git a/src/webpage/index.ts b/src/webpage/index.ts index 62c3040..0ef673f 100644 --- a/src/webpage/index.ts +++ b/src/webpage/index.ts @@ -9,428 +9,438 @@ import {I18n} from "./i18n.js"; import "./utils/pollyfills.js"; import {makeLogin} from "./login.js"; import {Hover} from "./hover.js"; +import "./templatePage.js"; +import "./more.js"; +import "./recover.js"; +import "./home.js"; +import "./invite.js"; +import "./oauth2/auth.js"; +import "./audio/page.js"; +import "./404.js"; + if (window.location.pathname === "/app") { window.location.pathname = "/channels/@me"; } -let templateID = new URLSearchParams(window.location.search).get("templateID"); -await I18n.done; -Localuser.loadFont(); - -I18n.translatePage(); - -const userInfoElement = document.getElementById("userinfo") as HTMLDivElement; -userInfoElement.addEventListener("click", (event) => { - event.stopImmediatePropagation(); - const rect = userInfoElement.getBoundingClientRect(); - Localuser.userMenu.makemenu(rect.x, rect.top - 10 - window.innerHeight, thisUser); -}); - -const switchAccountsElement = document.getElementById("switchaccounts") as HTMLDivElement; -switchAccountsElement.addEventListener("click", async (event) => { - event.stopImmediatePropagation(); - Localuser.showAccountSwitcher(thisUser); -}); - -let thisUser: Localuser; -function regSwap(l: Localuser) { - l.onswap = (l) => { - thisUser = l; - regSwap(l); - }; - l.fileExtange = (img, html) => { - const blobArr: Blob[] = []; - const htmlArr = imagesHtml; - let i = 0; - for (const file of images) { - const img = imagesHtml.get(file); - if (!img) continue; - if (pasteImageElement.contains(img)) { - pasteImageElement.removeChild(img); - blobArr.push(images[i]); - } else { - i++; - } - } - images = img; - imagesHtml = html; - for (const file of images) { - const img = imagesHtml.get(file); - if (!img) throw new Error("Image without HTML, exiting"); - pasteImageElement.append(img); - } - return [blobArr, htmlArr]; - }; -} -const loaddesc = document.getElementById("load-desc") as HTMLSpanElement; -try { - const current = sessionStorage.getItem("currentuser") || Localuser.users.currentuser; - if (!Localuser.users.users[current]) { - thisUser = new Localuser(await new Promise((res) => makeLogin(true, "", res))); - } else { - thisUser = new Localuser(Localuser.users.users[current]); - } - - regSwap(thisUser); - thisUser.initwebsocket().then(() => { - thisUser.loaduser(); - thisUser.init(); - const loading = document.getElementById("loading") as HTMLDivElement; - loading.classList.add("doneloading"); - loading.classList.remove("loading"); - loaddesc.textContent = I18n.loaded(); - console.log("done loading"); - if (templateID) { - thisUser.passTemplateID(templateID); - } - }); -} catch (e) { - console.error(e); - loaddesc.textContent = I18n.accountNotStart(); - thisUser = new Localuser(-1); -} -//TODO move this to the channel/guild class, this is a weird spot -const menu = new Contextmenu("create rightclick"); -menu.addButton( - I18n.channel.createChannel(), - () => { - if (thisUser.lookingguild) { - thisUser.lookingguild.createchannels(); - } - }, - {visible: () => thisUser.isAdmin()}, -); - -menu.addButton( - I18n.channel.createCatagory(), - () => { - if (thisUser.lookingguild) { - thisUser.lookingguild.createcategory(); - } - }, - {visible: () => thisUser.isAdmin()}, -); -const channelw = document.getElementById("channelw"); -console.log(channelw); -if (channelw) - channelw.addEventListener("keypress", (e) => { - if (e.ctrlKey || e.altKey || e.metaKey || e.metaKey) return; - let owner = e.target as HTMLElement; - while (owner !== channelw) { - if (owner.tagName === "input" || owner.contentEditable !== "false") { - return; - } - owner = owner.parentElement as HTMLElement; - } - typebox.markdown.boxupdate(Infinity); - }); -menu.bindContextmenu(document.getElementById("channels") as HTMLDivElement); - -const pasteImageElement = document.getElementById("pasteimage") as HTMLDivElement; -let replyingTo: Message | null = null; -window.addEventListener("popstate", (e) => { - if (e.state instanceof Object) { - thisUser.goToState(e.state); - } - //console.log(e.state,"state:3") -}); -let nonceMap = new Map(); -//@ts-expect-error unused right now, not needed -function getNonce(id: string) { - const nonce = nonceMap.get(id) || Math.floor(Math.random() * 1000000000) + ""; - nonceMap.set(id, nonce); - return nonce; -} -async function handleEnter(event: KeyboardEvent): Promise { - if (event.key === "Escape") { - while (images.length) { - const elm = imagesHtml.get(images.pop() as Blob) as HTMLElement; - if (pasteImageElement.contains(elm)) pasteImageElement.removeChild(elm); - } - if (thisUser.channelfocus) { - thisUser.channelfocus?.replyingto?.div?.classList.remove("replying"); - thisUser.channelfocus.replyingto = null; - thisUser.channelfocus.makereplybox(); - } - } - if (thisUser.handleKeyUp(event)) { - return; - } - - const channel = thisUser.channelfocus; - if (!channel) return; - const content = MarkDown.gatherBoxText(typebox); - if (content === "" && event.key === "ArrowUp") { - channel.editLast(); - return; - } - channel.typingstart(); - - if (event.key === "Enter" && !event.shiftKey) { - if (!channel.canMessageRightNow()) return; - if (channel.curCommand) { - channel.submitCommand(); - return; - } - event.preventDefault(); - replyingTo = thisUser.channelfocus ? thisUser.channelfocus.replyingto : null; - if (replyingTo?.div) { - replyingTo.div.classList.remove("replying"); - } - if (thisUser.channelfocus) { - thisUser.channelfocus.replyingto = null; - thisUser.channelfocus.makereplybox(); - } - const attachments = images.filter((_) => document.contains(imagesHtml.get(_) || null)); - while (images.length) { - const elm = imagesHtml.get(images.pop() as Blob) as HTMLElement; - if (pasteImageElement.contains(elm)) pasteImageElement.removeChild(elm); - } - typebox.innerHTML = ""; - typebox.markdown.txt = []; - try { - await new Promise((mres, rej) => - channel.sendMessage( - content, - { - attachments, - embeds: [], // Add an empty array for the embeds property - replyingto: replyingTo, - sticker_ids: [], - //nonce: getNonce(channel.id), - }, - (res) => { - if (res === "Ok") { - mres(); - } else { - rej(); - } - }, - ), - ); - } catch { - images = attachments; - for (const file of images) { - const img = imagesHtml.get(file); - if (!img) continue; - pasteImageElement.append(img); - } - channel.replyingto = replyingTo; - channel.makereplybox(); - typebox.textContent = content; - typebox.markdown.txt = content.split(""); - typebox.markdown.boxupdate(Infinity); - } - nonceMap.delete(channel.id); - } -} - export interface CustomHTMLDivElement extends HTMLDivElement { markdown: MarkDown; } +if (window.location.pathname.startsWith("/channels")) { + let templateID = new URLSearchParams(window.location.search).get("templateID"); + await I18n.done; + Localuser.loadFont(); -const typebox = document.getElementById("typebox") as CustomHTMLDivElement; -const markdown = new MarkDown("", thisUser); -typebox.markdown = markdown; -typebox.addEventListener("keyup", handleEnter); -typebox.addEventListener("keydown", (event) => { - thisUser.keydown(event); - if (event.key === "Enter" && !event.shiftKey) { - event.preventDefault(); + I18n.translatePage(); + + const userInfoElement = document.getElementById("userinfo") as HTMLDivElement; + userInfoElement.addEventListener("click", (event) => { event.stopImmediatePropagation(); - } -}); -markdown.giveBox(typebox); -{ - const searchBox = document.getElementById("searchBox") as CustomHTMLDivElement; - const markdown = new MarkDown("", thisUser); - searchBox.markdown = markdown; - const searchX = document.getElementById("searchX") as HTMLElement; - searchBox.addEventListener("keydown", (event) => { - if (event.key === "Enter") { - event.preventDefault(); - thisUser.mSearch(markdown.rawString); - } + const rect = userInfoElement.getBoundingClientRect(); + Localuser.userMenu.makemenu(rect.x, rect.top - 10 - window.innerHeight, thisUser); }); - searchBox.addEventListener("keyup", () => { - if (searchBox.textContent === "") { - setTimeout(() => (searchBox.innerHTML = ""), 0); - searchX.classList.add("svg-search"); - searchX.classList.remove("svg-plainx"); - searchBox.parentElement!.classList.remove("searching"); + + const switchAccountsElement = document.getElementById("switchaccounts") as HTMLDivElement; + switchAccountsElement.addEventListener("click", async (event) => { + event.stopImmediatePropagation(); + Localuser.showAccountSwitcher(thisUser); + }); + + let thisUser: Localuser; + function regSwap(l: Localuser) { + l.onswap = (l) => { + thisUser = l; + regSwap(l); + }; + l.fileExtange = (img, html) => { + const blobArr: Blob[] = []; + const htmlArr = imagesHtml; + let i = 0; + for (const file of images) { + const img = imagesHtml.get(file); + if (!img) continue; + if (pasteImageElement.contains(img)) { + pasteImageElement.removeChild(img); + blobArr.push(images[i]); + } else { + i++; + } + } + images = img; + imagesHtml = html; + for (const file of images) { + const img = imagesHtml.get(file); + if (!img) throw new Error("Image without HTML, exiting"); + pasteImageElement.append(img); + } + return [blobArr, htmlArr]; + }; + } + const loaddesc = document.getElementById("load-desc") as HTMLSpanElement; + try { + const current = sessionStorage.getItem("currentuser") || Localuser.users.currentuser; + if (!Localuser.users.users[current]) { + thisUser = new Localuser(await new Promise((res) => makeLogin(true, "", res))); } else { - searchX.classList.remove("svg-search"); - searchX.classList.add("svg-plainx"); - searchBox.parentElement!.classList.add("searching"); + thisUser = new Localuser(Localuser.users.users[current]); } - }); - const sideContainDiv = document.getElementById("sideContainDiv") as HTMLElement; - searchBox.onclick = () => { - sideContainDiv.classList.remove("hideSearchDiv"); - }; - searchX.onclick = () => { - if (searchX.classList.contains("svg-plainx")) { - markdown.txt = []; - searchBox.innerHTML = ""; - searchX.classList.add("svg-search"); - searchBox.parentElement!.classList.remove("searching"); - searchX.classList.remove("svg-plainx"); - thisUser.mSearch(""); - } else { - searchBox.parentElement!.classList.add("searching"); + + regSwap(thisUser); + thisUser.initwebsocket().then(() => { + thisUser.loaduser(); + thisUser.init(); + const loading = document.getElementById("loading") as HTMLDivElement; + loading.classList.add("doneloading"); + loading.classList.remove("loading"); + loaddesc.textContent = I18n.loaded(); + console.log("done loading"); + if (templateID) { + thisUser.passTemplateID(templateID); + } + }); + } catch (e) { + console.error(e); + loaddesc.textContent = I18n.accountNotStart(); + thisUser = new Localuser(-1); + } + //TODO move this to the channel/guild class, this is a weird spot + const menu = new Contextmenu("create rightclick"); + menu.addButton( + I18n.channel.createChannel(), + () => { + if (thisUser.lookingguild) { + thisUser.lookingguild.createchannels(); + } + }, + {visible: () => thisUser.isAdmin()}, + ); + + menu.addButton( + I18n.channel.createCatagory(), + () => { + if (thisUser.lookingguild) { + thisUser.lookingguild.createcategory(); + } + }, + {visible: () => thisUser.isAdmin()}, + ); + const channelw = document.getElementById("channelw"); + console.log(channelw); + if (channelw) + channelw.addEventListener("keypress", (e) => { + if (e.ctrlKey || e.altKey || e.metaKey || e.metaKey) return; + let owner = e.target as HTMLElement; + while (owner !== channelw) { + if (owner.tagName === "input" || owner.contentEditable !== "false") { + return; + } + owner = owner.parentElement as HTMLElement; + } + typebox.markdown.boxupdate(Infinity); + }); + menu.bindContextmenu(document.getElementById("channels") as HTMLDivElement); + + const pasteImageElement = document.getElementById("pasteimage") as HTMLDivElement; + let replyingTo: Message | null = null; + window.addEventListener("popstate", (e) => { + if (e.state instanceof Object) { + thisUser.goToState(e.state); } - }; - - markdown.giveBox(searchBox); - markdown.setCustomBox((e) => { - const span = document.createElement("span"); - span.textContent = e.replace("\n", ""); - return span; + //console.log(e.state,"state:3") }); -} -let images: Blob[] = []; -let imagesHtml = new WeakMap(); - -document.addEventListener("paste", async (e: ClipboardEvent) => { - if (!thisUser.channelfocus) return; - if (!e.clipboardData) return; - - for (const file of Array.from(e.clipboardData.files)) { - const fileInstance = File.initFromBlob(file); - e.preventDefault(); - const html = fileInstance.upHTML(images, imagesHtml, file); - pasteImageElement.appendChild(html); - images.push(file); - imagesHtml.set(file, html); + let nonceMap = new Map(); + //@ts-expect-error unused right now, not needed + function getNonce(id: string) { + const nonce = nonceMap.get(id) || Math.floor(Math.random() * 1000000000) + ""; + nonceMap.set(id, nonce); + return nonce; } -}); - -await setTheme(); - -function userSettings(): void { - thisUser.showusersettings(); -} - -(document.getElementById("settings") as HTMLImageElement).onclick = userSettings; -const memberListToggle = document.getElementById("memberlisttoggle") as HTMLInputElement; -memberListToggle.checked = !localStorage.getItem("memberNotChecked"); -memberListToggle.onchange = () => { - if (!memberListToggle.checked) { - localStorage.setItem("memberNotChecked", "true"); - } else { - localStorage.removeItem("memberNotChecked"); - } -}; -if (mobile) { - const channelWrapper = document.getElementById("channelw") as HTMLDivElement; - channelWrapper.onclick = () => { - const toggle = document.getElementById("maintoggle") as HTMLInputElement; - toggle.checked = true; - }; - memberListToggle.checked = false; -} -let dragendtimeout = setTimeout(() => {}); -document.addEventListener("dragover", (e) => { - clearTimeout(dragendtimeout); - const data = e.dataTransfer; - const bg = document.getElementById("gimmefile") as HTMLDivElement; - - if (data) { - const isfile = data.types.includes("Files") || data.types.includes("application/x-moz-file"); - if (!isfile) { - bg.hidden = true; + async function handleEnter(event: KeyboardEvent): Promise { + if (event.key === "Escape") { + while (images.length) { + const elm = imagesHtml.get(images.pop() as Blob) as HTMLElement; + if (pasteImageElement.contains(elm)) pasteImageElement.removeChild(elm); + } + if (thisUser.channelfocus) { + thisUser.channelfocus?.replyingto?.div?.classList.remove("replying"); + thisUser.channelfocus.replyingto = null; + thisUser.channelfocus.makereplybox(); + } + } + if (thisUser.handleKeyUp(event)) { return; } - e.preventDefault(); - bg.hidden = false; - //console.log(data.types,data) - } else { - bg.hidden = true; + + const channel = thisUser.channelfocus; + if (!channel) return; + const content = MarkDown.gatherBoxText(typebox); + if (content === "" && event.key === "ArrowUp") { + channel.editLast(); + return; + } + channel.typingstart(); + + if (event.key === "Enter" && !event.shiftKey) { + if (!channel.canMessageRightNow()) return; + if (channel.curCommand) { + channel.submitCommand(); + return; + } + event.preventDefault(); + replyingTo = thisUser.channelfocus ? thisUser.channelfocus.replyingto : null; + if (replyingTo?.div) { + replyingTo.div.classList.remove("replying"); + } + if (thisUser.channelfocus) { + thisUser.channelfocus.replyingto = null; + thisUser.channelfocus.makereplybox(); + } + const attachments = images.filter((_) => document.contains(imagesHtml.get(_) || null)); + while (images.length) { + const elm = imagesHtml.get(images.pop() as Blob) as HTMLElement; + if (pasteImageElement.contains(elm)) pasteImageElement.removeChild(elm); + } + typebox.innerHTML = ""; + typebox.markdown.txt = []; + try { + await new Promise((mres, rej) => + channel.sendMessage( + content, + { + attachments, + embeds: [], // Add an empty array for the embeds property + replyingto: replyingTo, + sticker_ids: [], + //nonce: getNonce(channel.id), + }, + (res) => { + if (res === "Ok") { + mres(); + } else { + rej(); + } + }, + ), + ); + } catch { + images = attachments; + for (const file of images) { + const img = imagesHtml.get(file); + if (!img) continue; + pasteImageElement.append(img); + } + channel.replyingto = replyingTo; + channel.makereplybox(); + typebox.textContent = content; + typebox.markdown.txt = content.split(""); + typebox.markdown.boxupdate(Infinity); + } + nonceMap.delete(channel.id); + } } -}); -document.addEventListener("dragleave", (_) => { - dragendtimeout = setTimeout(() => { + + const typebox = document.getElementById("typebox") as CustomHTMLDivElement; + const markdown = new MarkDown("", thisUser); + typebox.markdown = markdown; + typebox.addEventListener("keyup", handleEnter); + typebox.addEventListener("keydown", (event) => { + thisUser.keydown(event); + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + }); + markdown.giveBox(typebox); + { + const searchBox = document.getElementById("searchBox") as CustomHTMLDivElement; + const markdown = new MarkDown("", thisUser); + searchBox.markdown = markdown; + const searchX = document.getElementById("searchX") as HTMLElement; + searchBox.addEventListener("keydown", (event) => { + if (event.key === "Enter") { + event.preventDefault(); + thisUser.mSearch(markdown.rawString); + } + }); + searchBox.addEventListener("keyup", () => { + if (searchBox.textContent === "") { + setTimeout(() => (searchBox.innerHTML = ""), 0); + searchX.classList.add("svg-search"); + searchX.classList.remove("svg-plainx"); + searchBox.parentElement!.classList.remove("searching"); + } else { + searchX.classList.remove("svg-search"); + searchX.classList.add("svg-plainx"); + searchBox.parentElement!.classList.add("searching"); + } + }); + const sideContainDiv = document.getElementById("sideContainDiv") as HTMLElement; + searchBox.onclick = () => { + sideContainDiv.classList.remove("hideSearchDiv"); + }; + searchX.onclick = () => { + if (searchX.classList.contains("svg-plainx")) { + markdown.txt = []; + searchBox.innerHTML = ""; + searchX.classList.add("svg-search"); + searchBox.parentElement!.classList.remove("searching"); + searchX.classList.remove("svg-plainx"); + thisUser.mSearch(""); + } else { + searchBox.parentElement!.classList.add("searching"); + } + }; + + markdown.giveBox(searchBox); + markdown.setCustomBox((e) => { + const span = document.createElement("span"); + span.textContent = e.replace("\n", ""); + return span; + }); + } + let images: Blob[] = []; + let imagesHtml = new WeakMap(); + + document.addEventListener("paste", async (e: ClipboardEvent) => { + if (!thisUser.channelfocus) return; + if (!e.clipboardData) return; + + for (const file of Array.from(e.clipboardData.files)) { + const fileInstance = File.initFromBlob(file); + e.preventDefault(); + const html = fileInstance.upHTML(images, imagesHtml, file); + pasteImageElement.appendChild(html); + images.push(file); + imagesHtml.set(file, html); + } + }); + + await setTheme(); + + function userSettings(): void { + thisUser.showusersettings(); + } + + (document.getElementById("settings") as HTMLImageElement).onclick = userSettings; + const memberListToggle = document.getElementById("memberlisttoggle") as HTMLInputElement; + memberListToggle.checked = !localStorage.getItem("memberNotChecked"); + memberListToggle.onchange = () => { + if (!memberListToggle.checked) { + localStorage.setItem("memberNotChecked", "true"); + } else { + localStorage.removeItem("memberNotChecked"); + } + }; + if (mobile) { + const channelWrapper = document.getElementById("channelw") as HTMLDivElement; + channelWrapper.onclick = () => { + const toggle = document.getElementById("maintoggle") as HTMLInputElement; + toggle.checked = true; + }; + memberListToggle.checked = false; + } + let dragendtimeout = setTimeout(() => {}); + document.addEventListener("dragover", (e) => { + clearTimeout(dragendtimeout); + const data = e.dataTransfer; + const bg = document.getElementById("gimmefile") as HTMLDivElement; + + if (data) { + const isfile = data.types.includes("Files") || data.types.includes("application/x-moz-file"); + if (!isfile) { + bg.hidden = true; + return; + } + e.preventDefault(); + bg.hidden = false; + //console.log(data.types,data) + } else { + bg.hidden = true; + } + }); + document.addEventListener("dragleave", (_) => { + dragendtimeout = setTimeout(() => { + const bg = document.getElementById("gimmefile") as HTMLDivElement; + bg.hidden = true; + }, 1000); + }); + document.addEventListener("dragenter", (e) => { + e.preventDefault(); + }); + document.addEventListener("drop", (e) => { + const data = e.dataTransfer; const bg = document.getElementById("gimmefile") as HTMLDivElement; bg.hidden = true; - }, 1000); -}); -document.addEventListener("dragenter", (e) => { - e.preventDefault(); -}); -document.addEventListener("drop", (e) => { - const data = e.dataTransfer; - const bg = document.getElementById("gimmefile") as HTMLDivElement; - bg.hidden = true; - if (!thisUser.channelfocus) { - e.preventDefault(); - return; - } - if (data) { - const isfile = data.types.includes("Files") || data.types.includes("application/x-moz-file"); - if (isfile) { + if (!thisUser.channelfocus) { e.preventDefault(); - console.log(data.files); - for (const file of Array.from(data.files)) { - const fileInstance = File.initFromBlob(file); - const html = fileInstance.upHTML(images, imagesHtml, file); - pasteImageElement.appendChild(html); - images.push(file); - imagesHtml.set(file, html); + return; + } + if (data) { + const isfile = data.types.includes("Files") || data.types.includes("application/x-moz-file"); + if (isfile) { + e.preventDefault(); + console.log(data.files); + for (const file of Array.from(data.files)) { + const fileInstance = File.initFromBlob(file); + const html = fileInstance.upHTML(images, imagesHtml, file); + pasteImageElement.appendChild(html); + images.push(file); + imagesHtml.set(file, html); + } } } + }); + const pinnedM = document.getElementById("pinnedM") as HTMLElement; + pinnedM.onclick = (e) => { + thisUser.pinnedClick(pinnedM.getBoundingClientRect()); + e.preventDefault(); + e.stopImmediatePropagation(); + }; + (document.getElementById("upload") as HTMLElement).onclick = () => { + const input = document.createElement("input"); + input.type = "file"; + input.click(); + input.multiple = true; + console.log("clicked"); + if (!thisUser.channelfocus) return; + input.onchange = () => { + if (input.files) { + for (const file of Array.from(input.files)) { + const fileInstance = File.initFromBlob(file); + const html = fileInstance.upHTML(images, imagesHtml, file); + pasteImageElement.appendChild(html); + images.push(file); + imagesHtml.set(file, html); + } + } + }; + }; + const emojiTB = document.getElementById("emojiTB") as HTMLElement; + emojiTB.onmousedown = (e) => e.stopImmediatePropagation(); + emojiTB.onclick = (e) => { + e.preventDefault(); + e.stopImmediatePropagation(); + thisUser.TBEmojiMenu(emojiTB.getBoundingClientRect()); + }; + + const gifTB = document.getElementById("gifTB") as HTMLElement; + gifTB.onmousedown = (e) => e.stopImmediatePropagation(); + gifTB.onclick = (e) => { + e.preventDefault(); + e.stopImmediatePropagation(); + thisUser.makeGifBox(gifTB.getBoundingClientRect()); + }; + + const stickerTB = document.getElementById("stickerTB") as HTMLElement; + stickerTB.onmousedown = (e) => e.stopImmediatePropagation(); + stickerTB.onclick = (e) => { + e.preventDefault(); + e.stopImmediatePropagation(); + thisUser.makeStickerBox(stickerTB.getBoundingClientRect()); + }; + const updateIcon = document.getElementById("updateIcon"); + if (updateIcon) { + new Hover(() => updateIcon.textContent || "").addEvent(updateIcon); + updateIcon.onclick = () => { + window.location.reload(); + }; } -}); -const pinnedM = document.getElementById("pinnedM") as HTMLElement; -pinnedM.onclick = (e) => { - thisUser.pinnedClick(pinnedM.getBoundingClientRect()); - e.preventDefault(); - e.stopImmediatePropagation(); -}; -(document.getElementById("upload") as HTMLElement).onclick = () => { - const input = document.createElement("input"); - input.type = "file"; - input.click(); - input.multiple = true; - console.log("clicked"); - if (!thisUser.channelfocus) return; - input.onchange = () => { - if (input.files) { - for (const file of Array.from(input.files)) { - const fileInstance = File.initFromBlob(file); - const html = fileInstance.upHTML(images, imagesHtml, file); - pasteImageElement.appendChild(html); - images.push(file); - imagesHtml.set(file, html); - } - } - }; -}; -const emojiTB = document.getElementById("emojiTB") as HTMLElement; -emojiTB.onmousedown = (e) => e.stopImmediatePropagation(); -emojiTB.onclick = (e) => { - e.preventDefault(); - e.stopImmediatePropagation(); - thisUser.TBEmojiMenu(emojiTB.getBoundingClientRect()); -}; - -const gifTB = document.getElementById("gifTB") as HTMLElement; -gifTB.onmousedown = (e) => e.stopImmediatePropagation(); -gifTB.onclick = (e) => { - e.preventDefault(); - e.stopImmediatePropagation(); - thisUser.makeGifBox(gifTB.getBoundingClientRect()); -}; - -const stickerTB = document.getElementById("stickerTB") as HTMLElement; -stickerTB.onmousedown = (e) => e.stopImmediatePropagation(); -stickerTB.onclick = (e) => { - e.preventDefault(); - e.stopImmediatePropagation(); - thisUser.makeStickerBox(stickerTB.getBoundingClientRect()); -}; -const updateIcon = document.getElementById("updateIcon"); -if (updateIcon) { - new Hover(() => updateIcon.textContent || "").addEvent(updateIcon); - updateIcon.onclick = () => { - window.location.reload(); - }; } diff --git a/src/webpage/invite.html b/src/webpage/invite.html index 0439ce9..165d7c9 100644 --- a/src/webpage/invite.html +++ b/src/webpage/invite.html @@ -32,6 +32,6 @@ - + diff --git a/src/webpage/invite.ts b/src/webpage/invite.ts index 47cccba..527e096 100644 --- a/src/webpage/invite.ts +++ b/src/webpage/invite.ts @@ -2,126 +2,126 @@ import {I18n} from "./i18n.js"; import {AccountSwitcher} from "./utils/switcher.js"; import {createImg, getapiurls} from "./utils/utils.js"; import {getBulkUsers, Specialuser} from "./utils/utils.js"; +if (window.location.pathname.startsWith("/invite")) + (async () => { + const users = getBulkUsers(); + const well = new URLSearchParams(window.location.search).get("instance"); + const joinable: Specialuser[] = []; -(async () => { - const users = getBulkUsers(); - const well = new URLSearchParams(window.location.search).get("instance"); - const joinable: Specialuser[] = []; - - for (const key in users.users) { - if (Object.prototype.hasOwnProperty.call(users.users, key)) { - const user: Specialuser = users.users[key]; - if (well && user.serverurls.wellknown.includes(well)) { - joinable.push(user); - } - console.log(user); - } - } - - let urls: {api: string; cdn: string} | undefined; - - if (!joinable.length && well) { - const out = await getapiurls(well); - if (out) { - urls = out; - for (const key in users.users) { - if (Object.prototype.hasOwnProperty.call(users.users, key)) { - const user: Specialuser = users.users[key]; - if (user.serverurls.api.includes(out.api)) { - joinable.push(user); - } - console.log(user); + for (const key in users.users) { + if (Object.prototype.hasOwnProperty.call(users.users, key)) { + const user: Specialuser = users.users[key]; + if (well && user.serverurls.wellknown.includes(well)) { + joinable.push(user); } + console.log(user); + } + } + + let urls: {api: string; cdn: string} | undefined; + + if (!joinable.length && well) { + const out = await getapiurls(well); + if (out) { + urls = out; + for (const key in users.users) { + if (Object.prototype.hasOwnProperty.call(users.users, key)) { + const user: Specialuser = users.users[key]; + if (user.serverurls.api.includes(out.api)) { + joinable.push(user); + } + console.log(user); + } + } + } else { + throw new Error("Someone needs to handle the case where the servers don't exist"); } } else { - throw new Error("Someone needs to handle the case where the servers don't exist"); + urls = joinable[0].serverurls; + } + await I18n.done; + if (!joinable.length) { + document.getElementById("AcceptInvite")!.textContent = I18n.htmlPages.noAccount(); } - } else { - urls = joinable[0].serverurls; - } - await I18n.done; - if (!joinable.length) { - document.getElementById("AcceptInvite")!.textContent = I18n.htmlPages.noAccount(); - } - const code = window.location.pathname.split("/")[2]; - let guildinfo: any; + const code = window.location.pathname.split("/")[2]; + let guildinfo: any; - fetch(`${urls!.api}/invites/${code}`, { - method: "GET", - }) - .then((response) => response.json()) - .then((json) => { - if (json.code === 404) { - document.getElementById("AcceptInvite")?.remove(); - document.getElementById("invitename")!.textContent = I18n.invite.notFound(); - document.getElementById("invitedescription")!.textContent = ""; - return; - } - const guildjson = json.guild; - guildinfo = guildjson; - document.getElementById("invitename")!.textContent = guildjson.name; - document.getElementById("invitedescription")!.textContent = I18n.invite.longInvitedBy( - json.inviter.username, - guildjson.name, - ); - if (guildjson.discovery_splash) { - const img = createImg( - `${urls!.cdn}/discovery-splashes/${guildjson.id}/${guildjson.discovery_splash}.png`, - ); - img.classList.add("inviteBG"); - document.body.prepend(img); - document.getElementById("invitebody")?.classList.add("moreShadow"); - } - if (guildjson.banner) { - const img = createImg(`${urls!.cdn}/banners/${guildjson.id}/${guildjson.banner}.png`); - document.getElementById("inviteBanner")!.append(img); - } - if (guildjson.icon) { - const img = document.createElement("img"); - img.src = `${urls!.cdn}/icons/${guildjson.id}/${guildjson.icon}.png`; - img.classList.add("inviteGuild"); - document.getElementById("inviteimg")!.append(img); - } else { - const txt = guildjson.name - .replace(/'s /g, " ") - .replace(/\w+/g, (word: any[]) => word[0]) - .replace(/\s/g, ""); - const div = document.createElement("div"); - div.textContent = txt; - div.classList.add("inviteGuild"); - document.getElementById("inviteimg")!.append(div); - } - }); - - async function showAccounts() { - console.log("showing!"); - const user = await new AccountSwitcher( - (user) => { - return !!(well && user.serverurls.wellknown.includes(well)); - }, - { - loginText: () => I18n.login.login(), - createOpt: true, - loginurl: "/login?" + new URLSearchParams([["goback", window.location.href]]), - registerurl: "/register?" + new URLSearchParams([["goback", window.location.href]]), - }, - ).show(); fetch(`${urls!.api}/invites/${code}`, { - method: "POST", - headers: { - Authorization: user.token, - }, - }).then(() => { - users.currentuser = user.uid; - sessionStorage.setItem("currentuser", user.uid); - localStorage.setItem("userinfos", JSON.stringify(users)); - window.location.href = "/channels/" + guildinfo.id; - }); - } + method: "GET", + }) + .then((response) => response.json()) + .then((json) => { + if (json.code === 404) { + document.getElementById("AcceptInvite")?.remove(); + document.getElementById("invitename")!.textContent = I18n.invite.notFound(); + document.getElementById("invitedescription")!.textContent = ""; + return; + } + const guildjson = json.guild; + guildinfo = guildjson; + document.getElementById("invitename")!.textContent = guildjson.name; + document.getElementById("invitedescription")!.textContent = I18n.invite.longInvitedBy( + json.inviter.username, + guildjson.name, + ); + if (guildjson.discovery_splash) { + const img = createImg( + `${urls!.cdn}/discovery-splashes/${guildjson.id}/${guildjson.discovery_splash}.png`, + ); + img.classList.add("inviteBG"); + document.body.prepend(img); + document.getElementById("invitebody")?.classList.add("moreShadow"); + } + if (guildjson.banner) { + const img = createImg(`${urls!.cdn}/banners/${guildjson.id}/${guildjson.banner}.png`); + document.getElementById("inviteBanner")!.append(img); + } + if (guildjson.icon) { + const img = document.createElement("img"); + img.src = `${urls!.cdn}/icons/${guildjson.id}/${guildjson.icon}.png`; + img.classList.add("inviteGuild"); + document.getElementById("inviteimg")!.append(img); + } else { + const txt = guildjson.name + .replace(/'s /g, " ") + .replace(/\w+/g, (word: any[]) => word[0]) + .replace(/\s/g, ""); + const div = document.createElement("div"); + div.textContent = txt; + div.classList.add("inviteGuild"); + document.getElementById("inviteimg")!.append(div); + } + }); - document.getElementById("AcceptInvite")!.addEventListener("click", (e) => { - e.stopImmediatePropagation(); - showAccounts(); - }); -})(); + async function showAccounts() { + console.log("showing!"); + const user = await new AccountSwitcher( + (user) => { + return !!(well && user.serverurls.wellknown.includes(well)); + }, + { + loginText: () => I18n.login.login(), + createOpt: true, + loginurl: "/login?" + new URLSearchParams([["goback", window.location.href]]), + registerurl: "/register?" + new URLSearchParams([["goback", window.location.href]]), + }, + ).show(); + fetch(`${urls!.api}/invites/${code}`, { + method: "POST", + headers: { + Authorization: user.token, + }, + }).then(() => { + users.currentuser = user.uid; + sessionStorage.setItem("currentuser", user.uid); + localStorage.setItem("userinfos", JSON.stringify(users)); + window.location.href = "/channels/" + guildinfo.id; + }); + } + + document.getElementById("AcceptInvite")!.addEventListener("click", (e) => { + e.stopImmediatePropagation(); + showAccounts(); + }); + })(); diff --git a/src/webpage/login.html b/src/webpage/login.html index a5de8a1..4183633 100644 --- a/src/webpage/login.html +++ b/src/webpage/login.html @@ -22,6 +22,6 @@ - + diff --git a/src/webpage/oauth2/auth.ts b/src/webpage/oauth2/auth.ts index ccf63a6..ca5d600 100644 --- a/src/webpage/oauth2/auth.ts +++ b/src/webpage/oauth2/auth.ts @@ -44,209 +44,210 @@ type botjsonfetch = { }; authorized: boolean; }; +if (window.location.pathname.startsWith("oauth2")) { + const users = getBulkUsers(); + const params = new URLSearchParams(window.location.search); + const well = params.get("instance"); + const permstr = params.get("permissions"); + const joinable: Specialuser[] = []; -const users = getBulkUsers(); -const params = new URLSearchParams(window.location.search); -const well = params.get("instance"); -const permstr = params.get("permissions"); -const joinable: Specialuser[] = []; - -for (const key in users.users) { - if (Object.prototype.hasOwnProperty.call(users.users, key)) { - const user: Specialuser = users.users[key]; - if (well && user.serverurls.wellknown.includes(well)) { - joinable.push(user); - } - console.log(user); - } -} - -let urls: {api: string; cdn: string} | undefined; - -if (!joinable.length && well) { - const out = await getapiurls(well); - if (out) { - urls = out; - for (const key in users.users) { - if (Object.prototype.hasOwnProperty.call(users.users, key)) { - const user: Specialuser = users.users[key]; - if (user.serverurls.api.includes(out.api)) { - joinable.push(user); - } - console.log(user); + for (const key in users.users) { + if (Object.prototype.hasOwnProperty.call(users.users, key)) { + const user: Specialuser = users.users[key]; + if (well && user.serverurls.wellknown.includes(well)) { + joinable.push(user); } + console.log(user); + } + } + + let urls: {api: string; cdn: string} | undefined; + + if (!joinable.length && well) { + const out = await getapiurls(well); + if (out) { + urls = out; + for (const key in users.users) { + if (Object.prototype.hasOwnProperty.call(users.users, key)) { + const user: Specialuser = users.users[key]; + if (user.serverurls.api.includes(out.api)) { + joinable.push(user); + } + console.log(user); + } + } + } else { + throw new Error("Someone needs to handle the case where the servers don't exist"); } } else { - throw new Error("Someone needs to handle the case where the servers don't exist"); + urls = joinable[0].serverurls; } -} else { - urls = joinable[0].serverurls; -} - -if (!joinable.length) { - document.getElementById("AcceptInvite")!.textContent = "Create an account to invite the bot"; -} -await I18n.done; -function showGuilds(user: Specialuser) { - if (!urls) return; - fetch(urls.api + "/oauth2/authorize/" + window.location.search, { - headers: { - Authorization: user.token, - }, - }) - .then((_) => _.json()) - .then((json: botjsonfetch) => { - const guilds: botjsonfetch["guilds"] = []; - for (const guild of json.guilds) { - const permisions = new Permissions(guild.permissions); - if (permisions.hasPermission("MANAGE_GUILD")) { - guilds.push(guild); - } - } - const dialog = document.createElement("dialog"); - dialog.classList.add("flexttb", "accountSwitcher"); - const h1 = document.createElement("h1"); - dialog.append(h1); - h1.textContent = "Invite to server:"; - const select = document.createElement("select"); - const selectSpan = document.createElement("span"); - selectSpan.classList.add("selectspan"); - const selectArrow = document.createElement("span"); - selectArrow.classList.add("svgicon", "svg-category", "selectarrow"); - for (const guild of guilds) { - const option = document.createElement("option"); - option.textContent = guild.name; - option.value = guild.id; - select.append(option); - } - selectSpan.append(select); - selectSpan.append(selectArrow); - dialog.append(selectSpan); - const button = document.createElement("button"); - button.textContent = "Invite"; - dialog.append(button); - button.onclick = () => { - const id = select.value; - const params2 = new URLSearchParams(""); - params2.set("client_id", params.get("client_id") as string); - fetch(urls.api + "/oauth2/authorize?" + params2.toString(), { - method: "POST", - body: JSON.stringify({ - authorize: true, - guild_id: id, - permissions: permstr, - }), - headers: { - "Content-type": "application/json; charset=UTF-8", - Authorization: user.token, - }, - }).then((req) => { - if (req.ok) { - alert("Bot added successfully"); - } - }); - }; - document.body.append(dialog); - }); -} -function showAccounts(): void { - const table = document.createElement("dialog"); - for (const user of joinable) { - console.log(user.pfpsrc); - - const userinfo = document.createElement("div"); - userinfo.classList.add("flexltr", "switchtable"); - - const pfp = document.createElement("img"); - pfp.src = user.pfpsrc; - pfp.classList.add("pfp"); - userinfo.append(pfp); - - const userDiv = document.createElement("div"); - userDiv.classList.add("userinfo"); - userDiv.textContent = user.username; - userDiv.append(document.createElement("br")); - - const span = document.createElement("span"); - span.textContent = user.serverurls.wellknown.replace("https://", "").replace("http://", ""); - span.classList.add("serverURL"); - userDiv.append(span); - - userinfo.append(userDiv); - table.append(userinfo); - - userinfo.addEventListener("click", () => { - table.remove(); - showGuilds(user); - }); - } - - const td = document.createElement("div"); - td.classList.add("switchtable"); - td.textContent = "Login or create an account ⇌"; - td.addEventListener("click", () => { - const l = new URLSearchParams("?"); - l.set("goback", window.location.href); - l.set("instance", well!); - window.location.href = "/login?" + l.toString(); - }); if (!joinable.length) { - const l = new URLSearchParams("?"); - l.set("goback", window.location.href); - l.set("instance", well!); - window.location.href = "/login?" + l.toString(); + document.getElementById("AcceptInvite")!.textContent = "Create an account to invite the bot"; } - - table.append(td); - table.classList.add("flexttb", "accountSwitcher"); - console.log(table); - document.body.append(table); -} -const user = joinable[0]; -if (user) { - fetch(urls.api + "/oauth2/authorize/" + window.location.search, { - headers: { - Authorization: user.token, - }, - }) - .then((_) => _.json()) - .then((json: botjsonfetch) => { - const title = document.getElementById("invitename"); - if (title) { - title.textContent = `Invite ${json.bot.username} to your servers`; - } - const desc = document.getElementById("invitedescription"); - if (desc) { - desc.textContent = json.application.description; - } - const pfp = document.getElementById("inviteimg") as HTMLImageElement; - if (json.bot.avatar !== null) { - pfp.src = `${urls.cdn}/avatars/${json.bot.id}/${json.bot.avatar}.png`; - } else { - const int = Number((BigInt(json.bot.id) >> 22n) % 6n); - pfp.src = `${urls.cdn}/embed/avatars/${int}.png`; - } - const perms = document.getElementById("permissions") as HTMLDivElement; - - if (perms && permstr) { - perms.children[0].textContent = I18n.htmlPages.idpermissions(); - const permisions = new Permissions(permstr); - for (const perm of Permissions.info()) { - if (permisions.hasPermission(perm.name, false)) { - const div = document.createElement("div"); - const h2 = document.createElement("h2"); - h2.textContent = perm.readableName; - div.append(h2, perm.description); - div.classList.add("flexttb"); - perms.append(div); + await I18n.done; + function showGuilds(user: Specialuser) { + if (!urls) return; + fetch(urls.api + "/oauth2/authorize/" + window.location.search, { + headers: { + Authorization: user.token, + }, + }) + .then((_) => _.json()) + .then((json: botjsonfetch) => { + const guilds: botjsonfetch["guilds"] = []; + for (const guild of json.guilds) { + const permisions = new Permissions(guild.permissions); + if (permisions.hasPermission("MANAGE_GUILD")) { + guilds.push(guild); } } - } + const dialog = document.createElement("dialog"); + dialog.classList.add("flexttb", "accountSwitcher"); + const h1 = document.createElement("h1"); + dialog.append(h1); + h1.textContent = "Invite to server:"; + const select = document.createElement("select"); + const selectSpan = document.createElement("span"); + selectSpan.classList.add("selectspan"); + const selectArrow = document.createElement("span"); + selectArrow.classList.add("svgicon", "svg-category", "selectarrow"); + for (const guild of guilds) { + const option = document.createElement("option"); + option.textContent = guild.name; + option.value = guild.id; + select.append(option); + } + selectSpan.append(select); + selectSpan.append(selectArrow); + dialog.append(selectSpan); + const button = document.createElement("button"); + button.textContent = "Invite"; + dialog.append(button); + button.onclick = () => { + const id = select.value; + const params2 = new URLSearchParams(""); + params2.set("client_id", params.get("client_id") as string); + fetch(urls.api + "/oauth2/authorize?" + params2.toString(), { + method: "POST", + body: JSON.stringify({ + authorize: true, + guild_id: id, + permissions: permstr, + }), + headers: { + "Content-type": "application/json; charset=UTF-8", + Authorization: user.token, + }, + }).then((req) => { + if (req.ok) { + alert("Bot added successfully"); + } + }); + }; + document.body.append(dialog); + }); + } + function showAccounts(): void { + const table = document.createElement("dialog"); + for (const user of joinable) { + console.log(user.pfpsrc); + + const userinfo = document.createElement("div"); + userinfo.classList.add("flexltr", "switchtable"); + + const pfp = document.createElement("img"); + pfp.src = user.pfpsrc; + pfp.classList.add("pfp"); + userinfo.append(pfp); + + const userDiv = document.createElement("div"); + userDiv.classList.add("userinfo"); + userDiv.textContent = user.username; + userDiv.append(document.createElement("br")); + + const span = document.createElement("span"); + span.textContent = user.serverurls.wellknown.replace("https://", "").replace("http://", ""); + span.classList.add("serverURL"); + userDiv.append(span); + + userinfo.append(userDiv); + table.append(userinfo); + + userinfo.addEventListener("click", () => { + table.remove(); + showGuilds(user); + }); + } + + const td = document.createElement("div"); + td.classList.add("switchtable"); + td.textContent = "Login or create an account ⇌"; + td.addEventListener("click", () => { + const l = new URLSearchParams("?"); + l.set("goback", window.location.href); + l.set("instance", well!); + window.location.href = "/login?" + l.toString(); }); -} -const AcceptInvite = document.getElementById("AcceptInvite"); -if (AcceptInvite) { - AcceptInvite.addEventListener("click", showAccounts); - AcceptInvite.textContent = I18n.htmlPages.addBot(); + + if (!joinable.length) { + const l = new URLSearchParams("?"); + l.set("goback", window.location.href); + l.set("instance", well!); + window.location.href = "/login?" + l.toString(); + } + + table.append(td); + table.classList.add("flexttb", "accountSwitcher"); + console.log(table); + document.body.append(table); + } + const user = joinable[0]; + if (user) { + fetch(urls.api + "/oauth2/authorize/" + window.location.search, { + headers: { + Authorization: user.token, + }, + }) + .then((_) => _.json()) + .then((json: botjsonfetch) => { + const title = document.getElementById("invitename"); + if (title) { + title.textContent = `Invite ${json.bot.username} to your servers`; + } + const desc = document.getElementById("invitedescription"); + if (desc) { + desc.textContent = json.application.description; + } + const pfp = document.getElementById("inviteimg") as HTMLImageElement; + if (json.bot.avatar !== null) { + pfp.src = `${urls.cdn}/avatars/${json.bot.id}/${json.bot.avatar}.png`; + } else { + const int = Number((BigInt(json.bot.id) >> 22n) % 6n); + pfp.src = `${urls.cdn}/embed/avatars/${int}.png`; + } + const perms = document.getElementById("permissions") as HTMLDivElement; + + if (perms && permstr) { + perms.children[0].textContent = I18n.htmlPages.idpermissions(); + const permisions = new Permissions(permstr); + for (const perm of Permissions.info()) { + if (permisions.hasPermission(perm.name, false)) { + const div = document.createElement("div"); + const h2 = document.createElement("h2"); + h2.textContent = perm.readableName; + div.append(h2, perm.description); + div.classList.add("flexttb"); + perms.append(div); + } + } + } + }); + } + const AcceptInvite = document.getElementById("AcceptInvite"); + if (AcceptInvite) { + AcceptInvite.addEventListener("click", showAccounts); + AcceptInvite.textContent = I18n.htmlPages.addBot(); + } } diff --git a/src/webpage/oauth2/authorize.html b/src/webpage/oauth2/authorize.html index 573145b..c63d6c7 100644 --- a/src/webpage/oauth2/authorize.html +++ b/src/webpage/oauth2/authorize.html @@ -31,6 +31,6 @@ - + diff --git a/src/webpage/recover.ts b/src/webpage/recover.ts index d598af6..562e4e5 100644 --- a/src/webpage/recover.ts +++ b/src/webpage/recover.ts @@ -89,11 +89,12 @@ function makeMenu1() { }); d.show(false); } -if ( - window.location.href.split("#").length == 2 && - new URLSearchParams(window.location.href.split("#")[1]).has("token") -) { - makeMenu2(); -} else { - makeMenu1(); -} +if (window.location.pathname.startsWith("/reset")) + if ( + window.location.href.split("#").length == 2 && + new URLSearchParams(window.location.href.split("#")[1]).has("token") + ) { + makeMenu2(); + } else { + makeMenu1(); + } diff --git a/src/webpage/register.html b/src/webpage/register.html index f3c7a85..3c80b7b 100644 --- a/src/webpage/register.html +++ b/src/webpage/register.html @@ -24,6 +24,6 @@

Register for a Spacebar instance!

- + diff --git a/src/webpage/reset.html b/src/webpage/reset.html index 991906e..4183633 100644 --- a/src/webpage/reset.html +++ b/src/webpage/reset.html @@ -22,6 +22,6 @@ - + diff --git a/src/webpage/template.html b/src/webpage/template.html index 3057346..efd0ce2 100644 --- a/src/webpage/template.html +++ b/src/webpage/template.html @@ -30,6 +30,6 @@ - + diff --git a/src/webpage/templatePage.ts b/src/webpage/templatePage.ts index 59e9bf2..55c606d 100644 --- a/src/webpage/templatePage.ts +++ b/src/webpage/templatePage.ts @@ -2,109 +2,109 @@ import {I18n} from "./i18n.js"; import {templateSkim} from "./jsontypes.js"; import {getapiurls} from "./utils/utils.js"; import {getBulkUsers, Specialuser} from "./utils/utils.js"; +if (window.location.pathname.startsWith("/template")) + (async () => { + const users = getBulkUsers(); + const well = new URLSearchParams(window.location.search).get("instance"); + const joinable: Specialuser[] = []; -(async () => { - const users = getBulkUsers(); - const well = new URLSearchParams(window.location.search).get("instance"); - const joinable: Specialuser[] = []; - - for (const key in users.users) { - if (Object.prototype.hasOwnProperty.call(users.users, key)) { - const user: Specialuser = users.users[key]; - if (well && user.serverurls.wellknown.includes(well)) { - joinable.push(user); - } - console.log(user); - } - } - - let urls: {api: string; cdn: string} | undefined; - - if (!joinable.length && well) { - const out = await getapiurls(well); - if (out) { - urls = out; - for (const key in users.users) { - if (Object.prototype.hasOwnProperty.call(users.users, key)) { - const user: Specialuser = users.users[key]; - if (user.serverurls.api.includes(out.api)) { - joinable.push(user); - } - console.log(user); + for (const key in users.users) { + if (Object.prototype.hasOwnProperty.call(users.users, key)) { + const user: Specialuser = users.users[key]; + if (well && user.serverurls.wellknown.includes(well)) { + joinable.push(user); } + console.log(user); + } + } + + let urls: {api: string; cdn: string} | undefined; + + if (!joinable.length && well) { + const out = await getapiurls(well); + if (out) { + urls = out; + for (const key in users.users) { + if (Object.prototype.hasOwnProperty.call(users.users, key)) { + const user: Specialuser = users.users[key]; + if (user.serverurls.api.includes(out.api)) { + joinable.push(user); + } + console.log(user); + } + } + } else { + throw new Error("Someone needs to handle the case where the servers don't exist"); } } else { - throw new Error("Someone needs to handle the case where the servers don't exist"); + urls = joinable[0].serverurls; } - } else { - urls = joinable[0].serverurls; - } - await I18n.done; - if (!joinable.length) { - document.getElementById("usetemplate")!.textContent = I18n.htmlPages.noAccount(); - } - - const code = window.location.pathname.split("/")[2]; - - fetch(`${urls!.api}/guilds/templates/${code}`, { - method: "GET", - headers: { - Authorization: joinable[0].token, - }, - }) - .then((response) => response.json()) - .then((json) => { - const template = json as templateSkim; - document.getElementById("templatename")!.textContent = I18n.useTemplate(template.name); - document.getElementById("templatedescription")!.textContent = template.description; - }); - - function showAccounts(): void { - const table = document.createElement("dialog"); - for (const user of joinable) { - console.log(user.pfpsrc); - - const userinfo = document.createElement("div"); - userinfo.classList.add("flexltr", "switchtable"); - - const pfp = document.createElement("img"); - pfp.src = user.pfpsrc; - pfp.classList.add("pfp"); - userinfo.append(pfp); - - const userDiv = document.createElement("div"); - userDiv.classList.add("userinfo"); - userDiv.textContent = user.username; - userDiv.append(document.createElement("br")); - - const span = document.createElement("span"); - span.textContent = user.serverurls.wellknown.replace("https://", "").replace("http://", ""); - span.classList.add("serverURL"); - userDiv.append(span); - - userinfo.append(userDiv); - table.append(userinfo); - - userinfo.addEventListener("click", () => { - const search = new URLSearchParams(); - search.set("templateID", code); - sessionStorage.setItem("currentuser", user.uid); - window.location.assign("/channels/@me?" + search); - }); - } - + await I18n.done; if (!joinable.length) { - const l = new URLSearchParams("?"); - l.set("goback", window.location.href); - l.set("instance", well!); - window.location.href = "/login?" + l.toString(); + document.getElementById("usetemplate")!.textContent = I18n.htmlPages.noAccount(); } - table.classList.add("flexttb", "accountSwitcher"); - console.log(table); - document.body.append(table); - } + const code = window.location.pathname.split("/")[2]; - document.getElementById("usetemplate")!.addEventListener("click", showAccounts); - document.getElementById("usetemplate")!.textContent = I18n.useTemplateButton(); -})(); + fetch(`${urls!.api}/guilds/templates/${code}`, { + method: "GET", + headers: { + Authorization: joinable[0].token, + }, + }) + .then((response) => response.json()) + .then((json) => { + const template = json as templateSkim; + document.getElementById("templatename")!.textContent = I18n.useTemplate(template.name); + document.getElementById("templatedescription")!.textContent = template.description; + }); + + function showAccounts(): void { + const table = document.createElement("dialog"); + for (const user of joinable) { + console.log(user.pfpsrc); + + const userinfo = document.createElement("div"); + userinfo.classList.add("flexltr", "switchtable"); + + const pfp = document.createElement("img"); + pfp.src = user.pfpsrc; + pfp.classList.add("pfp"); + userinfo.append(pfp); + + const userDiv = document.createElement("div"); + userDiv.classList.add("userinfo"); + userDiv.textContent = user.username; + userDiv.append(document.createElement("br")); + + const span = document.createElement("span"); + span.textContent = user.serverurls.wellknown.replace("https://", "").replace("http://", ""); + span.classList.add("serverURL"); + userDiv.append(span); + + userinfo.append(userDiv); + table.append(userinfo); + + userinfo.addEventListener("click", () => { + const search = new URLSearchParams(); + search.set("templateID", code); + sessionStorage.setItem("currentuser", user.uid); + window.location.assign("/channels/@me?" + search); + }); + } + + if (!joinable.length) { + const l = new URLSearchParams("?"); + l.set("goback", window.location.href); + l.set("instance", well!); + window.location.href = "/login?" + l.toString(); + } + + table.classList.add("flexttb", "accountSwitcher"); + console.log(table); + document.body.append(table); + } + + document.getElementById("usetemplate")!.addEventListener("click", showAccounts); + document.getElementById("usetemplate")!.textContent = I18n.useTemplateButton(); + })();