2024-12-02 00:35:49 +00:00
|
|
|
import { Author, Message } from "./message"
|
|
|
|
import util from "./util"
|
|
|
|
import { BatchTimer } from "./batch-timer"
|
|
|
|
import { AdapterState } from "./adapter"
|
|
|
|
|
|
|
|
export class AuthorMessagesElement extends HTMLElement {
|
|
|
|
static observedAttributes = [ "data-latest", "data-adapter", "data-target" ];
|
|
|
|
|
|
|
|
private _id: string | null = null;
|
|
|
|
private _adapter: string = "";
|
|
|
|
|
|
|
|
private _messages: Message[] = [];
|
|
|
|
private _byAuthorTimer: BatchTimer | null = null;
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super();
|
2024-12-02 20:10:15 +00:00
|
|
|
this.innerHTML = `<ul class="messages_list"></ul>`;
|
2024-12-02 00:35:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
connectedCallback() {
|
|
|
|
this._id = this.getAttribute("data-target");
|
|
|
|
this._adapter = this.getAttribute("data-adapter") ?? "";
|
|
|
|
const gateway = this.getAttribute("data-gateway") ?? "";
|
|
|
|
this._byAuthorTimer = new BatchTimer((ids: string[])=>{
|
|
|
|
let url = `${gateway}/api/adapters/${this._adapter}/fetch?entity_type=byAuthor`;
|
|
|
|
for (let id of ids) {
|
|
|
|
url += `&entity_id=${id}`;
|
|
|
|
}
|
|
|
|
util.authorizedFetch("GET", url, null);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
attributeChangedCallback(attr: string, prev: string, next: string) {
|
|
|
|
switch (attr) {
|
|
|
|
case "data-target":
|
|
|
|
if (!next) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this._id = next;
|
|
|
|
if (this._byAuthorTimer) {
|
|
|
|
this._byAuthorTimer.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) {
|
2024-12-02 20:10:15 +00:00
|
|
|
const existingIdx = this._messages.findIndex(m=>m.id == msg.id && ((m.edited ?? m.created) < (msg.edited ?? msg.created)));
|
|
|
|
|
|
|
|
// first we update the backing data store
|
2024-12-02 00:35:49 +00:00
|
|
|
if (existingIdx >= 0) {
|
|
|
|
this._messages[existingIdx] = msg;
|
2024-12-02 20:10:15 +00:00
|
|
|
} else if (!this._messages.some(m=>m.id == msg.id)) {
|
2024-12-02 00:35:49 +00:00
|
|
|
this._messages.push(msg);
|
2024-12-02 20:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const ul = this.children[0];
|
|
|
|
if (ul) {
|
|
|
|
// first pass through the dom, try to update a message if it's there
|
|
|
|
for (let i = 0; i < ul.childElementCount; i++){
|
|
|
|
const id = ul.children[i]?.children[0]?.getAttribute("data-target");
|
|
|
|
const ogMsg = this._messages.find(m=>m.id == id);
|
|
|
|
if (ogMsg && existingIdx >= 0) {
|
|
|
|
ul.children[i]?.children[0]?.setAttribute("data-latest", id ?? "");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we made it this far, let's create a node
|
|
|
|
const e = document.createElement("li");
|
|
|
|
e.innerHTML = `<underbbs-message data-adapter="${this._adapter}" data-target="${next}"></underbbs-message>`
|
|
|
|
// second pass, try to place it in reverse-chronological order
|
|
|
|
for (let i = 0; i < ul.childElementCount; i++){
|
|
|
|
const id = ul.children[i]?.children[0]?.getAttribute("data-target");
|
|
|
|
const ogMsg = this._messages.find(m=>m.id == id);
|
|
|
|
if (ogMsg && ogMsg.created < msg.created) {
|
|
|
|
ul.insertBefore(e, ul.children[i])
|
|
|
|
e.children[0].setAttribute("data-latest", next);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// final pass, we must be the earliest child (or maybe the first one to be rendered)
|
|
|
|
ul.append(e);
|
|
|
|
e.children[0].setAttribute("data-latest", next);
|
|
|
|
}
|
|
|
|
console.log(JSON.stringify(this._messages));
|
2024-12-02 00:35:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|