113 lines
No EOL
3.9 KiB
TypeScript
113 lines
No EOL
3.9 KiB
TypeScript
import util from "./util"
|
|
import { Message, Author } from "./message"
|
|
import { AdapterState } from "./adapter"
|
|
import { BatchTimer } from "./batch-timer"
|
|
|
|
export class ThreadSummaryElement extends HTMLElement {
|
|
static observedAttributes = [ "data-msg", "data-len", "data-author", "data-created", "data-latest", "data-new" ];
|
|
|
|
private _len: number = 0;;
|
|
private _msg: Message | null = null;;
|
|
private _author: Author | null = null;
|
|
private _adapter: string = "";
|
|
private _created: number = 0;
|
|
private _latest: number = 0;
|
|
private _new: boolean = false;
|
|
|
|
private _authorTimer: BatchTimer;
|
|
|
|
constructor() {
|
|
super();
|
|
this.innerHTML = "<div class='thread_summary'><div class='thread_author'></div><div class='thread_text'></div><div class='thread_metadata'></div></div>"
|
|
|
|
// adapter shouldn't change, just set it here
|
|
this._adapter = this.getAttribute("data-adapter") ?? "";
|
|
this.addEventListener("click", this.viewThread(this), false);
|
|
this._authorTimer = new BatchTimer((ids: string[])=>{
|
|
let url = `/api/adapters/${this._adapter}/fetch?entity_type=author`;
|
|
for (let id of ids) {
|
|
url += `&entity_id=${id}`;
|
|
}
|
|
util.authorizedFetch("GET", url, null)
|
|
});
|
|
}
|
|
|
|
connectedCallback() {
|
|
|
|
}
|
|
|
|
attributeChangedCallback(attr: string, prev: string, next: string) {
|
|
|
|
const datastore = AdapterState._instance.data.get(this._adapter);
|
|
if (!datastore) {
|
|
return;
|
|
}
|
|
let metadataChanged = false;
|
|
|
|
switch (attr) {
|
|
case "data-msg":
|
|
if (next && next != prev) {
|
|
this._msg = datastore.messages.get(next) || null;
|
|
if (this._msg) {
|
|
// TODO: use attachment alttext or fallback text if no msg content
|
|
// TODO: handle boosts, quotes properly
|
|
|
|
const threadText = this.querySelector(".thread_text");
|
|
if (threadText) {
|
|
threadText.innerHTML = this._msg.content;
|
|
}
|
|
this.setAttribute("data-author", this._msg.author);
|
|
}
|
|
}
|
|
break;
|
|
case "data-author":
|
|
if (next) {
|
|
let authorData= datastore.profileCache.get(next);
|
|
if (!authorData) {
|
|
this._authorTimer.queue(next, 2000);
|
|
this._author = <Author>{id: next};
|
|
const threadAuthor = this.querySelector(".thread_author");
|
|
if (threadAuthor) {
|
|
threadAuthor.innerHTML = `<a id="thread_${this._adapter}_${(this._msg ? this._msg.id : 0)}_${this._author.id}" href="#author?id=${this._author.id}">${this._author.id}</a>`;
|
|
}
|
|
} else {
|
|
this._author = authorData;
|
|
const threadAuthor = this.querySelector(".thread_author");
|
|
if (threadAuthor) {
|
|
threadAuthor.innerHTML = `<img src="${this._author.profilePic}" alt="${this._author.id}"/> <a id="thread_${this._adapter}_${(this._msg ? this._msg.id : 0)}_${this._author.id}" href="#author?id=${this._author.id}">${this._author.id}</a>`
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case "data-len":
|
|
this._len = parseInt(next);
|
|
metadataChanged = true;
|
|
break;
|
|
case "data-latest":
|
|
this._latest = parseInt(next);
|
|
metadataChanged = true;
|
|
break;
|
|
case "data-new":
|
|
this._new = next ? true : false;
|
|
metadataChanged = true;
|
|
break;
|
|
}
|
|
|
|
if (metadataChanged) {
|
|
const threadMeta = this.querySelector(".thread_metadata");
|
|
if (threadMeta) {
|
|
threadMeta.innerHTML = `<span>${this._new ? "!" : ""}[${this._len}] created: ${new Date(this._created)}, updated: ${new Date(this._latest)}</span>`;
|
|
}
|
|
}
|
|
}
|
|
|
|
viewThread(self: ThreadSummaryElement) {
|
|
return () => {
|
|
const a = util.$(`adapter_${self._adapter}`);
|
|
if (a && self._msg) {
|
|
a.setAttribute("data-view", "thread");
|
|
a.setAttribute("data-viewing", self._msg.id);
|
|
}
|
|
}
|
|
}
|
|
} |