135 lines
4.6 KiB
HTML
Raw Normal View History

2025-02-08 16:07:04 +00:00
{% extends "app.html" %}
2025-02-09 12:06:12 +00:00
2025-02-08 16:07:04 +00:00
{% block main %}
2025-02-09 12:06:12 +00:00
<section class="chat-area" id="chat">
<div class="chat-header">
<h2>{{ channel.label.value }}</h2>
</div>
2025-02-09 11:35:38 +00:00
<div class="chat-messages">
{% for message in messages %}
2025-02-09 12:06:12 +00:00
{% autoescape false %}
{{ message.html }}
{% endautoescape %}
2025-02-09 11:35:38 +00:00
{% endfor %}
</div>
<chat-window style="display:none" class="chat-area"></chat-window>
<div class="chat-input">
2025-02-09 12:06:12 +00:00
<textarea placeholder="Type a message..." rows="2"></textarea>
2025-02-11 14:34:31 +00:00
<upload-button channel="{{ channel.uid.value }}"></upload-button>
2025-02-09 11:35:38 +00:00
</div>
2025-02-09 12:06:12 +00:00
</section>
2025-02-09 11:35:38 +00:00
2025-02-09 12:06:12 +00:00
<script>
2025-02-11 14:34:31 +00:00
const channelUid = "{{ channel.uid.value }}";
2025-02-09 11:35:38 +00:00
2025-02-09 12:06:12 +00:00
function initInputField(textBox) {
textBox.addEventListener('change', (e) => {
e.preventDefault();
this.dispatchEvent(new CustomEvent('change', { detail: e.target.value, bubbles: true }));
});
2025-02-09 11:35:38 +00:00
2025-02-09 12:06:12 +00:00
textBox.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
const message = e.target.value.trim();
if (message) {
app.rpc.sendMessage(channelUid, message);
e.target.value = '';
}
}
});
2025-02-17 12:37:05 +00:00
textBox.focus();
2025-02-09 12:06:12 +00:00
}
2025-02-09 11:35:38 +00:00
2025-02-09 12:06:12 +00:00
function updateTimes() {
2025-02-09 11:35:38 +00:00
document.querySelectorAll(".time").forEach((time) => {
2025-02-09 12:06:12 +00:00
time.innerText = app.timeDescription(time.dataset.created_at);
});
}
function isElementVisible(element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
2025-02-17 17:42:59 +00:00
const messagesContainer = document.querySelector(".chat-messages");
async function loadExtra() {
2025-02-17 17:54:25 +00:00
const offsetMessage = messagesContainer.querySelector(".chat-messages :nth-child(1)");
2025-02-17 17:50:20 +00:00
if(!offsetMessage){
2025-02-17 17:42:59 +00:00
return
}
const firstMessage = messagesContainer.querySelector(".message:first-child");
2025-02-17 17:50:20 +00:00
if(offsetMessage.dataset.seen){
2025-02-17 17:42:59 +00:00
return
}
2025-02-17 17:50:20 +00:00
if(isElementVisible(offsetMessage)){
offsetMessage.dataset.seen = true
2025-02-17 17:52:30 +00:00
const messages = await app.rpc.getMessages(channelUid, 1, offsetMessage.dataset.created_at);
2025-02-17 17:42:59 +00:00
messages.forEach((message) => {
firstMessage.insertAdjacentHTML("beforebegin", message.html);
})
}
}
messagesContainer.addEventListener("scroll",()=>{
loadExtra()
});
function updateLayout(doScrollDown) {
2025-02-09 12:06:12 +00:00
const messagesContainer = document.querySelector(".chat-messages");
2025-02-13 19:21:34 +00:00
//messagesContainer.scrollTop = messagesContainer.scrollHeight + 1000;
2025-02-09 12:06:12 +00:00
updateTimes();
let previousUser = null;
document.querySelectorAll(".message").forEach((message) => {
if (previousUser !== message.dataset.user_uid) {
message.classList.add("switch-user");
previousUser = message.dataset.user_uid;
} else {
message.classList.remove("switch-user");
}
});
lastMessage = messagesContainer.querySelector(".message:last-child");
if(doScrollDown){
lastMessage.scrollIntoView({ inline: "nearest" });
}
2025-02-13 19:21:34 +00:00
2025-02-09 12:06:12 +00:00
}
setInterval(updateTimes, 1000);
app.addEventListener("channel-message", (data) => {
if (data.channel_uid !== channelUid) return;
if (data.username !== "{{ user.username.value }}") {
app.playSound(0);
2025-02-09 11:35:38 +00:00
}
const messagesContainer = document.querySelector(".chat-messages");
const lastMessage = messagesContainer.querySelector(".message:last-child");
const doScrollDownBecauseLastMessageIsVisible = !lastMessage || isElementVisible(lastMessage);
2025-02-09 11:35:38 +00:00
2025-02-09 12:06:12 +00:00
const message = document.createElement("div");
message.dataset.color = data.color;
message.dataset.created_at = data.created_at;
message.dataset.user_nick = data.user_nick;
message.dataset.uid = data.uid;
message.innerHTML = data.html;
2025-02-09 14:53:45 +00:00
document.querySelector(".chat-messages").appendChild(message.firstChild);
updateLayout(doScrollDownBecauseLastMessageIsVisible);
2025-02-09 12:07:38 +00:00
setTimeout(()=>{
updateLayout(doScrollDownBecauseLastMessageIsVisible)
2025-02-13 19:21:34 +00:00
},1000)
2025-02-09 12:06:12 +00:00
});
2025-02-09 11:35:38 +00:00
2025-02-09 12:06:12 +00:00
initInputField(document.querySelector("textarea"));
updateLayout(true);
2025-02-09 12:06:12 +00:00
</script>
2025-02-08 16:07:04 +00:00
{% endblock %}
2025-02-09 12:06:12 +00:00