// authentication related functions and event handling function showAuthScreen() { authScreen.style.display = 'flex'; chatScreen.style.display = 'none'; } function showChatScreen() { authScreen.style.display = 'none'; chatScreen.style.display = 'flex'; currentUserDisplay.textContent = `👤 ${username}`; loadServers(); loadFriends(); loadFriendRequests(); loadUsers(); // fetch profile to populate avatar and pronouns if needed if (typeof loadProfile === 'function') loadProfile(); startAutoRefresh(); // Request browser notification permission requestNotificationPermission().then(granted => { if (granted) { console.log('Notification permission granted'); } }); // Connect to SocketIO for real-time updates connectSocketIO(); } async function register() { const user = usernameInput.value.trim(); const pass = passwordInput.value.trim(); if (!user || !pass) { authMessage.textContent = 'Please fill in all fields'; authMessage.className = 'auth-message error'; return; } const code = window.prompt('Enter the one-time code (e.g. ABC-DEF-GHI):'); if (code === null || code.trim() === '') { return; } try { const res = await fetch(`${API_URL}/register`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: user, password: pass, invite_code: code.trim() }) }); const text = await res.text(); if (!text || text.trim() === '') { console.error('Empty response from server'); authMessage.textContent = 'Server error: Empty response'; authMessage.className = 'auth-message error'; return; } let data; try { data = JSON.parse(text); } catch (parseError) { console.error('Invalid JSON response:', text); authMessage.textContent = 'Server error: Invalid response format'; authMessage.className = 'auth-message error'; return; } if (res.ok) { token = data.token; userId = data.user_id; username = data.username; localStorage.setItem('token', token); localStorage.setItem('userId', userId); localStorage.setItem('username', username); authMessage.textContent = 'Registration successful!'; authMessage.className = 'auth-message success'; setTimeout(showChatScreen, 500); } else { authMessage.textContent = data.error || 'Registration failed'; authMessage.className = 'auth-message error'; } } catch (error) { authMessage.textContent = 'Error: ' + error.message; authMessage.className = 'auth-message error'; } } async function login() { const user = usernameInput.value.trim(); const pass = passwordInput.value.trim(); if (!user || !pass) { authMessage.textContent = 'Please fill in all fields'; authMessage.className = 'auth-message error'; return; } try { const res = await fetch(`${API_URL}/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: user, password: pass }) }); // Get response text first to check if it's valid JSON const text = await res.text(); // Check for empty response if (!text || text.trim() === '') { console.error('Empty response from server'); authMessage.textContent = 'Server error: Empty response'; authMessage.className = 'auth-message error'; return; } // Try to parse as JSON let data; try { data = JSON.parse(text); } catch (parseError) { console.error('Invalid JSON response:', text); authMessage.textContent = 'Server error: Invalid response format'; authMessage.className = 'auth-message error'; return; } if (res.ok) { token = data.token; userId = data.user_id; username = data.username; localStorage.setItem('token', token); localStorage.setItem('userId', userId); localStorage.setItem('username', username); authMessage.textContent = 'Login successful!'; authMessage.className = 'auth-message success'; setTimeout(showChatScreen, 500); } else { authMessage.textContent = data.error || 'Login failed'; authMessage.className = 'auth-message error'; } } catch (error) { authMessage.textContent = 'Error: ' + error.message; authMessage.className = 'auth-message error'; } } function logout() { localStorage.removeItem('token'); localStorage.removeItem('userId'); localStorage.removeItem('username'); token = null; userId = null; username = null; currentDMUserId = null; messageInput.value = ''; // Disconnect SocketIO and stop auto-refresh to prevent memory leaks disconnectSocketIO(); stopAutoRefresh(); showAuthScreen(); } // attach auth event listeners (called after vars are bound) function initAuthListeners() { loginBtn.addEventListener('click', login); registerBtn.addEventListener('click', register); logoutBtn.addEventListener('click', logout); } // check token on load function authInitCheck() { if (token) { showChatScreen(); } else { showAuthScreen(); } }