tawny/app/public/messages.js

182 lines
4.8 KiB
JavaScript
Raw Normal View History

2025-08-27 20:22:12 -04:00
const STATE = {
id: 0,
chat_id: "",
observer: null,
is_loading: false,
stream_element: null,
2025-08-28 20:26:38 -04:00
last_message_time: 0,
last_read_receipt_load: 0,
2025-08-27 20:22:12 -04:00
};
function create_streamer(chat_id, hook_element) {
STATE.chat_id = chat_id;
STATE.stream_element = hook_element.parentElement;
STATE.observer = new IntersectionObserver(
() => {
load_messages();
},
{
root: STATE.stream_element,
rootMargin: "0px",
scrollMargin: "0px",
threshold: 1.0,
},
);
STATE.observer.observe(hook_element);
2025-08-28 20:26:38 -04:00
read_receipt();
2025-08-27 20:22:12 -04:00
}
function load_messages() {
if (STATE.is_loading) {
return;
}
STATE.is_loading = true;
STATE.id += 1;
fetch(
2025-08-28 20:26:38 -04:00
`/chats/_templates/chat/${STATE.chat_id}/messages/before/${STATE.last_message_time}?use_id=${STATE.id}`,
2025-08-27 20:22:12 -04:00
)
.then((res) => res.text())
.then((res) => {
setTimeout(() => {
STATE.is_loading = false;
}, 2000);
STATE.stream_element.innerHTML += res;
2025-08-28 20:26:38 -04:00
STATE.last_message_time = Number.parseInt(
2025-08-27 20:22:12 -04:00
document
.getElementById(`msgs_data_${STATE.id}`)
.getAttribute("data-first-message-time"),
);
// STATE.stream_element.scrollTo(0, STATE.stream_element.scrollHeight);
if (document.getElementById(`msgs_quit_${STATE.id}`)) {
STATE.observer.disconnect();
console.log("quit");
} else {
STATE.observer.unobserve(
STATE.stream_element.querySelector(
"[ui_ident=data_marker]",
),
);
const element = document.createElement("div");
element.setAttribute("ui_ident", "data_marker");
STATE.stream_element.append(element);
STATE.observer.observe(element);
}
});
}
function render_message(id) {
STATE.is_loading = true;
fetch(`/chats/_templates/message/${id}`)
.then((res) => res.text())
.then((res) => {
STATE.is_loading = false;
STATE.stream_element.innerHTML = `${res}${STATE.stream_element.innerHTML}`;
mark_message_read();
STATE.stream_element.scrollTo(0, STATE.stream_element.scrollHeight);
});
}
function sock_con() {
const socket = new WebSocket(
`//${window.location.origin.split("//")[1]}/api/v1/chats/${STATE.chat_id}/_connect`,
);
socket.addEventListener("message", async (event) => {
if (event.data === "Ping") {
return socket.send("Pong");
}
const msg = JSON.parse(event.data);
if (msg.method === "MessageCreate") {
render_message(msg.body);
} else if (msg.method === "MessageDelete") {
if (document.getElementById(`message_${msg.body}`)) {
document.getElementById(`message_${msg.body}`).remove();
}
2025-08-28 20:26:38 -04:00
} else if (msg.method === "ReadReceipt") {
setTimeout(() => {
read_receipt();
}, 1500);
2025-08-27 20:22:12 -04:00
}
});
}
function create_message(e) {
e.preventDefault();
const body = new FormData();
body.append(
"body",
JSON.stringify({
content: e.target.content.value,
}),
);
fetch(`/api/v1/messages/${STATE.chat_id}`, { method: "POST", body })
.then((res) => res.json())
.then((res) => {
if (res.ok) {
e.target.reset();
} else {
show_message(res.message, res.ok);
}
});
}
function mark_message_read() {
fetch(`/api/v1/chats/${STATE.chat_id}/read_message`, {
method: "POST",
})
.then((res) => res.json())
.then((res) => {
if (!res.ok) {
show_message(res.message, res.ok);
}
});
}
function read_receipt() {
2025-08-28 20:26:38 -04:00
if (new Date().getTime() - STATE.last_read_receipt_load < 150) {
console.log("too soon");
return;
}
STATE.last_read_receipt_load = new Date().getTime();
2025-08-27 20:22:12 -04:00
if (document.getElementById("delivered_read_status")) {
document.getElementById("delivered_read_status").remove();
}
fetch(`/chats/_templates/chat/${STATE.chat_id}/read_receipt`)
.then((res) => res.text())
.then((res) => {
STATE.stream_element.innerHTML = `${res}${STATE.stream_element.innerHTML}`;
});
}
2025-08-28 20:26:38 -04:00
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);
}
});
}