Canaux ok

This commit is contained in:
Flatlogic Bot 2026-02-15 16:49:18 +00:00
parent 7a52251131
commit 001690b707
5 changed files with 96 additions and 27 deletions

View File

@ -65,6 +65,37 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
exit;
}
if (isset($_GET['after_id'])) {
try {
$after_id = (int)$_GET['after_id'];
// 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("
SELECT m.*, u.username, 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
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, $channel_id, $after_id]);
$msgs = $stmt->fetchAll();
foreach ($msgs as &$m) {
$m['time'] = date('H:i', strtotime($m['created_at']));
$m['metadata'] = $m['metadata'] ? json_decode($m['metadata']) : null;
}
echo json_encode(['success' => true, 'messages' => $msgs]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
exit;
}
}
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
@ -213,11 +244,11 @@ try {
SELECT id FROM messages
WHERE channel_id = ?
ORDER BY created_at DESC, id DESC
LIMIT ?
LIMIT " . $limit . "
) as tmp
)
");
$stmt->execute([$channel_id, $channel_id, $limit]);
$stmt->execute([$channel_id, $channel_id]);
}
// Get server_id for the channel

View File

@ -382,7 +382,13 @@ body {
.message-author {
font-weight: bold;
font-size: 0.95em;
margin-bottom: 4px;
}
.message-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 2px;
}
.message-text {

View File

@ -86,6 +86,29 @@ document.addEventListener('DOMContentLoaded', () => {
}
connectWS();
// Polling as fallback for real-time
let lastMessageId = 0;
const findLastMessageId = () => {
const items = document.querySelectorAll('.message-item');
if (items.length > 0) {
lastMessageId = Math.max(...Array.from(items).map(i => parseInt(i.dataset.id) || 0));
}
};
findLastMessageId();
setInterval(async () => {
if (!currentChannel) return;
try {
const resp = await fetch(`api_v1_messages.php?channel_id=${currentChannel}&after_id=${lastMessageId}`);
const data = await resp.json();
if (data.success && data.messages && data.messages.length > 0) {
data.messages.forEach(msg => {
appendMessage(msg);
});
}
} catch (e) { }
}, 1000);
function showTyping(username) {
typingIndicator.textContent = `${username} is typing...`;
clearTimeout(typingTimeout);
@ -150,6 +173,8 @@ document.addEventListener('DOMContentLoaded', () => {
if (xhr.status === 200) {
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',
@ -158,9 +183,6 @@ document.addEventListener('DOMContentLoaded', () => {
channel_id: currentChannel
})
}));
} else {
appendMessage(result.message);
messagesList.scrollTop = messagesList.scrollHeight;
}
} else {
alert(result.error || 'Failed to send message');
@ -1384,7 +1406,6 @@ document.addEventListener('DOMContentLoaded', () => {
alert(result.error || 'Failed to save settings');
}
});
});
function escapeHTML(str) {
const div = document.createElement('div');
@ -1393,10 +1414,17 @@ document.addEventListener('DOMContentLoaded', () => {
}
function appendMessage(msg) {
if (!msg || !msg.id) return;
if (document.querySelector(`.message-item[data-id="${msg.id}"]`)) return;
const messagesList = document.getElementById('messages-list');
const div = document.createElement('div');
div.className = 'message-item';
div.dataset.id = msg.id;
if (parseInt(msg.id) > lastMessageId) {
lastMessageId = parseInt(msg.id);
}
const avatarStyle = msg.avatar_url ? `background-image: url('${msg.avatar_url}');` : '';
let attachmentHtml = '';
@ -1470,11 +1498,10 @@ document.addEventListener('DOMContentLoaded', () => {
div.innerHTML = `
<div class="message-avatar" style="${avatarStyle}"></div>
<div class="message-content">
<div class="message-author" style="${authorStyle}">
${escapeHTML(msg.username)}
<div class="message-header">
<span class="message-author" style="${authorStyle}">${escapeHTML(msg.username)}</span>
<span class="message-time">${msg.time}</span>
${pinnedBadge}
${actionsHtml}
</div>
<div class="message-text">
${escapeHTML(msg.content).replace(/\n/g, '<br>').replace(mentionRegex, `<span class="mention">@${window.currentUsername}</span>`)}
@ -1486,6 +1513,9 @@ document.addEventListener('DOMContentLoaded', () => {
<span class="add-reaction-btn" title="Add Reaction">+</span>
</div>
</div>
${actionsHtml}
`;
messagesList.appendChild(div);
messagesList.scrollTop = messagesList.scrollHeight;
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

View File

@ -602,8 +602,10 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
<div class="message-item <?php echo $is_mentioned ? 'mentioned' : ''; ?> <?php echo $m['is_pinned'] ? 'pinned' : ''; ?> <?php echo $channel_type === 'announcement' ? 'announcement-style' : ''; ?>" data-id="<?php echo $m['id']; ?>">
<div class="message-avatar" style="<?php echo $m['avatar_url'] ? "background-image: url('{$m['avatar_url']}');" : ""; ?>"></div>
<div class="message-content">
<div class="message-author" style="<?php echo !empty($m['role_color']) ? "color: {$m['role_color']};" : ""; ?>">
<?php echo htmlspecialchars($m['username']); ?>
<div class="message-header">
<span class="message-author" style="<?php echo !empty($m['role_color']) ? "color: {$m['role_color']};" : ""; ?>">
<?php echo htmlspecialchars($m['username']); ?>
</span>
<span class="message-time"><?php echo date('H:i', strtotime($m['created_at'])); ?></span>
<?php if ($m['is_pinned']): ?>
<span class="pinned-badge ms-2" title="Pinned Message">
@ -611,21 +613,6 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
Pinned
</span>
<?php endif; ?>
<?php if ($m['user_id'] == $current_user_id || ($active_server_id != 'dms' && $can_manage_channels)): ?>
<div class="message-actions-menu">
<span class="action-btn pin <?php echo $m['is_pinned'] ? 'active' : ''; ?>" title="<?php echo $m['is_pinned'] ? 'Unpin' : 'Pin'; ?>" data-id="<?php echo $m['id']; ?>" data-pinned="<?php echo $m['is_pinned']; ?>">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg>
</span>
<?php if ($m['user_id'] == $current_user_id): ?>
<span class="action-btn edit" title="Edit" data-id="<?php echo $m['id']; ?>">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</span>
<span class="action-btn delete" title="Delete" data-id="<?php echo $m['id']; ?>">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<div class="message-text">
<?php
@ -687,6 +674,21 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
<span class="add-reaction-btn" title="Add Reaction">+</span>
</div>
</div>
<?php if ($m['user_id'] == $current_user_id || ($active_server_id != 'dms' && $can_manage_channels)): ?>
<div class="message-actions-menu">
<span class="action-btn pin <?php echo $m['is_pinned'] ? 'active' : ''; ?>" title="<?php echo $m['is_pinned'] ? 'Unpin' : 'Pin'; ?>" data-id="<?php echo $m['id']; ?>" data-pinned="<?php echo $m['is_pinned'] ? '1' : '0'; ?>">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg>
</span>
<?php if ($m['user_id'] == $current_user_id): ?>
<span class="action-btn edit" title="Edit" data-id="<?php echo $m['id']; ?>">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</span>
<span class="action-btn delete" title="Delete" data-id="<?php echo $m['id']; ?>">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>