diff --git a/static/app.js b/static/app.js index f6a450a..88d9f0f 100644 --- a/static/app.js +++ b/static/app.js @@ -1,3 +1,30 @@ +/* + RadChat Frontend (static/app.js) + + Overview: + - Single-page application handling UI, signaling (WebSocket), and media (WebRTC). + - Uses a central CONFIG object (frozen) to define defaults for output, media, and connection. + - Manages: + * WebSocket connection lifecycle (reconnect, pings, presence) + * WebRTC peer connections (offers/answers/ICE, track management) + * UI state: users list, chat pane, emoji picker, file uploads, audio controls + * Permissions and device selection (planned for settings UI) + + Key Endpoints (see backend): + - /ws: signaling channel (JSON messages matching message.go) + - /files: POST uploads; /files/{id}: GET downloads + - /check-username and /user-count auxiliary endpoints + + Configuration: + - Adjust CONFIG.CONN.RTC_CONFIGURATION.iceServers to set STUN/TURN. + - For relay-only networks, consider setting iceTransportPolicy to "relay". + + Notes: + - Keep JSON envelope fields in sync with message.go to avoid wire format drift. + - Avoid heavy DOM queries in hot paths; use cached selectors where possible. + - Large file; consider future modularization by feature (chat, rtc, ui, files). +*/ + // ==================== CONFIGURATION ==================== // noinspection HtmlUnknownTarget function Fz(obj) { @@ -15,7 +42,7 @@ const CONFIG = Fz({ NOISE_SUPPRESSION: true, LATENCY: 0.01, LATENCY_HINT: 'interactive', - SAMPLE_RATE: 64000, + SAMPLE_RATE: 96000, DEVICE_ID: 'default', SPEAKING_THRESHOLD: 10, SPEAKING_TIMEOUT: 500, @@ -54,7 +81,7 @@ const CONFIG = Fz({ CONNECTED_USER_LIMIT: 10, SAVE_RATE_THROTTLE: 1000, SYSTEM_MSG_DEFAULT_TIMEOUT: 5000, - FILE_UPLOAD_SIZE_LIMIT: 128 * (1024 * 1024), + FILE_UPLOAD_SIZE_LIMIT: 256 * (1024 * 1024), } }); @@ -441,17 +468,24 @@ class UIManager { formData.append('client_id', state.currentId) try { + // Uploading files system message + const alertMessage = ChatManager.addChatAlert('Uploading file(s)...', 'upload'); + const response = await fetch('/files', { method: 'POST', body: formData }); if (response.ok) { + alertMessage.remove(); const data = await response.json(); console.log('Upload successful:', data); } else { + alertMessage.remove(); + ChatManager.addChatAlert(`Upload failed: ${error}`, 'upload_failure', 3000); console.error('Upload failed:', response.statusText); } } catch (error) { + ChatManager.addChatAlert(`Upload failed: ${error}`, 'upload_failure', 3000); console.error('Upload error:', error); } }, { once: true }); @@ -1634,7 +1668,7 @@ class ChatManager { UIManager.scrollChatToBottom(); console.log('Added chat message from:', data.username, 'message:', message); } - static addChatAlert(message, type, timeout) { + static addChatAlert(message, type, timeout) { const chatMessages = $id('chat-messages'); if (!chatMessages) return; const alertEl = document.createElement('div'); @@ -1659,6 +1693,7 @@ class ChatManager { chatMessages.appendChild(alertEl); UIManager.scrollChatToBottom(); console.log('📢 Added chat alert:', message); + return alertEl; } static deleteMessage(messageId) {