turn off minification and start refactoring web components

This commit is contained in:
Iris Lightshard 2024-08-04 11:48:51 -06:00
parent 557b87b700
commit 89135d0399
Signed by: nilix
GPG key ID: 688407174966CAF3
3 changed files with 136 additions and 167 deletions

View file

@ -32,32 +32,24 @@ export class AdapterElement extends HTMLElement {
connectedCallback() { connectedCallback() {
const name = this.getAttribute("data-name"); const name = this.getAttribute("data-name");
this._name = name ?? ""; this._name = name ?? "";
this._view = "";
this.buildThreads(); this.buildThreads();
this.setAttribute("data-view", "index");
} }
attributeChangedCallback() { attributeChangedCallback(attr: string, prev: string, next: string) {
// set the viewing subject if it's changed switch (attr) {
const viewing = this.getAttribute("data-viewing"); case "data-viewing":
if (this._viewing != viewing && viewing != null) { if (next != prev) {
console.log(`${this._name}.attributeChangedCallback: resetting viewing subject`); this._viewing = next;
this._viewing = viewing;
// if the viewing subject changed (not to nothing), unset the view
// this will force it to refresh
if (this._viewing) {
console.log(`${this._name}.attributeChangedCallback: forcing view update`);
this._view = "";
} }
// probably only needed for profile view; we might be able to move this to child components
// keep it simple for now, but eventually we will need a way to force _view to update
break;
case "data-view":
if (!next) {
this._view = "index";
} else {
this._view = next;
} }
// initialize the view if it's changed
const view = this.getAttribute("data-view");
if (this._view != view ?? "index") {
this._view = view ?? "index";
console.log(`${this._name}.attributeChangedCallback: setting view: ${this._view}`);
switch (this._view) { switch (this._view) {
case "index": case "index":
this.setIdxView(); this.setIdxView();
@ -72,26 +64,23 @@ export class AdapterElement extends HTMLElement {
this.populateProfileView(); this.populateProfileView();
break; break;
} }
} break;
case "data-latest":
// if latest changed, check if it's a message
const latest = this.getAttribute("data-latest");
if (latest ?? "" != this._latest) {
this._latest = latest ?? "";
let datastore = AdapterState._instance.data.get(this._name); let datastore = AdapterState._instance.data.get(this._name);
if (!datastore) { if (!datastore) {
//util.errMsg(this._name + " has no datastore!"); // this shouldn't be possible
return; return;
} }
if (prev != next && next) {
this._latest = next;
}
const latestMsg = datastore.messages.get(this._latest); const latestMsg = datastore.messages.get(this._latest);
if (latestMsg) { if (latestMsg) {
console.log('latest was a message; place it');
const rootId = this.placeMsg(this._latest); const rootId = this.placeMsg(this._latest);
// if rootId is null, this is an orphan and we don't need to actually do any updates yet // if rootId is null, this is an orphan and we don't need to actually do any UI updates yet
if (rootId) { if (rootId) {
switch (this._view) { switch (this._view) {
case "index": case "index":
console.log(`message was placed in thread ${rootId}, update view`)
this.updateIdxView(this._latest, rootId); this.updateIdxView(this._latest, rootId);
break; break;
case "thread": case "thread":
@ -106,12 +95,10 @@ export class AdapterElement extends HTMLElement {
if (latestAuthor) { if (latestAuthor) {
switch (this._view) { switch (this._view) {
case "index": case "index":
console.log (`author was updated: ${this._latest}, update their threads`)
const threadsByThisAuthor = this._threads.filter(t=>t.root.data.author == this._latest); const threadsByThisAuthor = this._threads.filter(t=>t.root.data.author == this._latest);
for (let t of threadsByThisAuthor) { for (let t of threadsByThisAuthor) {
let tse = this.querySelector(`underbbs-thread-summary[data-msg='${t.root.data.id}']`) let tse = this.querySelector(`underbbs-thread-summary[data-msg='${t.root.data.id}']`)
if (tse) { if (tse) {
console.log(`author has a thread in the dom, update it: ${t.root.data.id}`)
tse.setAttribute("data-author", this._latest); tse.setAttribute("data-author", this._latest);
} }
} }
@ -121,13 +108,8 @@ export class AdapterElement extends HTMLElement {
} }
} }
} }
// so, try to insert it into the threads break;
// then, switch on view
// if index, iterate through the topics and find the one to indicate new activity,
// if thread, if any relatives are in this thread, insert message appropriately
// if profile, if latest is this profile, update it
} }
} }
setIdxView() { setIdxView() {
@ -163,13 +145,11 @@ export class AdapterElement extends HTMLElement {
} }
updateIdxView(latest: string, rootId: string) { updateIdxView(latest: string, rootId: string) {
const existingThread = document.querySelector(`underbbs-thread-summary[data-msg='${rootId}']`); const threadSelector = `underbbs-thread-summary[data-msg='${rootId}']`
const existingThread = document.querySelector(threadSelector);
const thread = this._threads.find(t=>t.root.data.id == rootId); const thread = this._threads.find(t=>t.root.data.id == rootId);
console.log(`looking for thread ${rootId}`)
console.log(`- DOM object: ${existingThread}`);
console.log(`- in memory: ${thread}`);
if (existingThread && thread) { if (existingThread && thread) {
console.log(`updating thread: ${thread.root.data.id} // ${thread.messageCount} NEW`) debugger;
existingThread.setAttribute("data-latest", `${thread.latest}`); existingThread.setAttribute("data-latest", `${thread.latest}`);
existingThread.setAttribute("data-len", `${thread.messageCount}`); existingThread.setAttribute("data-len", `${thread.messageCount}`);
existingThread.setAttribute("data-new", "true"); existingThread.setAttribute("data-new", "true");
@ -189,13 +169,13 @@ export class AdapterElement extends HTMLElement {
} }
} }
if (nextThread) { if (nextThread) {
nextThread.insertAdjacentElement('beforebegin', li) nextThread.insertAdjacentElement('beforebegin', li);
return } else {
}
pl.append(li); pl.append(li);
} }
} }
} }
}
populateThreadView() { populateThreadView() {
} }
@ -288,6 +268,4 @@ export class AdapterElement extends HTMLElement {
} }
return null; return null;
} }
} }

