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: Iris Lightshard
GPG key ID: 688407174966CAF3
3 changed files with 136 additions and 167 deletions

View file

@ -32,102 +32,84 @@ 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 = "";
}
}
// 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;
}
} }
} else { // probably only needed for profile view; we might be able to move this to child components
const latestAuthor = datastore.profileCache.get(this._latest); // keep it simple for now, but eventually we will need a way to force _view to update
if (latestAuthor) { break;
switch (this._view) { case "data-view":
case "index": if (!next) {
console.log (`author was updated: ${this._latest}, update their threads`) this._view = "index";
const threadsByThisAuthor = this._threads.filter(t=>t.root.data.author == this._latest); } else {
for (let t of threadsByThisAuthor) { this._view = next;
let tse = this.querySelector(`underbbs-thread-summary[data-msg='${t.root.data.id}']`) }
if (tse) { switch (this._view) {
console.log(`author has a thread in the dom, update it: ${t.root.data.id}`) case "index":
tse.setAttribute("data-author", this._latest); 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 "thread": case "profile":
case "profile": break;
break; }
} }
} }
} 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
} }
} }
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,10 +169,10 @@ 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);
} }
} }
} }
@ -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(); this.addEventListener("click", this.viewThread(this), false);
if (this._msg) {
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;
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 || <Author>{ id: this._msg.author };
const threadAuthor = this.querySelector(".thread_author");
if (threadAuthor && this._author) {
threadAuthor.innerHTML = this._author.profilePic
? `<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>`;
}
}
} }
// 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
? `<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>` ;
}
}
}
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; let metadataChanged = false;
if (l && l != this._len) { switch (attr) {
metadataChanged = true; case "data-msg":
this._len = l; if (next && next != prev) {
} this._msg = datastore.messages.get(next) || null;
if (created && parseInt(created) != this._created) { if (this._msg) {
metadataChanged = true; // TODO: use attachment alttext or fallback text if no msg content
this._created = parseInt(created); // TODO: handle boosts, quotes properly
this._latest = this._created;
} const threadText = this.querySelector(".thread_text");
if (latest && parseInt(latest) != this._latest) { if (threadText) {
metadataChanged = true; threadText.innerHTML = this._msg.content;
this._latest = parseInt(latest); }
} }
}
if (newness != this._new) { break;
metadataChanged = true; case "data-author":
this._new = newness; 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 = <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) { 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,
} }
} }