feature: essays

fix: multiple rendering of things when sending
This commit is contained in:
Andy Burke 2025-09-24 13:21:39 -07:00
parent 376b7fdc24
commit b6f661c6ec
10 changed files with 537 additions and 60 deletions

View file

@ -5,12 +5,13 @@
let last_creator_id = null;
let user_tick_tock_class = "user-tock";
async function render_chat_event(event) {
async function render_chat_event(event, position = "beforeend") {
const creator = await USERS.get(event.creator_id);
const existing_element =
document.getElementById(event.id) ??
(event.meta?.temp_id ? document.getElementById(event.meta?.temp_id ?? "") : undefined);
document.getElementById(event.meta?.temp_id ?? "") ??
document.querySelector(`[data-temp_id="${event.meta?.temp_id ?? ""}" ]`);
const event_datetime = datetime_to_local(event.timestamps.created);
@ -24,7 +25,7 @@
last_creator_id = creator.id;
}
const html_content = `<div id="${event.id}" class="message-container ${user_tick_tock_class} ${time_tick_tock_class}" data-creator_id="${creator.id}">
const html_content = `<div id="${event.id}" class="message-container ${user_tick_tock_class} ${time_tick_tock_class}" data-creator_id="${creator.id}" data-temp_id="${event.meta?.temp_id ?? ""}">
<div class="message-actions-container">
<input
type="checkbox"
@ -64,35 +65,31 @@
// TODO: threading
document
.getElementById("topic-chat-content")
?.insertAdjacentHTML("beforeend", html_content);
?.insertAdjacentHTML(position, html_content);
}
}
async function append_chat_events(events) {
async function handle_chat_events(events) {
const topic_chat_content = document.getElementById("topic-chat-content");
let last_message_id = topic_chat_content.dataset.last_message_id ?? "";
for await (const event of events) {
// if the last message is undefined, it becomes this event, otherwise, if this event's id is newer,
// it becomes the latest message
last_message_id =
event.id > last_message_id && event.id.indexOf("TEMP") !== 0
? event.id
: last_message_id;
// if the last message has been updated, update the content's dataset to reflect that
if (last_message_id !== topic_chat_content.dataset.last_message_id) {
topic_chat_content.dataset.last_message_id = last_message_id;
}
const sorted = events.sort((lhs, rhs) => lhs.id.localeCompare(rhs.id));
for await (const event of sorted) {
await render_chat_event(event);
}
const last_message_id = sorted.reduce((_last_message_id, event) => {
return event.id > _last_message_id && event.id.indexOf("TEMP") < 0
? event.id
: _last_message_id;
}, topic_chat_content.dataset.last_message_id ?? "");
// if the last blurb has been updated, update the content's dataset to reflect that
if (last_message_id !== topic_chat_content.dataset.last_message_id) {
topic_chat_content.dataset.last_message_id = last_message_id;
}
setTimeout(() => {
topic_chat_content.scrollTop = topic_chat_content.scrollHeight;
console.dir({
scrollHeight: topic_chat_content.scrollHeight,
scrollTop: topic_chat_content.scrollTop,
});
}, 50);
}
@ -118,8 +115,8 @@
signal: topic_polling_request_abort_controller.signal,
})
.then(async (new_events_response) => {
const new_events = ((await new_events_response.json()) ?? []).reverse();
await append_chat_events(new_events);
const new_events = await new_events_response.json();
handle_chat_events(new_events);
poll_for_new_chat_events(topic_id);
})
.catch((error) => {
@ -163,9 +160,8 @@
return;
}
const events = (await events_response.json()).reverse();
await append_chat_events(events);
const events = await events_response.json();
handle_chat_events(events);
poll_for_new_chat_events();
}
document.addEventListener("topic_changed", load_active_topic_for_chat);
@ -204,7 +200,7 @@
width: 100%;
transition: all 0.5s;
"
on_reply="async (event) => { await append_chat_events([event]); document.getElementById( 'chat-input' )?.focus(); }"
on_reply="async (event) => { await render_chat_event(event); document.getElementById(event.id)?.classList.remove('sending'); document.getElementById( 'chat-input' )?.focus(); }"
on_parsed="async (event) => { await render_chat_event(event); document.getElementById(event.id)?.classList.add('sending'); }"
>
<input type="hidden" name="type" value="chat" />