View file

@ -3,7 +3,7 @@ import { Message, Author } from "./message"
import { AdapterState } from "./adapter" import { AdapterState } from "./adapter"
export class ThreadSummaryElement extends HTMLElement { export class ThreadSummaryElement extends HTMLElement {
static observedAttributes = [ "data-len", "data-author", "data-latest", "data-new" ]; static observedAttributes = [ "data-msg", "data-len", "data-author", "data-created", "data-latest", "data-new" ];
private _len: number = 0;; private _len: number = 0;;
private _msg: Message | null = null;; private _msg: Message | null = null;;
@ -22,87 +22,75 @@ export class ThreadSummaryElement extends HTMLElement {
// adapter shouldn't change, just set it here // adapter shouldn't change, just set it here
this._adapter = this.getAttribute("data-adapter") ?? ""; this._adapter = this.getAttribute("data-adapter") ?? "";
this.attributeChangedCallback();
if (this._msg) {
this.addEventListener("click", this.viewThread(this), false); this.addEventListener("click", this.viewThread(this), false);
} }
}
attributeChangedCallback() { attributeChangedCallback(attr: string, prev: string, next: string) {
const datastore = AdapterState._instance.data.get(this._adapter); const datastore = AdapterState._instance.data.get(this._adapter);
const msgId = this.getAttribute("data-msg"); if (!datastore) {
if (msgId && datastore && !this._msg) { return;
this._msg = datastore.messages.get(msgId) || null; }
let metadataChanged = false;
switch (attr) {
case "data-msg":
if (next && next != prev) {
this._msg = datastore.messages.get(next) || null;
if (this._msg) { 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"); const threadText = this.querySelector(".thread_text");
if (threadText) { if (threadText) {
threadText.innerHTML = this._msg.content; threadText.innerHTML = this._msg.content;
} }
let author = datastore.profileCache.get(this._msg.author); }
if (!author) { }
break;
case "data-author":
if (next) {
let authorData= datastore.profileCache.get(next);
if (!authorData) {
util.authorizedFetch( util.authorizedFetch(
"GET", "GET",
`/api/adapters/${this._adapter}/fetch?entity_type=author&entity_id=${this._msg.author}`, `/api/adapters/${this._adapter}/fetch?entity_type=author&entity_id=${next}`,
null); null);
} this._author = <Author>{id: next};
this._author = author || <Author>{ id: this._msg.author };
const threadAuthor = this.querySelector(".thread_author"); const threadAuthor = this.querySelector(".thread_author");
if (threadAuthor && this._author) { if (threadAuthor) {
threadAuthor.innerHTML = this._author.profilePic 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>`;
? `<img src="${this._author.profilePic}" alt="${this._author.id}"/> <a id="thread_${this._adapter}_${this._msg.id}_${this._author.id}" href="#author?id=${this._author.id}">${this._author.id}</a>`
: `<a id="thread_${this._adapter}_${this._msg.id}_${this._author.id}" href="#author?id=${this._author.id}">${this._author.id}</a>`;
} }
} } else {
} this._author = authorData;
// update author if it's passed in the attribute
const authorId = this.getAttribute("data-author");
if (authorId) {
let author = datastore?.profileCache?.get(this._msg?.author || "");
if (author) {
this._author = author;
const threadAuthor = this.querySelector(".thread_author"); const threadAuthor = this.querySelector(".thread_author");
if (threadAuthor && this._author && this._msg) { if (threadAuthor) {
threadAuthor.innerHTML = this._author.profilePic 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>`
? `<img src="${this._author.profilePic}" alt="${this._author.id}"/> <a id="thread_${this._adapter}_${this._msg.id}_${this._author.id}" href="#author?id=${this._author.id}">${this._author.id}</a>`
: `<a id="thread_${this._adapter}_${this._msg.id}_${this._author.id}" href="#author?id=${author.id}">${this._author.id}</a>` ;
} }
} }
} }
break;
const l = parseInt(this.getAttribute("data-len") ?? "0"); case "data-len":
const latest = this.getAttribute("data-latest") ; this._len = parseInt(next);
const created = this.getAttribute("data-created");
const newness = this.getAttribute("data-new") ? true : false;
let metadataChanged = false;
if (l && l != this._len) {
metadataChanged = true; metadataChanged = true;
this._len = l; break;
} case "data-latest":
if (created && parseInt(created) != this._created) { this._latest = parseInt(next);
metadataChanged = true; metadataChanged = true;
this._created = parseInt(created); break;
this._latest = this._created; case "data-new":
} this._new = next ? true : false;
if (latest && parseInt(latest) != this._latest) {
metadataChanged = true; metadataChanged = true;
this._latest = parseInt(latest); break;
}
if (newness != this._new) {
metadataChanged = true;
this._new = newness;
} }
if (metadataChanged) { if (metadataChanged) {
const threadMeta = this.querySelector(".thread_metadata"); const threadMeta = this.querySelector(".thread_metadata");
if (threadMeta) { if (threadMeta) {
threadMeta.innerHTML = `<span>${this._new ? "!" : ""}[${this._len}] created: ${this._created}, updated: ${this._latest}</span>`; threadMeta.innerHTML = `<span>${this._new ? "!" : ""}[${this._len}] created: ${new Date(this._created)}, updated: ${new Date(this._latest)}</span>`;
} }
} }
} }
viewThread(self: ThreadSummaryElement) { viewThread(self: ThreadSummaryElement) {
return () => { return () => {
const a = util.$(`adapter_${self._adapter}`); const a = util.$(`adapter_${self._adapter}`);

View file

@ -10,5 +10,8 @@ module.exports = {
output: { output: {
filename: '[name].js', filename: '[name].js',
path: path.resolve(__dirname, 'frontend', 'dist'), path: path.resolve(__dirname, 'frontend', 'dist'),
},
optimization: {
minimize: false,
} }
} }