start implementing boost carousel

This commit is contained in:
Iris Lightshard 2024-08-31 11:01:31 -06:00
parent 7a2eb99eb6
commit 09c7eb8318
Signed by: Iris Lightshard
GPG key ID: 688407174966CAF3
6 changed files with 37 additions and 7 deletions

View file

@ -216,6 +216,7 @@ func (self *MisskeyAdapter) toMessage(n mkm.Note, bustCache bool) *Message {
ReplyTo: n.ReplyID, ReplyTo: n.ReplyID,
ReplyCount: int(n.RepliesCount), ReplyCount: int(n.RepliesCount),
Replies: []string{}, Replies: []string{},
RenoteId: (*string)(n.RenoteID),
} }
for _, f := range n.Files { for _, f := range n.Files {

View file

@ -24,6 +24,7 @@ export class AdapterElement extends HTMLElement {
// TODO: use visibility of the thread to organize into DMs and public threads // TODO: use visibility of the thread to organize into DMs and public threads
private _threads: MessageThread[] = []; private _threads: MessageThread[] = [];
private _orphans: Message[] = []; private _orphans: Message[] = [];
private _boosts: Message[] = [];
constructor() { constructor() {
super(); super();
@ -102,6 +103,7 @@ export class AdapterElement extends HTMLElement {
tse.setAttribute("data-author", this._latest); tse.setAttribute("data-author", this._latest);
} }
} }
// also update any boosts by this author
case "thread": case "thread":
case "profile": case "profile":
break; break;
@ -113,7 +115,7 @@ export class AdapterElement extends HTMLElement {
} }
setIdxView() { setIdxView() {
this.innerHTML = "<ul id='dm_list'></ul><ul id='public_list'></ul>" this.innerHTML = "<ul id='boost_carousel'></ul><ul id='dm_list'></ul><ul id='public_list'></ul>"
} }
setThreadView() { setThreadView() {
@ -132,6 +134,8 @@ export class AdapterElement extends HTMLElement {
} }
populateIdxView() { populateIdxView() {
// populate boost carousel
// skip dm list for now // skip dm list for now
// public/unified list // public/unified list
const pl = util.$("public_list"); const pl = util.$("public_list");
@ -149,11 +153,12 @@ export class AdapterElement extends HTMLElement {
const existingThread = document.querySelector(threadSelector); 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);
if (existingThread && thread) { if (existingThread && thread) {
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");
} else { } else {
// if latest is a boost, put it in the carousel
// unified/public list for now // unified/public list for now
const pl = util.$("public_list"); const pl = util.$("public_list");
if (pl && thread) { if (pl && thread) {
@ -190,14 +195,14 @@ export class AdapterElement extends HTMLElement {
return; return;
} }
// make multiple passes over the store until every message is either // make multiple passes over the store until every message is either
// placed in a thread, or orphaned and waiting for its parent to be returned // placed in a thread, the boost carousel, or orphaned and waiting for its parent to be returned
do{ do{
for (let k of datastore.messages.keys()) { for (let k of datastore.messages.keys()) {
this.placeMsg(k); this.placeMsg(k);
} }
} while (this._threads.reduce((sum: number, thread: MessageThread)=>{ } while (this._threads.reduce((sum: number, thread: MessageThread)=>{
return sum + thread.messageCount; return sum + thread.messageCount;
}, 0) + this._orphans.length < datastore.messages.size); }, 0) + this._boosts.length + this._orphans.length < datastore.messages.size);
} }
placeMsg(k: string): string | null { placeMsg(k: string): string | null {
@ -211,11 +216,20 @@ export class AdapterElement extends HTMLElement {
util.errMsg(`message [${this._name}:${k}] doesn't exist`); util.errMsg(`message [${this._name}:${k}] doesn't exist`);
return null; return null;
} }
if (msg.renoteId) {
// fetch the referent thread and put the boost in the carousel
this._convoyBatchTimer.queue(msg.renoteId, 2000);
if (!this._boosts.some(m=>m.id == msg.id)) {
this._boosts.push(msg);
}
return null;
}
for (let t of this._threads) { for (let t of this._threads) {
// avoid processing nodes again on subsequent passes // avoid processing nodes again on subsequent passes
if (!msg || t.findNode(t.root, msg.id)) { if (!msg || t.findNode(t.root, msg.id)) {
return null; return null;
} }
if (msg.replyTo) { if (msg.replyTo) {
let x = t.addReply(msg.replyTo, msg); let x = t.addReply(msg.replyTo, msg);
if (x) { if (x) {

View file

@ -0,0 +1,14 @@
export class BoostTileElement extends HTMLElement {
static observedAttributes = [ "data-boostid", "data-msgid", "data-author", "data-booster" ];
constructor() {
this.innerHTML = "<div class='boost_booster'></div><div class='boost_author'></div><div class='boost_content'></div>";
}
connectedCallback() {
}
attributeChangedCallback(attr: string, prev: string, next: string) {
}
}

View file

@ -12,6 +12,7 @@ export class Message {
public created: number = 0; public created: number = 0;
public edited: number | null = null; public edited: number | null = null;
public visibility: string = "public"; public visibility: string = "public";
public renoteId: string | null = null;
} }
export class Author { export class Author {

View file

@ -58,13 +58,12 @@ export class DatagramSocket {
} }
static connect(): void { static connect(): void {
const wsProto = location.protocol == "https:" ? "wss" : "ws"; const wsProto = location.protocol == "https:" ? "wss" : "ws";
const _conn = new WebSocket(`${wsProto}://${location.host}/subscribe`, "underbbs"); const _conn = new WebSocket(`${wsProto}://${location.host}/subscribe`, "underbbs");
_conn.addEventListener("open", DatagramSocket.onOpen); _conn.addEventListener("open", DatagramSocket.onOpen);
_conn.addEventListener("message", DatagramSocket.onMsg); _conn.addEventListener("message", DatagramSocket.onMsg);
_conn.addEventListener("error", (e: any) => { _conn.addEventListener("error", (e: any) => {
console.log("websocket connection error"); console.log("websocket connection error");
console.log(JSON.stringify(e)); console.log(JSON.stringify(e));

View file

@ -25,6 +25,7 @@ type Message struct {
ReplyCount int `json:"replyCount"` ReplyCount int `json:"replyCount"`
Mentions []string `json:"mentions"` Mentions []string `json:"mentions"`
Visibility string `json:"visibility"` Visibility string `json:"visibility"`
RenoteId *string `json:"renoteId,omitempty"`
} }
type Author struct { type Author struct {