document.addEventListener('DOMContentLoaded', () => { const chatForm = document.getElementById('chat-form'); const chatInput = document.getElementById('chat-input'); const messagesList = document.getElementById('messages-list'); // Scroll to bottom messagesList.scrollTop = messagesList.scrollHeight; // WebSocket for real-time let ws; try { ws = new WebSocket('ws://' + window.location.hostname + ':8080'); ws.onmessage = (e) => { const msg = JSON.parse(e.data); if (msg.type === 'message') { const data = JSON.parse(msg.data); // Simple broadcast, we check if it belongs to current channel const currentChannel = new URLSearchParams(window.location.search).get('channel_id') || 1; if (data.channel_id == currentChannel) { appendMessage(data); messagesList.scrollTop = messagesList.scrollHeight; } } }; } catch (e) { console.warn('WebSocket connection failed, falling back to REST only.'); } chatForm.addEventListener('submit', async (e) => { e.preventDefault(); const content = chatInput.value.trim(); if (!content) return; chatInput.value = ''; const channel_id = new URLSearchParams(window.location.search).get('channel_id') || 1; try { const response = await fetch('api_v1_messages.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: content, channel_id: channel_id }) }); const result = await response.json(); if (result.success) { // If WS is connected, we might want to let WS handle the UI update // But for simplicity, we append here and also send to WS if (ws && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'message', data: JSON.stringify({ ...result.message, channel_id: channel_id }) })); } else { appendMessage(result.message); messagesList.scrollTop = messagesList.scrollHeight; } } else { alert('Error: ' + result.error); } } catch (err) { console.error('Failed to send message:', err); } }); // Voice const voiceHandler = new VoiceChannel(ws); document.querySelectorAll('.voice-item').forEach(item => { item.addEventListener('click', () => { const cid = item.dataset.channelId; voiceHandler.join(cid); // UI Update document.querySelectorAll('.voice-item').forEach(i => i.classList.remove('active')); item.classList.add('active'); }); }); }); function appendMessage(msg) { const messagesList = document.getElementById('messages-list'); const div = document.createElement('div'); div.className = 'message-item'; div.innerHTML = `
${msg.username} ${msg.time}
${msg.content.replace(/\n/g, '
')}
`; messagesList.appendChild(div); } }); }); const result = await response.json(); if (result.success) { // If WS is connected, we might want to let WS handle the UI update // But for simplicity, we append here and also send to WS if (ws && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ ...result.message, channel_id: channel_id })); } else { appendMessage(result.message); messagesList.scrollTop = messagesList.scrollHeight; } } else { alert('Error: ' + result.error); } } catch (err) { console.error('Failed to send message:', err); } }); function appendMessage(msg) { const div = document.createElement('div'); div.className = 'message-item'; div.innerHTML = `
${msg.username} ${msg.time}
${msg.content.replace(/\n/g, '
')}
`; messagesList.appendChild(div); } });