117 lines
4.0 KiB
JavaScript
117 lines
4.0 KiB
JavaScript
// Written by retoor@molodetz.nl
|
|
|
|
// This class defines a custom HTML element that displays a list of messages with avatars and timestamps. It handles message addition with a delay in event dispatch and ensures the display of messages in the correct format.
|
|
|
|
// The code seems to rely on some external dependencies like 'models.Message', 'app', and 'Schedule'. These should be imported or defined elsewhere in your application.
|
|
|
|
// MIT License: This is free software. Permission is granted to use, copy, modify, and/or distribute this software for any purpose with or without fee. The software is provided "as is" without any warranty.
|
|
import { app } from "../app.js";
|
|
class MessageList extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
app.ws.addEventListener("update_message_text", (data) => {
|
|
this.updateMessageText(data.uid, data);
|
|
});
|
|
app.ws.addEventListener("set_typing", (data) => {
|
|
this.triggerGlow(data.user_uid,data.color);
|
|
});
|
|
|
|
this.items = [];
|
|
}
|
|
|
|
connectedCallback() {
|
|
const messagesContainer = this
|
|
messagesContainer.addEventListener('click', (e) => {
|
|
if (e.target.tagName !== 'IMG' || e.target.classList.contains('avatar-img')) return;
|
|
|
|
const img = e.target;
|
|
|
|
const overlay = document.createElement('div');
|
|
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.9);display:flex;justify-content:center;align-items:center;z-index:9999;'
|
|
|
|
const urlObj = new URL(img.currentSrc || img.src)
|
|
urlObj.searchParams.delete("width");
|
|
urlObj.searchParams.delete("height");
|
|
|
|
const fullImg = document.createElement('img');
|
|
|
|
fullImg.src = urlObj.toString();
|
|
fullImg.alt = img.alt;
|
|
fullImg.style.maxWidth = '90%';
|
|
fullImg.style.maxHeight = '90%';
|
|
|
|
overlay.appendChild(fullImg);
|
|
document.body.appendChild(overlay);
|
|
overlay.addEventListener('click', () => document.body.removeChild(overlay));
|
|
})
|
|
|
|
}
|
|
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)
|
|
);
|
|
}
|
|
isScrolledToBottom() {
|
|
return this.isElementVisible(this.querySelector(".message-list-bottom"));
|
|
}
|
|
scrollToBottom(force) {
|
|
//this.scrollTop = this.scrollHeight;
|
|
|
|
this.querySelector(".message-list-bottom").scrollIntoView();
|
|
this.querySelector(".message-list-bottom").scrollIntoView();
|
|
setTimeout(() => {
|
|
|
|
// this.scrollTop = this.scrollHeight;
|
|
this.querySelector(".message-list-bottom").scrollIntoView();
|
|
},200)
|
|
}
|
|
updateMessageText(uid, message) {
|
|
const messageDiv = this.querySelector('div[data-uid="' + uid + '"]');
|
|
|
|
if (!messageDiv) {
|
|
return;
|
|
}
|
|
const scrollToBottom = this.isScrolledToBottom();
|
|
const receivedHtml = document.createElement("div");
|
|
receivedHtml.innerHTML = message.html;
|
|
const html = receivedHtml.querySelector(".text").innerHTML;
|
|
const textElement = messageDiv.querySelector(".text");
|
|
textElement.innerHTML = html;
|
|
textElement.style.display = message.text == "" ? "none" : "block";
|
|
if(scrollToBottom)
|
|
this.scrollToBottom(true)
|
|
}
|
|
triggerGlow(uid,color) {
|
|
app.starField.glowColor(color)
|
|
let lastElement = null;
|
|
this.querySelectorAll(".avatar").forEach((el) => {
|
|
const div = el.closest("a");
|
|
if (el.href.indexOf(uid) != -1) {
|
|
lastElement = el;
|
|
}
|
|
});
|
|
if (lastElement) {
|
|
lastElement.classList.add("glow");
|
|
setTimeout(() => {
|
|
lastElement.classList.remove("glow");
|
|
}, 1000);
|
|
}
|
|
}
|
|
|
|
set data(items) {
|
|
this.items = items;
|
|
this.render();
|
|
}
|
|
render() {
|
|
this.innerHTML = "";
|
|
|
|
//this.insertAdjacentHTML("beforeend", html);
|
|
}
|
|
}
|
|
|
|
customElements.define("message-list", MessageList);
|