From 89135d039904f090db3f6474968cfdf400c03c59 Mon Sep 17 00:00:00 2001 From: Iris Lightshard Date: Sun, 4 Aug 2024 11:48:51 -0600 Subject: [PATCH] turn off minification and start refactoring web components --- frontend/ts/adapter-element.ts | 174 +++++++++++--------------- frontend/ts/thread-summary-element.ts | 126 +++++++++---------- webpack.config.js | 3 + 3 files changed, 136 insertions(+), 167 deletions(-) diff --git a/frontend/ts/adapter-element.ts b/frontend/ts/adapter-element.ts index dceef3e..d8ba09c 100644 --- a/frontend/ts/adapter-element.ts +++ b/frontend/ts/adapter-element.ts @@ -32,102 +32,84 @@ export class AdapterElement extends HTMLElement { connectedCallback() { const name = this.getAttribute("data-name"); this._name = name ?? ""; - this._view = ""; this.buildThreads(); - this.setAttribute("data-view", "index"); } - attributeChangedCallback() { - // set the viewing subject if it's changed - const viewing = this.getAttribute("data-viewing"); - if (this._viewing != viewing && viewing != null) { - console.log(`${this._name}.attributeChangedCallback: resetting viewing subject`); - 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 = ""; - } - } - - // 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) { - case "index": - this.setIdxView(); - this.populateIdxView(); - break; - case "thread": - this.setThreadView(); - this.populateThreadView(); - break; - case "profile": - this.setProfileView(); - this.populateProfileView(); - break; - } - } - - // 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); - if (!datastore) { - //util.errMsg(this._name + " has no datastore!"); - return; - } - const latestMsg = datastore.messages.get(this._latest); - if (latestMsg) { - console.log('latest was a message; place it'); - 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) { - switch (this._view) { - case "index": - console.log(`message was placed in thread ${rootId}, update view`) - this.updateIdxView(this._latest, rootId); - break; - case "thread": - // if the the message is part of this thread, update it - case "profile": - // if the message is from this user, show it in their profile - break; - } + attributeChangedCallback(attr: string, prev: string, next: string) { + switch (attr) { + case "data-viewing": + if (next != prev) { + this._viewing = next; } - } else { - const latestAuthor = datastore.profileCache.get(this._latest); - if (latestAuthor) { - switch (this._view) { - case "index": - console.log (`author was updated: ${this._latest}, update their threads`) - const threadsByThisAuthor = this._threads.filter(t=>t.root.data.author == this._latest); - for (let t of threadsByThisAuthor) { - let tse = this.querySelector(`underbbs-thread-summary[data-msg='${t.root.data.id}']`) - if (tse) { - console.log(`author has a thread in the dom, update it: ${t.root.data.id}`) - tse.setAttribute("data-author", this._latest); + // 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; + } + switch (this._view) { + case "index": + this.setIdxView(); + this.populateIdxView(); + break; + case "thread": + this.setThreadView(); + this.populateThreadView(); + break; + case "profile": + this.setProfileView(); + this.populateProfileView(); + break; + } + break; + case "data-latest": + let datastore = AdapterState._instance.data.get(this._name); + if (!datastore) { + // this shouldn't be possible + return; + } + if (prev != next && next) { + this._latest = next; + } + const latestMsg = datastore.messages.get(this._latest); + if (latestMsg) { + const rootId = this.placeMsg(this._latest); + // if rootId is null, this is an orphan and we don't need to actually do any UI updates yet + if (rootId) { + switch (this._view) { + case "index": + this.updateIdxView(this._latest, rootId); + break; + case "thread": + // if the the message is part of this thread, update it + case "profile": + // if the message is from this user, show it in their profile + break; + } + } + } else { + const latestAuthor = datastore.profileCache.get(this._latest); + if (latestAuthor) { + switch (this._view) { + case "index": + const threadsByThisAuthor = this._threads.filter(t=>t.root.data.author == this._latest); + for (let t of threadsByThisAuthor) { + let tse = this.querySelector(`underbbs-thread-summary[data-msg='${t.root.data.id}']`) + if (tse) { + tse.setAttribute("data-author", this._latest); + } } - } - case "thread": - case "profile": - break; + case "thread": + case "profile": + break; + } } } - } - // so, try to insert it into the threads - // 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 + break; } - } setIdxView() { @@ -163,13 +145,11 @@ export class AdapterElement extends HTMLElement { } 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); - console.log(`looking for thread ${rootId}`) - console.log(`- DOM object: ${existingThread}`); - console.log(`- in memory: ${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-len", `${thread.messageCount}`); existingThread.setAttribute("data-new", "true"); @@ -189,10 +169,10 @@ export class AdapterElement extends HTMLElement { } } if (nextThread) { - nextThread.insertAdjacentElement('beforebegin', li) - return + nextThread.insertAdjacentElement('beforebegin', li); + } else { + pl.append(li); } - pl.append(li); } } } @@ -288,6 +268,4 @@ export class AdapterElement extends HTMLElement { } return null; } - - } \ No newline at end of file diff --git a/frontend/ts/thread-summary-element.ts b/frontend/ts/thread-summary-element.ts index ba33a0d..fe131bf 100644 --- a/frontend/ts/thread-summary-element.ts +++ b/frontend/ts/thread-summary-element.ts @@ -3,7 +3,7 @@ import { Message, Author } from "./message" import { AdapterState } from "./adapter" 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 _msg: Message | null = null;; @@ -22,87 +22,75 @@ export class ThreadSummaryElement extends HTMLElement { // adapter shouldn't change, just set it here 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 msgId = this.getAttribute("data-msg"); - if (msgId && datastore && !this._msg) { - this._msg = datastore.messages.get(msgId) || null; - if (this._msg) { - const threadText = this.querySelector(".thread_text"); - if (threadText) { - threadText.innerHTML = this._msg.content; - } - let author = datastore.profileCache.get(this._msg.author); - if (!author) { - util.authorizedFetch( - "GET", - `/api/adapters/${this._adapter}/fetch?entity_type=author&entity_id=${this._msg.author}`, - null); - } - this._author = author || { id: this._msg.author }; - const threadAuthor = this.querySelector(".thread_author"); - if (threadAuthor && this._author) { - threadAuthor.innerHTML = this._author.profilePic - ? `${this._author.id} ${this._author.id}` - : `${this._author.id}`; - } - } + if (!datastore) { + return; } - - // 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"); - if (threadAuthor && this._author && this._msg) { - threadAuthor.innerHTML = this._author.profilePic - ? `${this._author.id} ${this._author.id}` - : `${this._author.id}` ; - } - } - } - - const l = parseInt(this.getAttribute("data-len") ?? "0"); - const latest = this.getAttribute("data-latest") ; - const created = this.getAttribute("data-created"); - const newness = this.getAttribute("data-new") ? true : false; - let metadataChanged = false; - if (l && l != this._len) { - metadataChanged = true; - this._len = l; - } - if (created && parseInt(created) != this._created) { - metadataChanged = true; - this._created = parseInt(created); - this._latest = this._created; - } - if (latest && parseInt(latest) != this._latest) { - metadataChanged = true; - this._latest = parseInt(latest); - } - - if (newness != this._new) { - metadataChanged = true; - this._new = newness; + 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; + } + } + } + break; + case "data-author": + if (next) { + let authorData= datastore.profileCache.get(next); + if (!authorData) { + util.authorizedFetch( + "GET", + `/api/adapters/${this._adapter}/fetch?entity_type=author&entity_id=${next}`, + null); + this._author = {id: next}; + const threadAuthor = this.querySelector(".thread_author"); + if (threadAuthor) { + threadAuthor.innerHTML = `${this._author.id}`; + } + } else { + this._author = authorData; + const threadAuthor = this.querySelector(".thread_author"); + if (threadAuthor) { + threadAuthor.innerHTML = `${this._author.id} ${this._author.id}` + } + } + } + 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 = `${this._new ? "!" : ""}[${this._len}] created: ${this._created}, updated: ${this._latest}`; + threadMeta.innerHTML = `${this._new ? "!" : ""}[${this._len}] created: ${new Date(this._created)}, updated: ${new Date(this._latest)}`; } } - } + } + viewThread(self: ThreadSummaryElement) { return () => { const a = util.$(`adapter_${self._adapter}`); diff --git a/webpack.config.js b/webpack.config.js index 5695b1e..366c1bb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -10,5 +10,8 @@ module.exports = { output: { filename: '[name].js', path: path.resolve(__dirname, 'frontend', 'dist'), + }, + optimization: { + minimize: false, } }