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