import util from "./util" import {AdapterState, AdapterData} from "./adapter"; import {Message, Attachment, Author} from "./message" import {Settings} from "./settings" import {SettingsElement} from "./settings-element" import {ProfileElement} from "./profile-element" import {MessageElement} from "./message-element" import {TimelineElement} from "./timeline-element" import {TimelineFilterElement} from "./timeline-filter-element" import {CreateMessageElement} from "./create-message-element" import {NavigatorElement} from "./navigator" export class DatagramSocket { public static skey: string | null = null; public static conn: WebSocket | null; private static _gateway: string = "" private static onOpen(e: Event) { console.log("websocket connection opened"); console.log(JSON.stringify(e)); } private static gatewayWithScheme(): string { return location.protocol + "//" + DatagramSocket._gateway } private static onMsg(e: MessageEvent) { const data = JSON.parse(e.data); console.log(data); if (data.key) { DatagramSocket.skey = data.key; util.authorizedFetch("POST", DatagramSocket.gatewayWithScheme() + "/api/adapters", JSON.stringify(Settings._instance.adapters)) .then(r=> { if (r.ok) { // iterate through any components which might want to fetch data const profiles = document.querySelectorAll("underbbs-profile"); profiles.forEach(p=>{ const target = p.getAttribute("data-target"); p.setAttribute("data-target", target ?? ""); }); const timelines = document.querySelectorAll("underbbs-timeline"); timelines.forEach(t=>{ const target = t.getAttribute("data-target"); t.setAttribute("data-target", target ?? ""); }); } }) .catch(e => { util.errMsg(e.message); }); } else { let store = AdapterState._instance.data.get(data.adapter); if (!store) { AdapterState._instance.data.set(data.adapter, new AdapterData(data.protocol)); store = AdapterState._instance.data.get(data.adapter); } if (store) { // typeswitch on the incoming data type and fill the memory switch (data.type) { case "message": store.messages.set(data.renoteId ?? data.id, data); break; case "author": store.profileCache.set(data.id, data); break; default: break; } } // go through each type of component and give it the latest if it's relevant to them let profileTargets = document.querySelectorAll(`underbbs-profile[data-adapter="${data.adapter}"][data-target="${data.id}"]`); profileTargets.forEach(t=>{ t.setAttribute("data-latest", data.id); }); let byAuthorTargets = document.querySelectorAll(`underbbs-author-messages[data-adapter="${data.adapter}"][data-target="${data.author}"]`); byAuthorTargets.forEach(t=>{ t.setAttribute("data-latest", data.id); }); if (data.renoter) { let byAuthorTargetsForBoosts = document.querySelectorAll(`underbbs-author-messages[data-adapter="${data.adapter}"][data-target="${data.renoter}"]`); byAuthorTargetsForBoosts.forEach(t=>{ console.log("setting renote id on data-latest") t.setAttribute("data-latest", data.renoteId); }); } if (data.target) { console.log("data has target: " + data.target); let e = document.querySelector(`underbbs-timeline#${data.target}[data-adapter="${data.adapter}"]`); if (e) { e.setAttribute("data-latest", data.renoteId ?? data.id); } } } } static connect(gateway: string): void { DatagramSocket._gateway = gateway; const wsProto = location.protocol == "https:" ? "wss" : "ws"; let wsUrl = "" if (!gateway) { wsUrl = `${wsProto}://${location.host}/subscribe`; } else { wsUrl = wsProto + "://" + gateway + "/subscribe" } const _conn = new WebSocket(wsUrl, "underbbs"); _conn.addEventListener("open", DatagramSocket.onOpen); _conn.addEventListener("message", DatagramSocket.onMsg); _conn.addEventListener("error", (e: any) => { console.log("websocket connection error"); console.log(JSON.stringify(e)); }); DatagramSocket.conn = _conn; } } function init() { const saveData = localStorage.getItem("underbbs_settings"); Settings._instance = saveData ? JSON.parse(saveData) : new Settings(); customElements.define("underbbs-message", MessageElement); customElements.define("underbbs-settings", SettingsElement); customElements.define("underbbs-profile", ProfileElement); customElements.define("underbbs-timeline", TimelineElement); customElements.define("underbbs-timeline-filter", TimelineFilterElement); customElements.define("underbbs-create-message", CreateMessageElement); customElements.define("underbbs-navigator", NavigatorElement); console.log("underbbs initialized!") } init();