Projet final V5 + Forum

This commit is contained in:
Flatlogic Bot 2026-02-19 12:42:34 +00:00
parent 430d57545f
commit f56ab7ba2b
5 changed files with 108 additions and 14 deletions

View File

@ -38,21 +38,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if ($pinned) { if ($pinned) {
try { try {
$thread_id = isset($_GET['thread_id']) && $_GET['thread_id'] !== '' ? (int)$_GET['thread_id'] : null;
// Get server_id for the channel // Get server_id for the channel
$stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?"); $stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?");
$stmt->execute([$channel_id]); $stmt->execute([$channel_id]);
$server_id = $stmt->fetchColumn(); $server_id = $stmt->fetchColumn();
$stmt = db()->prepare(" $query = "
SELECT m.*, u.display_name as username, u.username as login_name, u.avatar_url, 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.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 (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 FROM messages m
JOIN users u ON m.user_id = u.id JOIN users u ON m.user_id = u.id
WHERE m.channel_id = ? AND m.is_pinned = 1 WHERE m.channel_id = ? AND m.is_pinned = 1
ORDER BY m.created_at DESC ";
"); $params = [$server_id ?: 0, $server_id ?: 0, $channel_id];
$stmt->execute([$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(); $msgs = $stmt->fetchAll();
foreach ($msgs as &$m) { foreach ($msgs as &$m) {
@ -70,21 +83,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (isset($_GET['after_id'])) { if (isset($_GET['after_id'])) {
try { try {
$after_id = (int)$_GET['after_id']; $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 // Get server_id for the channel
$stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?"); $stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?");
$stmt->execute([$channel_id]); $stmt->execute([$channel_id]);
$server_id = $stmt->fetchColumn(); $server_id = $stmt->fetchColumn();
$stmt = db()->prepare(" $query = "
SELECT m.*, u.display_name as username, u.username as login_name, u.avatar_url, 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.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 (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 FROM messages m
JOIN users u ON m.user_id = u.id JOIN users u ON m.user_id = u.id
WHERE m.channel_id = ? AND m.id > ? WHERE m.channel_id = ? AND m.id > ?
ORDER BY m.id ASC ";
"); $params = [$server_id ?: 0, $server_id ?: 0, $channel_id, $after_id];
$stmt->execute([$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(); $msgs = $stmt->fetchAll();
foreach ($msgs as &$m) { foreach ($msgs as &$m) {

View File

@ -498,6 +498,16 @@ document.addEventListener('DOMContentLoaded', () => {
if (msg.type === 'message') { if (msg.type === 'message') {
const data = JSON.parse(msg.data); const data = JSON.parse(msg.data);
if (data.channel_id == currentChannel) { 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); appendMessage(data);
// Desktop Notifications for mentions // Desktop Notifications for mentions
@ -551,11 +561,24 @@ document.addEventListener('DOMContentLoaded', () => {
setInterval(async () => { setInterval(async () => {
if (!currentChannel) return; 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 { 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(); const data = await resp.json();
if (data.success && data.messages && data.messages.length > 0) { if (data.success && data.messages && data.messages.length > 0) {
data.messages.forEach(msg => { 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); appendMessage(msg);
}); });
} }
@ -2652,6 +2675,14 @@ document.addEventListener('DOMContentLoaded', () => {
if (!msg || !msg.id) return; if (!msg || !msg.id) return;
if (document.querySelector(`.message-item[data-id="${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 // Auto-populate metadata for video platforms if missing
const dmRegexForMeta = /(?:https?:\/\/)?(?:www\.)?(?:dailymotion\.com\/video\/|dai\.ly\/)([a-zA-Z0-9]+)/; const dmRegexForMeta = /(?:https?:\/\/)?(?:www\.)?(?:dailymotion\.com\/video\/|dai\.ly\/)([a-zA-Z0-9]+)/;
const dmMatchForMeta = msg.content.match(dmRegexForMeta); const dmMatchForMeta = msg.content.match(dmRegexForMeta);
@ -2665,6 +2696,11 @@ document.addEventListener('DOMContentLoaded', () => {
} }
const messagesList = document.getElementById('messages-list'); 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'); const div = document.createElement('div');
div.className = 'message-item'; div.className = 'message-item';
div.dataset.id = msg.id; div.dataset.id = msg.id;
@ -2751,7 +2787,7 @@ document.addEventListener('DOMContentLoaded', () => {
${actionsHtml} ${actionsHtml}
<div class="message-reaction-picker-anchor"></div> <div class="message-reaction-picker-anchor"></div>
`; `;
messagesList.appendChild(div); targetContainer.appendChild(div);
scrollToBottom(isMe); scrollToBottom(isMe);
// Ensure we scroll again when images/videos load // Ensure we scroll again when images/videos load

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

View File

@ -137,6 +137,10 @@ requireLogin();
$user = getCurrentUser(); $user = getCurrentUser();
$current_user_id = $user['id']; $current_user_id = $user['id'];
$messages = []; // Initialize messages array
$threads = [];
$rules = [];
$autoroles = [];
// Fetch servers user is member of // Fetch servers user is member of
$stmt = db()->prepare(" $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 = db()->prepare("SELECT * FROM channel_rules WHERE channel_id = ? ORDER BY position ASC");
$stmt->execute([$active_channel_id]); $stmt->execute([$active_channel_id]);
$rules = $stmt->fetchAll(); $rules = $stmt->fetchAll();
@ -293,7 +299,7 @@ if ($is_dm_view) {
$stmt->execute([$active_server_id, $active_server_id, $active_channel_id]); $stmt->execute([$active_server_id, $active_server_id, $active_channel_id]);
$threads = $stmt->fetchAll(); $threads = $stmt->fetchAll();
} else { } else {
// Fetch messages // Fetch messages for normal chat channels
$display_limit = !empty($active_channel['message_limit']) ? (int)$active_channel['message_limit'] : 50; $display_limit = !empty($active_channel['message_limit']) ? (int)$active_channel['message_limit'] : 50;
$stmt = db()->prepare(" $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 (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 FROM messages m
JOIN users u ON m.user_id = u.id 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 ORDER BY m.created_at ASC
LIMIT " . $display_limit . " LIMIT " . $display_limit . "
"); ");
@ -386,6 +392,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
window.canManageServer = <?php echo ($can_manage_server ?? false) ? 'true' : 'false'; ?>; window.canManageServer = <?php echo ($can_manage_server ?? false) ? 'true' : 'false'; ?>;
window.canManageChannels = <?php echo ($can_manage_channels ?? false) ? 'true' : 'false'; ?>; window.canManageChannels = <?php echo ($can_manage_channels ?? false) ? 'true' : 'false'; ?>;
window.activeChannelId = <?php echo $active_channel_id; ?>; window.activeChannelId = <?php echo $active_channel_id; ?>;
window.activeChannelType = "<?php echo $channel_type ?? 'chat'; ?>";
window.currentChannelName = "<?php echo addslashes($current_channel_name); ?>"; window.currentChannelName = "<?php echo addslashes($current_channel_name); ?>";
window.isDndMode = <?php echo ($user['dnd_mode'] ?? 0) ? 'true' : 'false'; ?>; window.isDndMode = <?php echo ($user['dnd_mode'] ?? 0) ? 'true' : 'false'; ?>;
window.soundNotifications = <?php echo ($user['sound_notifications'] ?? 0) ? 'true' : 'false'; ?>; window.soundNotifications = <?php echo ($user['sound_notifications'] ?? 0) ? 'true' : 'false'; ?>;
@ -1101,7 +1108,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
$show_input = true; $show_input = true;
if ($channel_type === 'rules') $show_input = false; if ($channel_type === 'rules') $show_input = false;
if ($channel_type === 'forum' && !$active_thread) $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 ($show_input):
if (!$can_send) { if (!$can_send) {

View File

@ -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: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: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: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: []