146 lines
5.3 KiB
JavaScript
146 lines
5.3 KiB
JavaScript
// server and channel management
|
|
|
|
async function loadServers() {
|
|
try {
|
|
const res = await fetch(`${API_URL}/servers`, {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
});
|
|
if (res.ok) {
|
|
servers = await res.json();
|
|
// seed lastSeen timestamps so we don't mark existing messages as unread
|
|
servers.forEach(s => {
|
|
s.channels.forEach(ch => {
|
|
const key = conversationKey('c', ch.id);
|
|
if (!lastSeen[key]) lastSeen[key] = Date.now();
|
|
});
|
|
});
|
|
renderServers();
|
|
if (servers.length > 0) {
|
|
selectServer(servers[0].id);
|
|
}
|
|
|
|
// Update Service Worker with channels list for background notifications
|
|
updateServiceWorkerChannels();
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading servers:', error);
|
|
}
|
|
}
|
|
|
|
function renderServers() {
|
|
const bar = document.getElementById('servers-bar');
|
|
bar.querySelectorAll('.server-icon').forEach(n => n.remove());
|
|
servers.forEach(s => {
|
|
const icon = document.createElement('div');
|
|
icon.className = 'server-icon';
|
|
icon.textContent = s.name.charAt(0).toUpperCase();
|
|
icon.onclick = () => selectServer(s.id);
|
|
bar.insertBefore(icon, document.getElementById('create-server-btn'));
|
|
});
|
|
}
|
|
|
|
function addChannelButton() {
|
|
const list = document.getElementById('channels-list');
|
|
let btn = document.getElementById('create-channel-btn');
|
|
if (!btn) {
|
|
btn = document.createElement('div');
|
|
btn.id = 'create-channel-btn';
|
|
btn.className = 'channel create-channel-btn';
|
|
btn.textContent = '+ create channel';
|
|
btn.onclick = async () => {
|
|
const name = prompt('Channel name:');
|
|
if (!name) return;
|
|
const res = await fetch(`${API_URL}/servers/${currentServerId}/channels`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
|
body: JSON.stringify({ name })
|
|
});
|
|
if (res.ok) {
|
|
const newch = await res.json();
|
|
const srv = servers.find(s=>s.id===currentServerId);
|
|
srv.channels.push(newch);
|
|
selectServer(currentServerId);
|
|
} else {
|
|
const err = await res.json();
|
|
alert(err.error || 'failed');
|
|
}
|
|
};
|
|
list.prepend(btn);
|
|
}
|
|
}
|
|
|
|
function selectServer(id) {
|
|
currentServerId = id;
|
|
const srv = servers.find(s => s.id === id);
|
|
document.querySelector('.server-name').textContent = srv.name;
|
|
const list = document.getElementById('channels-list');
|
|
list.innerHTML = '';
|
|
addChannelButton();
|
|
srv.channels.forEach(ch => {
|
|
const el = document.createElement('div');
|
|
el.className = 'channel';
|
|
el.textContent = '# ' + ch.name;
|
|
// badge
|
|
const count = unreadCounts[conversationKey('c', ch.id)];
|
|
if (count) {
|
|
const badge = document.createElement('span');
|
|
badge.className = 'unread-badge';
|
|
badge.textContent = count;
|
|
el.appendChild(badge);
|
|
}
|
|
el.onclick = () => selectChannel(ch.id, ch.name);
|
|
list.appendChild(el);
|
|
});
|
|
if (srv.channels.length>0) selectChannel(srv.channels[0].id, srv.channels[0].name);
|
|
messageInput.value = '';
|
|
}
|
|
|
|
function selectChannel(id, name) {
|
|
currentChannelId = id;
|
|
headerTitle.textContent = `#${name}`;
|
|
// clear current messages when switching channels to avoid mixed history
|
|
if (messagesContainer) messagesContainer.innerHTML = '';
|
|
lastFetchedTs = null;
|
|
isAtBottom = true; // reset scroll state for new conversation
|
|
currentDMUserId = null;
|
|
loadChannel(id);
|
|
document.querySelectorAll('.channel').forEach(ch => ch.classList.remove('active'));
|
|
const el = [...document.querySelectorAll('.channel')].find(n=>n.textContent.includes(name));
|
|
if(el) el.classList.add('active');
|
|
messageInput.value = '';
|
|
}
|
|
|
|
function selectGlobalChat() {
|
|
currentDMUserId = null;
|
|
headerTitle.textContent = 'Глобальный чат';
|
|
if (messagesContainer) messagesContainer.innerHTML = '';
|
|
lastFetchedTs = null;
|
|
isAtBottom = true; // reset scroll state for new conversation
|
|
currentChannelId = null;
|
|
loadGlobalChat();
|
|
document.querySelectorAll('.channel').forEach(ch => ch.classList.remove('active'));
|
|
document.querySelector('[data-channel="global"]').classList.add('active');
|
|
messageInput.value = '';
|
|
}
|
|
|
|
function initServerListeners() {
|
|
const btn = document.getElementById('create-server-btn');
|
|
if (btn) {
|
|
btn.addEventListener('click', async () => {
|
|
const name = prompt('Server name:');
|
|
if (!name) return;
|
|
const res = await fetch(`${API_URL}/servers`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type':'application/json', 'Authorization':`Bearer ${token}` },
|
|
body: JSON.stringify({name})
|
|
});
|
|
if (res.ok) {
|
|
loadServers();
|
|
} else {
|
|
const err = await res.json();
|
|
alert(err.error || 'failed');
|
|
}
|
|
});
|
|
}
|
|
}
|