chat défilement

This commit is contained in:
Flatlogic Bot 2026-02-15 18:28:21 +00:00
parent 1440c83ccf
commit dfd640b430
2 changed files with 54 additions and 10 deletions

View File

@ -5,11 +5,33 @@ document.addEventListener('DOMContentLoaded', () => {
const messagesList = document.getElementById('messages-list');
const typingIndicator = document.getElementById('typing-indicator');
function scrollToBottom(force = false) {
if (!messagesList) return;
// Smart scroll: only scroll if user is already at the bottom or if forced (e.g. sending a message)
const threshold = 150; // pixels margin
const isAtBottom = messagesList.scrollHeight - messagesList.scrollTop <= messagesList.clientHeight + threshold;
if (force || isAtBottom) {
messagesList.scrollTo({
top: messagesList.scrollHeight,
behavior: 'smooth'
});
// Backup for non-smooth support or rendering delays
setTimeout(() => {
if (force || messagesList.scrollHeight - messagesList.scrollTop <= messagesList.clientHeight + threshold + 200) {
messagesList.scrollTop = messagesList.scrollHeight;
}
}, 100);
}
}
// Emoji list for reactions
const EMOJIS = ['👍', '❤️', '😂', '😮', '😢', '🔥', '✅', '🚀', '❓', '💡', '📌', '💯'];
// Scroll to bottom
messagesList.scrollTop = messagesList.scrollHeight;
scrollToBottom(true);
const currentChannel = new URLSearchParams(window.location.search).get('channel_id') || 1;
const currentThread = new URLSearchParams(window.location.search).get('thread_id');
@ -45,7 +67,6 @@ document.addEventListener('DOMContentLoaded', () => {
const data = JSON.parse(msg.data);
if (data.channel_id == currentChannel) {
appendMessage(data);
messagesList.scrollTop = messagesList.scrollHeight;
// Desktop Notifications for mentions
if (data.content.includes(`@${window.currentUsername}`) && data.user_id != window.currentUserId) {
@ -174,7 +195,6 @@ document.addEventListener('DOMContentLoaded', () => {
const result = JSON.parse(xhr.responseText);
if (result.success) {
appendMessage(result.message);
messagesList.scrollTop = messagesList.scrollHeight;
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({
type: 'message',
@ -1417,6 +1437,18 @@ document.addEventListener('DOMContentLoaded', () => {
if (!msg || !msg.id) return;
if (document.querySelector(`.message-item[data-id="${msg.id}"]`)) return;
// Auto-populate metadata for video platforms if missing
const dmRegexForMeta = /(?:https?:\/\/)?(?:www\.)?(?:dailymotion\.com\/video\/|dai\.ly\/)([a-zA-Z0-9]+)/;
const dmMatchForMeta = msg.content.match(dmRegexForMeta);
if (dmMatchForMeta && !msg.metadata) {
msg.metadata = {
title: 'Dailymotion Video',
url: dmMatchForMeta[0],
image: `https://www.dailymotion.com/thumbnail/video/${dmMatchForMeta[1]}`,
site_name: 'Dailymotion'
};
}
const messagesList = document.getElementById('messages-list');
const div = document.createElement('div');
div.className = 'message-item';
@ -1496,11 +1528,11 @@ document.addEventListener('DOMContentLoaded', () => {
let videoHtml = '';
if (ytMatch && ytMatch[1]) {
videoHtml = `<div class="video-embed mt-2"><iframe width="100%" height="315" src="https://www.youtube.com/embed/${ytMatch[1]}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="border-radius: 8px; max-width: 560px;"></iframe></div>`;
videoHtml = `<div class="video-embed mt-2"><iframe width="100%" height="315" src="https://www.youtube.com/embed/${ytMatch[1]}?autoplay=0" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="border-radius: 8px; max-width: 560px;"></iframe></div>`;
} else if (dmMatch && dmMatch[1]) {
videoHtml = `<div class="video-embed mt-2"><iframe width="100%" height="315" src="https://www.dailymotion.com/embed/video/${dmMatch[1]}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="border-radius: 8px; max-width: 560px;"></iframe></div>`;
videoHtml = `<div class="video-embed mt-2"><iframe width="100%" height="315" src="https://www.dailymotion.com/embed/video/${dmMatch[1]}?autoplay=0&queue-enable=0&mute=0" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="border-radius: 8px; max-width: 560px;"></iframe></div>`;
} else if (vimeoMatch && vimeoMatch[1]) {
videoHtml = `<div class="video-embed mt-2"><iframe width="100%" height="315" src="https://player.vimeo.com/video/${vimeoMatch[1]}" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="border-radius: 8px; max-width: 560px;"></iframe></div>`;
videoHtml = `<div class="video-embed mt-2"><iframe width="100%" height="315" src="https://player.vimeo.com/video/${vimeoMatch[1]}?autoplay=0" frameborder="0" allow="fullscreen; picture-in-picture" allowfullscreen style="border-radius: 8px; max-width: 560px;"></iframe></div>`;
}
const authorStyle = msg.role_color ? `color: ${msg.role_color};` : '';
@ -1517,7 +1549,7 @@ document.addEventListener('DOMContentLoaded', () => {
${escapeHTML(msg.content).replace(/\n/g, '<br>').replace(mentionRegex, `<span class="mention">@${window.currentUsername}</span>`)}
${attachmentHtml}
${videoHtml}
${videoHtml ? '' : embedHtml}
${embedHtml}
</div>
<div class="message-reactions mt-1" data-message-id="${msg.id}">
<span class="add-reaction-btn" title="Add Reaction">+</span>
@ -1526,6 +1558,11 @@ document.addEventListener('DOMContentLoaded', () => {
${actionsHtml}
`;
messagesList.appendChild(div);
messagesList.scrollTop = messagesList.scrollHeight;
scrollToBottom(isMe);
// Ensure we scroll again when images/videos load
div.querySelectorAll('img, iframe').forEach(el => {
el.addEventListener('load', () => scrollToBottom(isMe));
});
}
});

View File

@ -4,8 +4,15 @@ function fetchOpenGraphData($url) {
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; Bot/1.0)');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
'Accept-Language: en-US,en;q=0.9',
'Cache-Control: no-cache',
'Pragma: no-cache',
'Upgrade-Insecure-Requests: 1'
]);
$html = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);