generated from t/malachite
add: full working chats
This commit is contained in:
parent
b360c5e737
commit
3f8171938e
7 changed files with 77 additions and 13 deletions
|
@ -4,7 +4,8 @@ const STATE = {
|
||||||
observer: null,
|
observer: null,
|
||||||
is_loading: false,
|
is_loading: false,
|
||||||
stream_element: null,
|
stream_element: null,
|
||||||
first_message_time: 0,
|
last_message_time: 0,
|
||||||
|
last_read_receipt_load: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
function create_streamer(chat_id, hook_element) {
|
function create_streamer(chat_id, hook_element) {
|
||||||
|
@ -24,6 +25,7 @@ function create_streamer(chat_id, hook_element) {
|
||||||
);
|
);
|
||||||
|
|
||||||
STATE.observer.observe(hook_element);
|
STATE.observer.observe(hook_element);
|
||||||
|
read_receipt();
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_messages() {
|
function load_messages() {
|
||||||
|
@ -35,7 +37,7 @@ function load_messages() {
|
||||||
STATE.id += 1;
|
STATE.id += 1;
|
||||||
|
|
||||||
fetch(
|
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) => res.text())
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
@ -44,7 +46,7 @@ function load_messages() {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
STATE.stream_element.innerHTML += res;
|
STATE.stream_element.innerHTML += res;
|
||||||
STATE.first_message_time = Number.parseInt(
|
STATE.last_message_time = Number.parseInt(
|
||||||
document
|
document
|
||||||
.getElementById(`msgs_data_${STATE.id}`)
|
.getElementById(`msgs_data_${STATE.id}`)
|
||||||
.getAttribute("data-first-message-time"),
|
.getAttribute("data-first-message-time"),
|
||||||
|
@ -78,7 +80,6 @@ function render_message(id) {
|
||||||
STATE.is_loading = false;
|
STATE.is_loading = false;
|
||||||
STATE.stream_element.innerHTML = `${res}${STATE.stream_element.innerHTML}`;
|
STATE.stream_element.innerHTML = `${res}${STATE.stream_element.innerHTML}`;
|
||||||
mark_message_read();
|
mark_message_read();
|
||||||
read_receipt();
|
|
||||||
STATE.stream_element.scrollTo(0, STATE.stream_element.scrollHeight);
|
STATE.stream_element.scrollTo(0, STATE.stream_element.scrollHeight);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -101,6 +102,10 @@ function sock_con() {
|
||||||
if (document.getElementById(`message_${msg.body}`)) {
|
if (document.getElementById(`message_${msg.body}`)) {
|
||||||
document.getElementById(`message_${msg.body}`).remove();
|
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() {
|
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")) {
|
if (document.getElementById("delivered_read_status")) {
|
||||||
document.getElementById("delivered_read_status").remove();
|
document.getElementById("delivered_read_status").remove();
|
||||||
}
|
}
|
||||||
|
@ -151,3 +163,19 @@ function read_receipt() {
|
||||||
STATE.stream_element.innerHTML = `${res}${STATE.stream_element.innerHTML}`;
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -323,6 +323,10 @@ video {
|
||||||
max-width: 15rem;
|
max-width: 15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown .inner.surface {
|
||||||
|
background: var(--color-surface);
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown .inner.left {
|
.dropdown .inner.left {
|
||||||
right: unset;
|
right: unset;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -757,13 +761,13 @@ menu.col {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message .inner {
|
.message .body {
|
||||||
padding: var(--pad-2) var(--pad-3);
|
padding: var(--pad-2) var(--pad-3);
|
||||||
background: var(--color-surface);
|
background: var(--color-surface);
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.message.mine .inner {
|
.message.mine .body {
|
||||||
background: var(--color-primary);
|
background: var(--color-primary);
|
||||||
color: var(--color-text-primary);
|
color: var(--color-text-primary);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,24 @@
|
||||||
(div
|
(div
|
||||||
("class" "flex w_full gap_ch message {%- if user.id == message.owner %} justify_right mine {%- endif %}")
|
("class" "flex w_full gap_ch message {%- if user.id == message.owner %} justify_right mine {%- endif %}")
|
||||||
("id" "message_{{ message.id }}")
|
("id" "message_{{ message.id }}")
|
||||||
|
(text "{% if message.owner == user.id -%}")
|
||||||
(div
|
(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 "{{ message.content|markdown|safe }}"))
|
||||||
(text "{{ self::avatar(id=message.owner) }}"))
|
(text "{{ self::avatar(id=message.owner) }}"))
|
||||||
(text "{%- endmacro %}")
|
(text "{%- endmacro %}")
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
(div
|
(div
|
||||||
("class" "hidden")
|
("class" "hidden")
|
||||||
("id" "msgs_data_{{ id }}")
|
("id" "msgs_data_{{ id }}")
|
||||||
("data-first-message-time" "{{ first_message_time }}"))
|
("data-first-message-time" "{{ last_message_time }}"))
|
||||||
|
|
||||||
(text "{% if messages|length == 0 -%}")
|
(text "{% if messages|length == 0 -%}")
|
||||||
(div
|
(div
|
||||||
|
|
|
@ -86,6 +86,8 @@ pub enum SocketMethod {
|
||||||
MessageUpdate,
|
MessageUpdate,
|
||||||
/// A chat update event.
|
/// A chat update event.
|
||||||
ChatUpdate,
|
ChatUpdate,
|
||||||
|
/// A read receipt update event.
|
||||||
|
ReadReceipt,
|
||||||
/// Simple ping.
|
/// Simple ping.
|
||||||
Ping,
|
Ping,
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,6 +185,20 @@ pub async fn read_message_request(
|
||||||
{
|
{
|
||||||
return Json(e.into());
|
return Json(e.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send event
|
||||||
|
let mut con = data.0.1.get_con().await;
|
||||||
|
|
||||||
|
if let Err(e) = con.publish::<usize, String, ()>(
|
||||||
|
id,
|
||||||
|
SocketMessage {
|
||||||
|
method: SocketMethod::ReadReceipt,
|
||||||
|
body: String::new(),
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
) {
|
||||||
|
return Json(Error::MiscError(e.to_string()).into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Json(ApiReturn {
|
Json(ApiReturn {
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub async fn chat_request(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let messages = match data.get_messages_by_chat(id, 12, props.page).await {
|
let messages = match data.get_messages_by_chat(id, 24, props.page).await {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await);
|
return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await);
|
||||||
|
@ -132,9 +132,9 @@ pub async fn messages_request(
|
||||||
};
|
};
|
||||||
|
|
||||||
let messages = match if before > 0 {
|
let messages = match if before > 0 {
|
||||||
data.get_messages_by_chat_before(id, before, 12, 0).await
|
data.get_messages_by_chat_before(id, before, 24, 0).await
|
||||||
} else {
|
} else {
|
||||||
data.get_messages_by_chat(id, 12, 0).await
|
data.get_messages_by_chat(id, 24, 0).await
|
||||||
} {
|
} {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -145,8 +145,8 @@ pub async fn messages_request(
|
||||||
let mut ctx = default_context(&data.0.0, &build_code, &Some(user));
|
let mut ctx = default_context(&data.0.0, &build_code, &Some(user));
|
||||||
|
|
||||||
ctx.insert(
|
ctx.insert(
|
||||||
"first_message_time",
|
"last_message_time",
|
||||||
&match messages.first() {
|
&match messages.last() {
|
||||||
Some(x) => x.created,
|
Some(x) => x.created,
|
||||||
None => 0,
|
None => 0,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue