import util from "./util" import { Message } from "./message" import { Fetcher } from "./fetcher" import { AdapterState } from "./adapter" export class MessageElement extends HTMLElement { static observedAttributes = [ "data-target", "data-latest", "data-adapter", "data-replyCt", "data-reactionCt", "data-boostCt" ] private _id: string | null = null; private _adapter: string | null = null; private _message: Message | null = null; private _interactable: boolean = false; private _replyWith: string | null = null; private _inspectWith: string | null = null; private _msgFetcher: Fetcher | null = null; constructor() { super(); this.innerHTML = `
` } connectedCallback() { this._id = this.getAttribute("data-target"); this._adapter = this.getAttribute("data-adapter"); const gateway = this.getAttribute("data-gateway") ?? ""; this._msgFetcher = new Fetcher(gateway, this._adapter ?? "", "message"); this._interactable = this.getAttribute("data-interactable") != null; this._replyWith = this.getAttribute("data-replywith"); this._inspectWith = this.getAttribute("data-inspectwith"); } attributeChangedCallback(attr: string, prev: string, next: string) { switch (attr) { case "data-target": if (!next) { return } this._id = next; this._message = null; this.innerHTML = `
`; if (this._msgFetcher) { this._msgFetcher.queue(next, 100); } break; case "data-latest": let datastore = AdapterState._instance.data.get(this._adapter ?? ""); if (!datastore) { console.log("no data yet, wait for some to come in maybe..."); return; } let msg = datastore.messages.get(next); if (msg) { this._message = msg; const metadata = this.querySelector(".message_metadata"); const content = this.querySelector(".message_content"); const attachments = this.querySelector(".message_attachments"); const interactions = this.querySelector(".message_interactions"); if (metadata) { if (this._message.renoteId) { metadata.innerHTML = `${this._message.renoter} boosted${new Date(this._message.renoteTime ?? 0)}` } else { metadata.innerHTML = ""; } metadata.innerHTML += `${this._message.author}${new Date(this._message.created)}${this._message.uri}${this._message.replyTo ? "reply to " + this._message.replyTo + "" : ""}${this._message.visibility}${this._message.protocol}` const renoter = this.querySelector(".message_renoter"); const author = this.querySelector(".message_author"); const url = this.querySelector(".message_url"); const replyToUrl = this.querySelector(".message_inreplyto"); if (renoter) { renoter.addEventListener("click", this.inspect(this._message.renoter ?? "", "author")); } if (author) { author.addEventListener("click", this.inspect(this._message.author, "author")); } if (url) { url.addEventListener("click", this.inspect(this._message.uri, "message")); } if (replyToUrl) { replyToUrl.addEventListener("click", this.inspect(this._message.replyTo ?? "", "message")); } } if (content) { content.innerHTML = this._message.content; } if (attachments && this._message.attachments && this._message.attachments.length > 0) { let html = ""; attachments.innerHTML = html; } if (this._interactable && interactions) { interactions.innerHTML = `` const replyBtn = this.querySelector(".message_reply"); const boostBtn = this.querySelector(".message_boost"); if (replyBtn) { replyBtn.addEventListener("click", this.reply.bind(this)); } if (boostBtn) { boostBtn.addEventListener("click", this.boost.bind(this)); } } } break; } } private reply() { const e = document.querySelector(`#${this._replyWith}`); if (e) { e.setAttribute("data-replyto", this._id || ""); const txtArea = e.querySelector("textarea") as HTMLTextAreaElement; if (txtArea) { txtArea.focus(); } } } private boost() { // use a Doer to boost } private inspect(target: string, type: string): ()=>void { const self = this; return ()=> { const e = document.querySelector(`#${self._inspectWith}`); if (e) { e.setAttribute("data-" + type, target); } else { window.open(target, "_blank"); } } } }