function toggleSettings() { const panel = document.getElementById("settings-panel"); panel.style.display = panel.style.display === "none" ? "block" : "none"; if (panel.style.display === "block") { const username = document.getElementById("username"); username.focus(); username.selectionStart = username.selectionEnd = username.value .length; } } function toggleUsers() { const panel = document.getElementById("users-panel"); panel.style.display = panel.style.display === "none" ? "block" : "none"; } document.addEventListener("click", function (event) { const settingsPanel = document.getElementById("settings-panel"); const settingsButton = document.querySelector(".settings-button"); const usersPanel = document.getElementById("users-panel"); const usersButton = document.querySelector(".users-button"); if ( !settingsPanel.contains(event.target) && !settingsButton.contains(event.target) ) { settingsPanel.style.display = "none"; } if ( !usersPanel.contains(event.target) && !usersButton.contains(event.target) ) { usersPanel.style.display = "none"; } }); document.addEventListener("keypress", function (event) { if (event.key === "Enter" && !event.shiftKey) { const settingsPanel = document.getElementById("settings-panel"); const inputPanel = document.getElementById("message"); if (settingsPanel.contains(event.target)) { setUsername(); } if (inputPanel.contains(event.target)) { event.preventDefault(); sendMessage(); } } }); document.addEventListener("input", function (event) { const msg = document.getElementById("message"); msg.style.height = "auto"; msg.style.height = (msg.scrollHeight) + "px"; }); async function loadUsers() { try { const response = await fetch("/users"); const data = await response.json(); const usersList = document.getElementById("users-list"); usersList.innerHTML = ""; data.users.sort().forEach((user) => { const userDiv = document.createElement("div"); userDiv.className = "user-item"; userDiv.textContent = user; usersList.appendChild(userDiv); }); } catch (error) { console.error("Error loading users:", error); } } let lastMessageCount = 0; async function loadMessages() { try { const messagesDiv = document.getElementById("messages"); const response = await fetch("/messages"); const text = await response.text(); const tempDiv = document.createElement("div"); tempDiv.innerHTML = text; if (messagesDiv.scrollTop != bottom) { // show a button to scroll to the bottom const scrollToBottomButton = document.getElementById( "scroll", ); scrollToBottomButton.style.display = "block"; scrollToBottomButton.onclick = scrollToBottom; } else { // hide the button const scrollToBottomButton = document.getElementById( "scroll", ); scrollToBottomButton.style.display = "none"; } const messages = tempDiv.getElementsByTagName("p"); const newMessageCount = messages.length; if ( newMessageCount > lastMessageCount || lastMessageCount === 0 ) { messagesDiv.innerHTML = ""; Array.from(messages).forEach((msg) => { const messageDiv = document.createElement( "div", ); messageDiv.className = "message"; const [username, content] = msg.innerHTML.split( "
", ); messageDiv.innerHTML = '
' + username + "
" + '
' + content + "
"; messagesDiv.appendChild(messageDiv); }); scrollToBottom(); lastMessageCount = newMessageCount; } } catch (error) { console.error("Error loading messages:", error); } } var bottom = 0; function scrollToBottom() { const messagesDiv = document.getElementById("messages"); messagesDiv.scrollTop = messagesDiv.scrollHeight; bottom = messagesDiv.scrollTop; } async function checkUsername() { try { const response = await fetch("/username/status"); const data = await response.json(); if (!data.hasUsername) { document.getElementById("settings-panel").style .display = "block"; const username = document.getElementById("username"); username.focus(); username.selectionStart = username.selectionEnd = username.value.length; } } catch (error) { console.error("Error checking username status:", error); } } async function updateCurrentUser() { try { const response = await fetch("/username/status"); const data = await response.json(); const userDiv = document.getElementById("current-user"); if (data.hasUsername) { userDiv.textContent = data.username; } else { userDiv.textContent = ""; } } catch (error) { console.error("Error getting username:", error); } } async function setUsername() { const username = document.getElementById("username").value; if (!username) { showUsernameStatus("Please enter a username", "red"); return; } try { const response = await fetch("/username", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ username: username }), }); const data = await response.json(); if (response.ok) { showUsernameStatus( "Username set successfully!", "green", ); updateCurrentUser(); setTimeout(() => { document.getElementById("settings-panel").style .display = "none"; }, 500); location.reload(); } else { showUsernameStatus( data.error || "Failed to set username", "red", ); } } catch (error) { showUsernameStatus("Error connecting to server", "red"); } } async function sendMessage() { const messageInput = document.getElementById("message"); const message = messageInput.value; if (!message) { return; } try { const response = await fetch("/messages", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ message: message }), }); const data = await response.json(); if (response.ok) { messageInput.value = ""; messageInput.style.height = "auto"; loadMessages(); } else { showStatus( data.error || "Failed to send message", "red", ); } } catch (error) { showStatus("Error connecting to server", "red"); } } function showStatus(message, color) { const status = document.getElementById("status"); status.textContent = message; status.style.color = color; setTimeout(() => { status.textContent = ""; }, 3000); } function showUsernameStatus(message, color) { const status = document.getElementById("username-status"); status.textContent = message; status.style.color = color; setTimeout(() => { status.textContent = ""; }, 3000); } async function pingCheck() { try { await fetch("/ping", { method: "POST" }); } catch (error) { console.error("Ping failed:", error); } } async function timeZoneCheck() { try { const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; const response = await fetch("/timezone", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ timezone: timeZone }), }); const data = await response.json(); console.log(data); } catch (error) { console.error("Error checking timezone:", error); } } async function initialize() { await loadMessages(); document.getElementById("users-panel").style.display = "none"; document.getElementById("settings-panel").style.display = "none"; checkUsername(); updateCurrentUser(); setInterval(loadMessages, 1000); setInterval(loadUsers, 1000); setInterval(pingCheck, 3000); scrollToBottom(); } initialize();