From 51bd3a65053363adc389f298a906a0596804e906 Mon Sep 17 00:00:00 2001 From: Iris Lightshard Date: Sun, 1 Dec 2024 17:35:49 -0700 Subject: [PATCH] get pull a user's public posts, we just need to fill the dom with the data --- frontend/ts/author-messages-element.ts | 65 ++++++++++++++++++++++++++ frontend/ts/index.ts | 7 +++ frontend/ts/message-element.ts | 15 ++++-- frontend/ts/profile-element.ts | 3 +- frontend/ts/settings-element.ts | 2 +- frontend/ts/websocket.ts | 15 ++++-- models/msg.go | 2 +- 7 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 frontend/ts/author-messages-element.ts diff --git a/frontend/ts/author-messages-element.ts b/frontend/ts/author-messages-element.ts new file mode 100644 index 0000000..ffde06e --- /dev/null +++ b/frontend/ts/author-messages-element.ts @@ -0,0 +1,65 @@ +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(); + this.innerHTML = "" + } + + 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) { + // if _messages has this one, and this updated date is greater + const existingIdx = this._messages.findIndex(m=>m.id == msg.id && ((m.edited ?? 0) < (msg.edited ?? 0))); + if (existingIdx >= 0) { + this._messages[existingIdx] = msg; + // and update it in the dom + } else { + this._messages.push(msg); + // and insert in into the dom + } + console.log(JSON.stringify(this._messages)); + } + } + } +} \ No newline at end of file diff --git a/frontend/ts/index.ts b/frontend/ts/index.ts index d11a018..9e065bf 100644 --- a/frontend/ts/index.ts +++ b/frontend/ts/index.ts @@ -8,6 +8,7 @@ import { SettingsElement } from "./settings-element" import { AdapterElement } from "./adapter-element" import { ThreadSummaryElement } from "./thread-summary-element" import { ProfileElement } from "./profile-element" +import { AuthorMessagesElement } from "./author-messages-element" import {DatagramSocket} from "./websocket" function main() { @@ -20,6 +21,7 @@ function main() { customElements.define("underbbs-adapter", AdapterElement); customElements.define("underbbs-thread-summary", ThreadSummaryElement); customElements.define("underbbs-profile", ProfileElement); + customElements.define("underbbs-author-messages", AuthorMessagesElement); util._("closeErr", util.closeErr); let settingsParent = util.$("settings_parent"); @@ -31,6 +33,11 @@ function main() { if (profileParent) { profileParent.innerHTML = "" } + + let honksParent = util.$("honks_parent"); + if (honksParent) { + honksParent.innerHTML = ""; + } } main(); diff --git a/frontend/ts/message-element.ts b/frontend/ts/message-element.ts index acc7bab..d34907e 100644 --- a/frontend/ts/message-element.ts +++ b/frontend/ts/message-element.ts @@ -2,19 +2,26 @@ import util from "./util" var _ = util._ export class MessageElement extends HTMLElement { - static observedAttributes = [ "data-id", "data-adapter", "data-replyCt", "data-reactionCt", "data-boostCt" ] + static observedAttributes = [ "data-target", "data-latest", "data-adapter", "data-replyCt", "data-reactionCt", "data-boostCt" ] private _id: string | null = null; - private _adapter: any; + private _adapter: string | null = null; constructor() { super(); } connectedCallback() { - this._id = this.getAttribute("data-id"); - this._adapter = _("settings").adapters.filter((a: any)=>a.nickname == this.getAttribute("data-adapter"))[0]; + this._id = this.getAttribute("data-target"); + this._adapter = this.getAttribute("data-adapter"); // grab message content from the store and format our innerHTML } + + attributeChangedCallback(attr: string, prev: string, next: string) { + switch (attr) { + case "data-target": + break; + } + } } \ No newline at end of file diff --git a/frontend/ts/profile-element.ts b/frontend/ts/profile-element.ts index 0311c2d..63581ed 100644 --- a/frontend/ts/profile-element.ts +++ b/frontend/ts/profile-element.ts @@ -4,7 +4,7 @@ import { BatchTimer } from "./batch-timer" import { AdapterState } from "./adapter" export class ProfileElement extends HTMLElement { - static observedAttributes = [ "data-latest", "data-adapter", "data-target" ] + static observedAttributes = [ "data-latest", "data-adapter", "data-target" ]; private _id: string | null = null; private _adapter: string = ""; @@ -42,7 +42,6 @@ export class ProfileElement extends HTMLElement { } this._id = next; if (this._authorTimer) { - this._authorTimer.queue(next, 100); } break; diff --git a/frontend/ts/settings-element.ts b/frontend/ts/settings-element.ts index 6d06a81..d9d4c46 100644 --- a/frontend/ts/settings-element.ts +++ b/frontend/ts/settings-element.ts @@ -116,7 +116,7 @@ export class SettingsElement extends HTMLElement { break; case "honk": const handle = (util.$("settings_newadapter_honk_handle") as HTMLInputElement)?.value ?? ""; - const password = (util.$("settings_newadapter_honk_password") as HTMLInputElement)?.value ?? ""; + const password = (util.$("settings_newadapter_honk_password") as HTMLInputElement)?.value || null; adapterdata = { nickname: nickname, protocol: proto.options[proto.selectedIndex].value, handle: handle, password: password }; break; } diff --git a/frontend/ts/websocket.ts b/frontend/ts/websocket.ts index 8dbd829..a1a4208 100644 --- a/frontend/ts/websocket.ts +++ b/frontend/ts/websocket.ts @@ -28,6 +28,11 @@ export class DatagramSocket { const target = p.getAttribute("data-target"); p.setAttribute("data-target", target ?? ""); }); + const feeds = document.querySelectorAll("underbbs-author-messages"); + feeds.forEach(f=>{ + const target = f.getAttribute("data-target"); + f.setAttribute("data-target", target ?? ""); + }); } }) .catch(e => { @@ -53,9 +58,13 @@ export class DatagramSocket { } } console.log(store); - // now search for any components with this adapter and target - let targets = document.querySelectorAll(`*[data-adapter="${data.adapter}"][data-target="${data.id}"]`); - targets.forEach(t=>{ + // go through each type of component and give it the latest if it's relevant to them + let profileTargets = document.querySelectorAll(`underbbs-profile[data-adapter="${data.adapter}"][data-target="${data.id}"]`); + profileTargets.forEach(t=>{ + t.setAttribute("data-latest", data.id); + }); + let byAuthorTargets = document.querySelectorAll(`underbbs-author-messages[data-adapter="${data.adapter}"][data-target="${data.author}"]`); + byAuthorTargets.forEach(t=>{ t.setAttribute("data-latest", data.id); }); } diff --git a/models/msg.go b/models/msg.go index 270be57..7cd893e 100644 --- a/models/msg.go +++ b/models/msg.go @@ -12,7 +12,7 @@ type Datagram struct { Type string `json:"type"` Target *string `json:"target,omitempty"` Created int64 `json:"created"` - Updated *int64 `json:"updated,omitempty"` + Updated *int64 `json:"edited,omitempty"` } type Message struct {