underbbs/frontend/ts/navigator.ts

108 lines
3.8 KiB
TypeScript
Raw Normal View History

import { AdapterState } from "./adapter"
class HistoryNode {
id: string;
type: string;
prev: HistoryNode | null = null;
next: HistoryNode | null = null;
constructor(id: string, type: string) {
this.id = id;
this.type = type;
}
}
export class NavigatorElement extends HTMLElement {
static observedAttributes = [ "data-author", "data-message" ];
private _adapter: string = "";
private _history: HistoryNode | null = null;
private _replyWith: string | null = null;
private _gateway: string = "";
constructor() {
super();
this.innerHTML = `<nav><button class="nav_prev">&larr;</button><button class="nav_next">&rarr;</button><button class="nav_clear">&times;</button></nav><div class="nav_container"></div>`
}
connectedCallback() {
this._adapter = this.getAttribute("data-adapter") ?? "";
this._replyWith = this.getAttribute("data-replywith");
this._gateway = this.getAttribute("data-gateway") ?? "";
const prevBtn = this.querySelector(".nav_prev");
const nextBtn = this.querySelector(".nav_next");
const clearBtn = this.querySelector(".nav_clear");
if (prevBtn) {
prevBtn.addEventListener("click", this.goPrev);
}
if (nextBtn) {
nextBtn.addEventListener("click", this.goNext);
}
if (clearBtn) {
clearBtn.addEventListener("click", this.clear);
}
}
attributeChangedCallback(attr: string, prev: string, next: string) {
switch (attr) {
case "data-author":
case "data-message":
if (next == prev) {
return;
}
if (this._history && this._history.prev && this._history.prev.id == next) {
this._history = this._history.prev;
} else {
const h = this._history;
this._history = new HistoryNode(next, attr.slice(attr.indexOf("-") + 1));
this._history.prev = h;
}
const panel = this.querySelector(".nav_container");
const datastore = AdapterState._instance.data.get(this._adapter);
if (datastore && panel) {
switch (attr) {
case "data-author":
const author = datastore.profileCache.get(next);
panel.innerHTML = `<underbbs-profile data-gateway="${this._gateway}" data-adapter="${this._adapter}" data-target="${next}"></underbbs-profile><underbbs-timeline data-gateway="${this._gateway}" data-target="${next}" data-adapter="${this._adapter}" data-interactable data-mode="fetch" data-inspectwith="${this.getAttribute("id")??""}" data-replywith="${this._replyWith}"></underbbs-timeline>`
const profile = this.querySelector("underbbs-profile");
const tl = this.querySelector("underbbs-timeline");
if (profile && tl) {
if (!author) {
profile.setAttribute("data-target", next);
} else {
profile.setAttribute("data-latest", next);
}
tl.setAttribute("data-target", next);
}
break;
case "data-message":
const msg = datastore.messages.get(next);
panel.innerHTML = `<underbbs-message data-gateway="${this._gateway}" data-adapter="${this._adapter}" data-target="${next}" data-interactable data-inspectwith="${this.getAttribute("id")??""}" data-replywith="${this._replyWith}"></underbbs-message>`
const e = this.querySelector("underbbs-message");
if (e) {
if (!msg) {
e.setAttribute("data-target", next);
} else {
e.setAttribute("data-latest", next);
}
}
break;
}
}
}
}
private goNext() {
}
private goPrev() {
}
private clear() {
}
}