Dnishe/static/js/servers.js
2026-06-08 21:56:14 +00:00

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');
}
});
}
}