diff --git a/api_v1_messages.php b/api_v1_messages.php index f6e92ba..1332033 100644 --- a/api_v1_messages.php +++ b/api_v1_messages.php @@ -38,21 +38,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if ($pinned) { try { + $thread_id = isset($_GET['thread_id']) && $_GET['thread_id'] !== '' ? (int)$_GET['thread_id'] : null; + // Get server_id for the channel $stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?"); $stmt->execute([$channel_id]); $server_id = $stmt->fetchColumn(); - $stmt = db()->prepare(" + $query = " SELECT m.*, u.display_name as username, u.username as login_name, u.avatar_url, (SELECT r.color FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_color, (SELECT r.icon_url FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_icon FROM messages m JOIN users u ON m.user_id = u.id WHERE m.channel_id = ? AND m.is_pinned = 1 - ORDER BY m.created_at DESC - "); - $stmt->execute([$server_id ?: 0, $server_id ?: 0, $channel_id]); + "; + $params = [$server_id ?: 0, $server_id ?: 0, $channel_id]; + + if ($thread_id !== null) { + $query .= " AND m.thread_id = ?"; + $params[] = $thread_id; + } else { + $query .= " AND m.thread_id IS NULL"; + } + + $query .= " ORDER BY m.created_at DESC"; + + $stmt = db()->prepare($query); + $stmt->execute($params); $msgs = $stmt->fetchAll(); foreach ($msgs as &$m) { @@ -70,21 +83,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (isset($_GET['after_id'])) { try { $after_id = (int)$_GET['after_id']; + $thread_id = isset($_GET['thread_id']) && $_GET['thread_id'] !== '' ? (int)$_GET['thread_id'] : null; + // Get server_id for the channel $stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?"); $stmt->execute([$channel_id]); $server_id = $stmt->fetchColumn(); - $stmt = db()->prepare(" + $query = " SELECT m.*, u.display_name as username, u.username as login_name, u.avatar_url, (SELECT r.color FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_color, (SELECT r.icon_url FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_icon FROM messages m JOIN users u ON m.user_id = u.id WHERE m.channel_id = ? AND m.id > ? - ORDER BY m.id ASC - "); - $stmt->execute([$server_id ?: 0, $server_id ?: 0, $channel_id, $after_id]); + "; + $params = [$server_id ?: 0, $server_id ?: 0, $channel_id, $after_id]; + + if ($thread_id !== null) { + $query .= " AND m.thread_id = ?"; + $params[] = $thread_id; + } else { + $query .= " AND m.thread_id IS NULL"; + } + + $query .= " ORDER BY m.id ASC"; + + $stmt = db()->prepare($query); + $stmt->execute($params); $msgs = $stmt->fetchAll(); foreach ($msgs as &$m) { diff --git a/assets/js/main.js b/assets/js/main.js index 7bbfdd7..ae289f6 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -498,6 +498,16 @@ document.addEventListener('DOMContentLoaded', () => { if (msg.type === 'message') { const data = JSON.parse(msg.data); if (data.channel_id == currentChannel) { + // For forums, only append if we are in the correct thread + if (window.activeChannelType === 'forum') { + if (!currentThread || data.thread_id != currentThread) { + return; + } + } else if (data.thread_id) { + // If it's not a forum channel but has a thread_id (shouldn't happen with current logic but for safety) + return; + } + appendMessage(data); // Desktop Notifications for mentions @@ -551,11 +561,24 @@ document.addEventListener('DOMContentLoaded', () => { setInterval(async () => { if (!currentChannel) return; + // For forums, if we're not in a thread, don't poll for messages + if (window.activeChannelType === 'forum' && !currentThread) return; + + // If we are in a non-forum channel, we should NOT have a currentThread + if (window.activeChannelType !== 'forum' && currentThread) return; + try { - const resp = await fetch(`api_v1_messages.php?channel_id=${currentChannel}&after_id=${lastMessageId}`); + const threadParam = currentThread ? `&thread_id=${currentThread}` : ''; + const resp = await fetch(`api_v1_messages.php?channel_id=${currentChannel}&after_id=${lastMessageId}${threadParam}`); const data = await resp.json(); if (data.success && data.messages && data.messages.length > 0) { data.messages.forEach(msg => { + // Double check thread_id in JS side too + if (window.activeChannelType === 'forum') { + if (msg.thread_id != currentThread) return; + } else { + if (msg.thread_id) return; + } appendMessage(msg); }); } @@ -2652,6 +2675,14 @@ document.addEventListener('DOMContentLoaded', () => { if (!msg || !msg.id) return; if (document.querySelector(`.message-item[data-id="${msg.id}"]`)) return; + // Security: Ensure message belongs to current channel/thread + if (msg.channel_id && msg.channel_id != currentChannel) return; + if (window.activeChannelType === 'forum') { + if (!currentThread || msg.thread_id != currentThread) return; + } else { + if (msg.thread_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); @@ -2665,6 +2696,11 @@ document.addEventListener('DOMContentLoaded', () => { } const messagesList = document.getElementById('messages-list'); + const messagesInner = document.querySelector('.messages-list-inner'); + const targetContainer = messagesInner || messagesList; + + if (!targetContainer) return; + const div = document.createElement('div'); div.className = 'message-item'; div.dataset.id = msg.id; @@ -2751,7 +2787,7 @@ document.addEventListener('DOMContentLoaded', () => { ${actionsHtml}
`; - messagesList.appendChild(div); + targetContainer.appendChild(div); scrollToBottom(isMe); // Ensure we scroll again when images/videos load diff --git a/assets/pasted-20260219-121958-92d2aa61.png b/assets/pasted-20260219-121958-92d2aa61.png new file mode 100644 index 0000000..9684a1e Binary files /dev/null and b/assets/pasted-20260219-121958-92d2aa61.png differ diff --git a/index.php b/index.php index bf0e1e0..cbae0e4 100644 --- a/index.php +++ b/index.php @@ -137,6 +137,10 @@ requireLogin(); $user = getCurrentUser(); $current_user_id = $user['id']; +$messages = []; // Initialize messages array +$threads = []; +$rules = []; +$autoroles = []; // Fetch servers user is member of $stmt = db()->prepare(" @@ -262,7 +266,9 @@ if ($is_dm_view) { } } - if (!$active_thread && $channel_type === 'rules') { + if ($active_thread) { + // Thread messages already fetched above + } elseif ($channel_type === 'rules') { $stmt = db()->prepare("SELECT * FROM channel_rules WHERE channel_id = ? ORDER BY position ASC"); $stmt->execute([$active_channel_id]); $rules = $stmt->fetchAll(); @@ -293,7 +299,7 @@ if ($is_dm_view) { $stmt->execute([$active_server_id, $active_server_id, $active_channel_id]); $threads = $stmt->fetchAll(); } else { - // Fetch messages + // Fetch messages for normal chat channels $display_limit = !empty($active_channel['message_limit']) ? (int)$active_channel['message_limit'] : 50; $stmt = db()->prepare(" @@ -302,7 +308,7 @@ if ($is_dm_view) { (SELECT r.icon_url FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_icon FROM messages m JOIN users u ON m.user_id = u.id - WHERE m.channel_id = ? + WHERE m.channel_id = ? AND m.thread_id IS NULL ORDER BY m.created_at ASC LIMIT " . $display_limit . " "); @@ -386,6 +392,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; window.canManageServer = ; window.canManageChannels = ; window.activeChannelId = ; + window.activeChannelType = ""; window.currentChannelName = ""; window.isDndMode = ; window.soundNotifications = ; @@ -1101,7 +1108,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; $show_input = true; if ($channel_type === 'rules') $show_input = false; if ($channel_type === 'forum' && !$active_thread) $show_input = false; - if ($channel_type === 'announcement' && !$can_manage_channels) $show_input = false; + if (($channel_type === 'announcement' || $channel_type === 'text') && !$can_manage_channels) $show_input = false; if ($show_input): if (!$can_send) { diff --git a/requests.log b/requests.log index aa9be90..c9cab83 100644 --- a/requests.log +++ b/requests.log @@ -782,3 +782,28 @@ 2026-02-19 12:18:33 - GET /index.php?server_id=1&channel_id=13 - POST: [] 2026-02-19 12:18:58 - GET /index.php?server_id=1&channel_id=13&thread_id=3 - POST: [] 2026-02-19 12:19:02 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:22:26 - GET /?fl_project=38443 - POST: [] +2026-02-19 12:35:03 - GET /?fl_project=38443 - POST: [] +2026-02-19 12:35:49 - GET /?fl_project=38443 - POST: [] +2026-02-19 12:40:12 - GET / - POST: [] +2026-02-19 12:40:37 - GET /?fl_project=38443 - POST: [] +2026-02-19 12:40:45 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-19 12:40:48 - GET /index.php?server_id=1&channel_id=6 - POST: [] +2026-02-19 12:40:51 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:40:54 - GET /index.php?server_id=1&channel_id=13&thread_id=3 - POST: [] +2026-02-19 12:40:58 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:00 - GET /index.php?server_id=1&channel_id=13&thread_id=2 - POST: [] +2026-02-19 12:41:02 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:03 - GET /index.php?server_id=1&channel_id=13&thread_id=4 - POST: [] +2026-02-19 12:41:18 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:19 - GET /index.php?server_id=1&channel_id=13&thread_id=4 - POST: [] +2026-02-19 12:41:22 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:23 - GET /index.php?server_id=1&channel_id=13&thread_id=3 - POST: [] +2026-02-19 12:41:32 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:38 - GET /index.php?server_id=1&channel_id=13&thread_id=4 - POST: [] +2026-02-19 12:41:41 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:42 - GET /index.php?server_id=1&channel_id=13&thread_id=2 - POST: [] +2026-02-19 12:41:46 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:48 - GET /index.php?server_id=1&channel_id=13&thread_id=4 - POST: [] +2026-02-19 12:41:52 - GET /index.php?server_id=1&channel_id=13 - POST: [] +2026-02-19 12:41:56 - GET /index.php?server_id=1&channel_id=13&thread_id=3 - POST: []