Canaux ok
This commit is contained in:
parent
7a52251131
commit
001690b707
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
BIN
assets/pasted-20260215-162151-f0d79b58.png
Normal file
BIN
assets/pasted-20260215-162151-f0d79b58.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 213 KiB |
36
index.php
36
index.php
@ -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; ?>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user