add: full working chats

This commit is contained in:
trisua 2025-08-28 20:26:38 -04:00
parent b360c5e737
commit 3f8171938e
7 changed files with 77 additions and 13 deletions

View file

@ -4,7 +4,8 @@ const STATE = {
observer: null,
is_loading: false,
stream_element: null,
first_message_time: 0,
last_message_time: 0,
last_read_receipt_load: 0,
};
function create_streamer(chat_id, hook_element) {
@ -24,6 +25,7 @@ function create_streamer(chat_id, hook_element) {
);
STATE.observer.observe(hook_element);
read_receipt();
}
function load_messages() {
@ -35,7 +37,7 @@ function load_messages() {
STATE.id += 1;
fetch(
`/chats/_templates/chat/${STATE.chat_id}/messages/before/${STATE.first_message_time}?use_id=${STATE.id}`,
`/chats/_templates/chat/${STATE.chat_id}/messages/before/${STATE.last_message_time}?use_id=${STATE.id}`,
)
.then((res) => res.text())
.then((res) => {
@ -44,7 +46,7 @@ function load_messages() {
}, 2000);
STATE.stream_element.innerHTML += res;
STATE.first_message_time = Number.parseInt(
STATE.last_message_time = Number.parseInt(
document
.getElementById(`msgs_data_${STATE.id}`)
.getAttribute("data-first-message-time"),
@ -78,7 +80,6 @@ function render_message(id) {
STATE.is_loading = false;
STATE.stream_element.innerHTML = `${res}${STATE.stream_element.innerHTML}`;
mark_message_read();
read_receipt();
STATE.stream_element.scrollTo(0, STATE.stream_element.scrollHeight);
});
}
@ -101,6 +102,10 @@ function sock_con() {
if (document.getElementById(`message_${msg.body}`)) {
document.getElementById(`message_${msg.body}`).remove();
}
} else if (msg.method === "ReadReceipt") {
setTimeout(() => {
read_receipt();
}, 1500);
}
});
}
@ -141,6 +146,13 @@ function mark_message_read() {
}
function read_receipt() {
if (new Date().getTime() - STATE.last_read_receipt_load < 150) {
console.log("too soon");
return;
}
STATE.last_read_receipt_load = new Date().getTime();
if (document.getElementById("delivered_read_status")) {
document.getElementById("delivered_read_status").remove();
}
@ -151,3 +163,19 @@ function read_receipt() {
STATE.stream_element.innerHTML = `${res}${STATE.stream_element.innerHTML}`;
});
}
function delete_message(id) {
if (!confirm("Are you sure you want to do this?")) {
return;
}
fetch(`/api/v1/messages/${id}`, {
method: "DELETE",
})
.then((res) => res.json())
.then((res) => {
if (!res.ok) {
show_message(res.message, res.ok);
}
});
}

View file

@ -323,6 +323,10 @@ video {
max-width: 15rem;
}
.dropdown .inner.surface {
background: var(--color-surface);
}
.dropdown .inner.left {
right: unset;
left: 0;
@ -757,13 +761,13 @@ menu.col {
justify-content: flex-end;
}
.message .inner {
.message .body {
padding: var(--pad-2) var(--pad-3);
background: var(--color-surface);
color: var(--color-text);
}
.message.mine .inner {
.message.mine .body {
background: var(--color-primary);
color: var(--color-text-primary);
}

View file

@ -45,8 +45,24 @@
(div
("class" "flex w_full gap_ch message {%- if user.id == message.owner %} justify_right mine {%- endif %}")
("id" "message_{{ message.id }}")
(text "{% if message.owner == user.id -%}")
(div
("class" "inner no_p_margin")
("class" "dropdown")
(button
("onclick" "open_dropdown(event)")
("exclude" "dropdown")
("class" "button")
(text "{{ icon \"ellipsis\" }}"))
(div
("class" "inner surface")
(button
("class" "button surface red")
("onclick" "delete_message('{{ message.id }}')")
(text "delete"))))
(text "{%- endif %}")
(div
("class" "body no_p_margin")
(text "{{ message.content|markdown|safe }}"))
(text "{{ self::avatar(id=message.owner) }}"))
(text "{%- endmacro %}")

View file

@ -6,7 +6,7 @@
(div
("class" "hidden")
("id" "msgs_data_{{ id }}")
("data-first-message-time" "{{ first_message_time }}"))
("data-first-message-time" "{{ last_message_time }}"))
(text "{% if messages|length == 0 -%}")
(div