// global variables and constants let token = localStorage.getItem('token'); let userId = localStorage.getItem('userId'); let username = localStorage.getItem('username'); let currentDMUserId = null; let currentServerId = null; let currentChannelId = null; let servers = []; let friends = []; let allUsers = []; // reply functionality let replyToMessage = null; // { id, username, content } let replyToUsername = null; // unread message bookkeeping let lastSeen = {}; // key -> timestamp ms of last seen message let unreadCounts = {}; // key -> number of unread messages // notification state let notificationPermission = Notification.permission; let lastNotifiedMessages = {}; // key -> timestamp of last notified message function conversationKey(type, id) { // type 'c' for channel, 'd' for dm return `${type}${id}`; } const API_URL = '/api'; // relative base for flask backend // DOM elements (will be assigned after DOM ready) let authScreen, chatScreen; let usernameInput, passwordInput; let loginBtn, registerBtn, logoutBtn; let messagesContainer, messageInput, sendBtn, fileInput, attachBtn, filePreview, filePreviewText, filePreviewClear; let authMessage, currentUserDisplay, headerTitle; let dmList, friendsList, friendRequestsList; let addFriendBtn, addFriendModal, closeModal; let friendUsernameInput, modalAddBtn, modalError; let tabBtns, chatTab, friendsTab; let profileBtn, profileModal, profileAvatarInput, profileDescInput, profilePronounsInput, profileSaveBtn, profileCloseBtn; let userProfileModal, userProfileAvatar, userProfileUsername, userProfilePronouns, userProfileDescription; let userProfileAddFriendBtn, userProfileCloseBtn; // Reply functionality DOM elements let replyPreview, replyUsername, replyPreviewText, replyCancelBtn; // utility function available globally function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); } // Stub functions for Service Worker updates (prevent errors if sw not implemented) function updateServiceWorkerFriends() { // Placeholder - implement if Service Worker is used console.log('Service Worker friends update skipped'); } function updateServiceWorkerChannels() { // Placeholder - implement if Service Worker is used console.log('Service Worker channels update skipped'); }