148 lines
5.1 KiB
JavaScript
148 lines
5.1 KiB
JavaScript
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 = `
|
|
<div class="message-avatar"></div>
|
|
<div class="message-content">
|
|
<div class="message-author">
|
|
${msg.username}
|
|
<span class="message-time">${msg.time}</span>
|
|
</div>
|
|
<div class="message-text">
|
|
${msg.content.replace(/\n/g, '<br>')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
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 = `
|
|
<div class="message-avatar"></div>
|
|
<div class="message-content">
|
|
<div class="message-author">
|
|
${msg.username}
|
|
<span class="message-time">${msg.time}</span>
|
|
</div>
|
|
<div class="message-text">
|
|
${msg.content.replace(/\n/g, '<br>')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
messagesList.appendChild(div);
|
|
}
|
|
});
|