zero_gpu_test / static /chat.js
vericudebuget's picture
Upload 7 files
9c72a28 verified
Raw
History Blame Contribute Delete
5.74 kB
let socket;
let username;
let sessionToken;
let nextId = 0;
let pendingMessages = {};
async function init() {
try {
const res = await fetch("/api/session");
const data = await res.json();
if (data.authenticated) {
username = data.username;
sessionToken = data.token;
showChat();
connectWebSocket();
} else {
showLogin();
}
} catch {
showLogin();
}
}
function showLogin() {
document.getElementById("auth-container").style.display = "block";
document.getElementById("login-form").style.display = "block";
document.getElementById("signup-form").style.display = "none";
document.getElementById("chat-app").style.display = "none";
document.getElementById("login-error").textContent = "";
}
function showSignup() {
document.getElementById("auth-container").style.display = "block";
document.getElementById("login-form").style.display = "none";
document.getElementById("signup-form").style.display = "block";
document.getElementById("chat-app").style.display = "none";
document.getElementById("signup-error").textContent = "";
}
function showChat() {
document.getElementById("auth-container").style.display = "none";
document.getElementById("chat-app").style.display = "block";
document.getElementById("display-username").textContent = username;
document.getElementById("chat-window").innerHTML = "";
}
async function handleLogin(e) {
e.preventDefault();
const login = e.target.login.value;
const password = e.target.password.value;
const error = document.getElementById("login-error");
try {
const res = await fetch("/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ login, password }),
});
const data = await res.json();
if (res.ok) {
username = data.username;
sessionToken = data.token;
showChat();
connectWebSocket();
} else {
error.textContent = data.error;
e.target.password.value = "";
}
} catch {
error.textContent = "Network error.";
}
}
async function handleSignup(e) {
e.preventDefault();
const email = e.target.email.value;
const usernameVal = e.target.username.value;
const password = e.target.password.value;
const confirm = e.target.confirm_password.value;
const error = document.getElementById("signup-error");
if (password !== confirm) {
error.textContent = "Passwords do not match.";
return;
}
try {
const res = await fetch("/api/signup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, username: usernameVal, password }),
});
const data = await res.json();
if (res.ok) {
username = data.username;
sessionToken = data.token;
showChat();
connectWebSocket();
} else {
error.textContent = data.error;
}
} catch {
error.textContent = "Network error.";
}
}
async function logout() {
if (socket) { socket.close(); socket = null; }
try { await fetch("/api/logout", { method: "POST" }); } catch {}
username = "";
sessionToken = "";
showLogin();
}
function connectWebSocket() {
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
const url = protocol + "//" + window.location.host + "/ws?token=" + encodeURIComponent(sessionToken);
socket = new WebSocket(url);
socket.onmessage = function (event) {
const data = JSON.parse(event.data);
const now = Date.now();
const win = document.getElementById("chat-window");
const el = document.createElement("div");
if (data.is_system) {
el.style.fontStyle = "italic";
el.style.color = "#ffcc00";
el.textContent = "[System] " + data.msg;
} else {
let text = data.user + ": " + data.msg;
if (data.user === username && pendingMessages[data.id] !== undefined) {
const rtt = now - pendingMessages[data.id];
text += " (rtt: " + rtt + "ms)";
delete pendingMessages[data.id];
} else if (data.server_time) {
const sp = now - data.server_time;
text += " (sping: " + sp + "ms)";
}
el.textContent = text;
}
win.appendChild(el);
win.scrollTop = win.scrollHeight;
};
socket.onclose = function (event) {
if (event.code === 4002) {
location.reload();
return;
}
const win = document.getElementById("chat-window");
if (win) {
const el = document.createElement("div");
el.style.fontStyle = "italic";
el.style.color = "#e94560";
if (event.code === 4001) {
el.textContent = "Session expired. Logging out...";
setTimeout(() => { logout(); }, 1500);
} else {
el.textContent = "Connection lost. Refresh the page.";
}
win.appendChild(el);
}
};
}
function sendMessage() {
if (!socket || socket.readyState !== WebSocket.OPEN) return;
const input = document.getElementById("message-input");
const msg = input.value.trim();
if (!msg) return;
const id = nextId++;
pendingMessages[id] = Date.now();
socket.send(JSON.stringify({ msg, id }));
input.value = "";
input.focus();
}
init();