transient.chat/static/assets/js/server_list.js

233 lines
No EOL
8.9 KiB
JavaScript

document.addEventListener("DOMContentLoaded", async () => {
const username = localStorage.getItem('username');
const userKey = localStorage.getItem('userKey');
if (!username || !userKey) {
window.location.href = '/';
return;
}
try {
const response = await fetch('/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, key: userKey })
});
if (!response.ok) {
localStorage.clear();
window.location.href = '/';
return;
}
} catch (err) {
console.error('Validation failed:', err);
localStorage.clear();
window.location.href = '/';
return;
}
function escapeHtml(text) {
if (!text) return text;
return text
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
const userInfoEl = document.getElementById('user-info');
userInfoEl.style.display = 'flex';
userInfoEl.style.alignItems = 'center';
userInfoEl.style.justifyContent = 'flex-start';
userInfoEl.style.gap = '15px';
userInfoEl.style.marginBottom = '20px';
const logoutBtn = document.createElement('button');
logoutBtn.textContent = 'Logout';
logoutBtn.style.backgroundColor = '#d9534f';
logoutBtn.style.color = 'white';
logoutBtn.style.border = 'none';
logoutBtn.style.padding = '6px 12px';
logoutBtn.style.borderRadius = '4px';
logoutBtn.style.cursor = 'pointer';
logoutBtn.onclick = async () => {
if (confirm("Are you sure you want to logout? This will release your username immediately.")) {
try {
await fetch('/logout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, key: userKey })
});
} catch (e) {
console.error("Logout request failed:", e);
}
localStorage.clear();
window.location.href = '/';
}
};
const userSpan = document.createElement('span');
userSpan.innerHTML = `Logged in as: <strong>${escapeHtml(username)}</strong>`;
userInfoEl.append(logoutBtn, userSpan);
document.querySelectorAll('.collapsible').forEach(heading => {
heading.addEventListener('click', () => {
const content = heading.nextElementSibling;
const isOpen = content.style.display === 'block';
content.style.display = isOpen ? 'none' : 'block';
heading.textContent = (isOpen ? '▶' : '▼') + heading.textContent.slice(1);
});
});
fetch("/rooms")
.then(response => response.json())
.then(data => {
const { regional, topical, public: publicRooms, unique_users } = data;
const regionalList = document.getElementById('regional-rooms');
const topicalList = document.getElementById('topical-rooms');
const publicList = document.getElementById('public-rooms');
const watchpartyList = document.getElementById('watchparty-rooms');
// Helper to create a room <li>
function createRoomItem({ name, users, type }) {
const li = document.createElement('li');
const a = document.createElement('a');
const isWatchParty = type && type.startsWith('watchparty');
a.href = isWatchParty
? `/watchparty_chat.html?room=${encodeURIComponent(name)}`
: `/chat.html?room=${encodeURIComponent(name)}`;
a.textContent = `${name} ( ${users} )`;
li.appendChild(a);
return { li, isWatchParty };
}
// Add regional rooms
regional.forEach(room => {
regionalList.appendChild(createRoomItem(room).li);
});
// Add topical rooms
topical.forEach(room => {
topicalList.appendChild(createRoomItem(room).li);
});
// Add public/watchparty rooms
publicRooms.forEach(room => {
const { li, isWatchParty } = createRoomItem(room);
if (isWatchParty) {
watchpartyList.appendChild(li);
} else {
publicList.appendChild(li);
}
});
// Show total unique user count
document.getElementById('user-count').textContent = `Users Chatting ( ${unique_users} )`;
// 🧠 Load and render Active Rooms (regional, topical, public w/ users)
fetch("/rooms?activeOnly=true")
.then(response => response.json())
.then(({ regional, topical, public: publicRooms }) => {
const activeList = document.getElementById("active-rooms");
let count = 0;
function createActiveRoomItem({ name, users, type }) {
const li = document.createElement("li");
const a = document.createElement("a");
a.href = type === "watchparty"
? `/watchparty_chat.html?room=${encodeURIComponent(name)}`
: `/chat.html?room=${encodeURIComponent(name)}`;
a.textContent = `${name} ( ${users} )`;
li.appendChild(a);
return li;
}
[...regional, ...topical, ...publicRooms].forEach(room => {
activeList.appendChild(createActiveRoomItem(room));
count++;
});
// Update Active Rooms heading with count
const activeHeadingEl = document.getElementById("active-rooms-header");
if (activeHeadingEl) {
const baseText = activeHeadingEl.textContent.replace(/▶|▼|\(\d+\)/g, "").trim();
activeHeadingEl.textContent = `${baseText} ( ${count} )`;
}
})
.catch(err => {
console.error("Failed to load active rooms:", err);
});
})
.catch(err => {
console.error("Failed to load rooms:", err);
alert("Failed to load rooms.");
});
document.getElementById('create-room-btn').addEventListener('click', () => {
const roomName = document.getElementById('new-room-name').value.trim();
if (!roomName) return alert('Room name cannot be empty.');
fetch('/rooms', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: roomName })
})
.then(response => {
if (!response.ok) throw new Error('Room creation failed.');
return response.json();
})
.then(data => {
window.location.href = `/chat.html?room=${encodeURIComponent(data.name)}`;
})
.catch(err => alert(err.message));
});
document.getElementById('create-unlisted-room-btn').addEventListener('click', () => {
const roomName = document.getElementById('new-room-name').value.trim();
if (!roomName) return alert('Room name cannot be empty.');
window.location.href = `/chat.html?room=${encodeURIComponent(roomName)}`;
});
// 🔥 Watch Party creation
document.getElementById('create-watchparty-btn').addEventListener('click', () => {
const roomName = document.getElementById('new-room-name').value.trim();
if (!roomName) return alert('Room name cannot be empty.');
fetch('/rooms', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: roomName })
})
.then(response => {
if (!response.ok) throw new Error('Watch party creation failed.');
return response.json();
})
.then(data => {
window.location.href = `/watchparty_chat.html?room=${encodeURIComponent(data.name)}`;
})
.catch(err => alert(err.message));
});
});
// Enable Enter key for room creation
document.getElementById('new-room-name').addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
document.getElementById('create-room-btn').click();
}
});
// Enable Enter key for watch party creation
document.getElementById('new-room-name').addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
document.getElementById('create-watchparty-btn').click();
}
});
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
window.location.reload();
}
});