From 564ad324175f22b5618744e9236dbda8e1b4ed5c Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Thu, 20 Nov 2025 16:29:10 -0300 Subject: [PATCH] . Adjust chat layout dimensions and remove context indicator Reduced footer height from 90px to 75px and adjusted related spacing throughout --- web/desktop/chat/chat.css | 48 ++++++-------------------------------- web/desktop/chat/chat.html | 11 --------- web/desktop/chat/chat.js | 48 +++++++++++++++++--------------------- web/desktop/index.html | 20 +++------------- web/desktop/js/layout.js | 48 ++++++++++++++++++++++++++++++++++---- 5 files changed, 76 insertions(+), 99 deletions(-) diff --git a/web/desktop/chat/chat.css b/web/desktop/chat/chat.css index 3b3fccb07..715310ed0 100644 --- a/web/desktop/chat/chat.css +++ b/web/desktop/chat/chat.css @@ -199,7 +199,7 @@ body::before { top: 0; left: 50%; transform: translateX(-50%); - bottom: 100px; + bottom: 75px; overflow-y: auto; overflow-x: hidden; padding: 80px 20px 40px; @@ -208,6 +208,7 @@ body::before { z-index: 1; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; + height: calc(100vh - 75px); } .message-container { margin-bottom: 24px; @@ -322,7 +323,7 @@ footer { z-index: 100; transition: all 0.3s; backdrop-filter: blur(20px); - height: 90px; + height: 75px; } .suggestions-container { display: flex; @@ -424,7 +425,7 @@ footer { } .scroll-to-bottom { position: fixed; - bottom: 80px; + bottom: 85px; right: 20px; width: 40px; height: 40px; @@ -476,37 +477,6 @@ footer { color: var(--bg); transform: translateY(-2px); } -.context-indicator { - position: fixed; - bottom: 130px; - right: 20px; - width: 120px; - border-radius: 12px; - padding: 10px; - font-size: 10px; - text-align: center; - z-index: 90; - background: var(--bg); - border: 1px solid var(--border); - display: none; - backdrop-filter: blur(10px); -} -.context-indicator.visible { - display: block; -} -.context-progress { - height: 3px; - background: var(--glass); - border-radius: 2px; - margin-top: 6px; - overflow: hidden; -} -.context-progress-bar { - height: 100%; - background: var(--accent); - border-radius: 2px; - transition: width 0.3s; -} .connection-status { position: fixed; top: 20px; @@ -706,7 +676,8 @@ footer { #messages { padding: 80px 16px 40px; top: 0; - bottom: 100px; + bottom: 75px; + height: calc(100vh - 75px); } .float-menu { left: 12px; @@ -721,12 +692,7 @@ footer { .scroll-to-bottom { width: 36px; height: 36px; - bottom: 70px; + bottom: 85px; right: 12px; } - .context-indicator { - bottom: 120px; - right: 12px; - width: 100px; - } } diff --git a/web/desktop/chat/chat.html b/web/desktop/chat/chat.html index bfea4a1f9..43899e9c3 100644 --- a/web/desktop/chat/chat.html +++ b/web/desktop/chat/chat.html @@ -16,15 +16,4 @@ -
-
Context
-
0%
-
-
-
- diff --git a/web/desktop/chat/chat.js b/web/desktop/chat/chat.js index 8861f0030..b54e5c69f 100644 --- a/web/desktop/chat/chat.js +++ b/web/desktop/chat/chat.js @@ -55,9 +55,6 @@ function chatApp() { sidebar, themeBtn, scrollToBottomBtn, - contextIndicator, - contextPercentage, - contextProgressBar, sidebarTitle; marked.setOptions({ breaks: true, gfm: true }); @@ -194,9 +191,6 @@ function chatApp() { sidebar = document.getElementById("sidebar"); themeBtn = document.getElementById("themeBtn"); scrollToBottomBtn = document.getElementById("scrollToBottom"); - contextIndicator = document.getElementById("contextIndicator"); - contextPercentage = document.getElementById("contextPercentage"); - contextProgressBar = document.getElementById("contextProgressBar"); sidebarTitle = document.getElementById("sidebarTitle"); // Theme initialization and focus @@ -250,14 +244,6 @@ function chatApp() { }); }, - updateContextUsage(u) { - contextUsage = u; - const p = Math.min(100, Math.round(u * 100)); - contextPercentage.textContent = `${p}%`; - contextProgressBar.style.width = `${p}%`; - contextIndicator.classList.remove("visible"); - }, - flashScreen() { gsap.to(flashOverlay, { opacity: 0.15, @@ -355,7 +341,6 @@ function chatApp() { this.loadSessions(); messagesDiv.innerHTML = ""; this.clearSuggestions(); - this.updateContextUsage(0); if (isVoiceMode) { await this.stopVoiceSession(); isVoiceMode = false; @@ -469,9 +454,6 @@ function chatApp() { return; } - if (r.context_usage !== undefined) { - this.updateContextUsage(r.context_usage); - } if (r.suggestions && r.suggestions.length > 0) { this.handleSuggestions(r.suggestions); } @@ -516,7 +498,7 @@ function chatApp() { this.showWarning(d.message); break; case "context_usage": - this.updateContextUsage(d.usage); + // Context usage removed break; case "change_theme": if (d.color1) themeColor1 = d.color1; @@ -632,10 +614,8 @@ function chatApp() { m.className = "message-container"; if (role === "user") { m.innerHTML = `
${this.escapeHtml(content)}
`; - this.updateContextUsage(contextUsage + 0.05); } else if (role === "assistant") { m.innerHTML = `
${streaming ? "" : marked.parse(content)}
`; - this.updateContextUsage(contextUsage + 0.03); } else if (role === "voice") { m.innerHTML = `
🎤
${content}
`; } else { @@ -728,10 +708,6 @@ function chatApp() { ws.send(JSON.stringify(s)); }); await pendingContextChange; - const x = document.getElementById("contextIndicator"); - if (x) { - document.getElementById("contextPercentage").textContent = c; - } } else { console.warn("WebSocket não está conectado. Tentando reconectar..."); this.connectWebSocket(); @@ -948,7 +924,6 @@ function chatApp() { toggleSidebar: toggleSidebar, toggleTheme: toggleTheme, applyTheme: applyTheme, - updateContextUsage: updateContextUsage, flashScreen: flashScreen, updateConnectionStatus: updateConnectionStatus, getWebSocketUrl: getWebSocketUrl, @@ -979,6 +954,16 @@ function chatApp() { startVoiceRecording: startVoiceRecording, simulateVoiceTranscription: simulateVoiceTranscription, scrollToBottom: scrollToBottom, + cleanup: function () { + // Cleanup WebSocket connection + if (ws) { + ws.close(); + ws = null; + } + // Clear any pending timeouts/intervals + isConnecting = false; + isInitialized = false; + }, }; // Cache and return the singleton instance @@ -988,3 +973,14 @@ function chatApp() { // Initialize the app chatApp().init(); + +// Listen for section changes to cleanup when leaving chat +document.addEventListener("section-hidden", function (e) { + if ( + e.target.id === "section-chat" && + chatAppInstance && + chatAppInstance.cleanup + ) { + chatAppInstance.cleanup(); + } +}); diff --git a/web/desktop/index.html b/web/desktop/index.html index f4a996437..c211e9d6b 100644 --- a/web/desktop/index.html +++ b/web/desktop/index.html @@ -51,9 +51,8 @@ .logo-wrapper { display: flex; align-items: center; - gap: 12px; cursor: pointer; - padding: 8px 12px; + padding: 8px; border-radius: 12px; transition: all 0.3s; background: rgba(255, 255, 255, 0.9); @@ -67,8 +66,8 @@ } .logo-icon { - width: 32px; - height: 32px; + width: 36px; + height: 36px; background: url("https://pragmatismo.com.br/icons/general-bots.svg") center/contain no-repeat; } @@ -298,7 +297,6 @@
-
General Bots
@@ -344,18 +342,6 @@
Mail - -
📅
- Calendar -
- -
📝
- Notes -
diff --git a/web/desktop/js/layout.js b/web/desktop/js/layout.js index 60cdf969a..de7342ee4 100644 --- a/web/desktop/js/layout.js +++ b/web/desktop/js/layout.js @@ -34,6 +34,20 @@ async function loadSectionHTML(path) { async function switchSection(section) { const mainContent = document.getElementById("main-content"); + // Validate section exists + if (!sections[section]) { + console.warn(`Section "${section}" does not exist, defaulting to chat`); + section = "chat"; + } + + // Clean up any existing WebSocket connections from chat + if ( + window.chatAppInstance && + typeof window.chatAppInstance.cleanup === "function" + ) { + window.chatAppInstance.cleanup(); + } + try { const htmlPath = sections[section]; console.log("Loading section:", section, "from", htmlPath); @@ -78,6 +92,11 @@ async function switchSection(section) { }); targetDiv.style.display = "block"; } else { + // Remove any existing loading divs first + container.querySelectorAll(".loading").forEach((div) => { + div.remove(); + }); + // Show loading placeholder inside the container const loadingDiv = document.createElement("div"); loadingDiv.className = "loading"; @@ -95,15 +114,22 @@ async function switchSection(section) { // Hide any existing sections container.querySelectorAll(".section").forEach((div) => { div.style.display = "none"; + // Dispatch a custom event to notify sections they're being hidden + div.dispatchEvent(new CustomEvent("section-hidden")); }); - // Remove loading placeholder - container.removeChild(loadingDiv); + // Remove loading placeholder if it still exists + if (loadingDiv && loadingDiv.parentNode) { + container.removeChild(loadingDiv); + } // Add the new section to the container and cache it container.appendChild(wrapper); sectionCache[section] = wrapper; + // Dispatch a custom event to notify the section it's being shown + wrapper.dispatchEvent(new CustomEvent("section-shown")); + // Ensure the new section is visible with a fast GSAP fade-in gsap.fromTo( wrapper, @@ -178,13 +204,27 @@ function getInitialSection() { window.addEventListener("DOMContentLoaded", () => { // Small delay to ensure all resources are loaded setTimeout(() => { - switchSection(getInitialSection()); + const section = getInitialSection(); + // Ensure valid section + if (!sections[section]) { + window.location.hash = "#chat"; + switchSection("chat"); + } else { + switchSection(section); + } }, 50); }); // Handle browser back/forward navigation window.addEventListener("popstate", () => { - switchSection(getInitialSection()); + const section = getInitialSection(); + // Ensure valid section + if (!sections[section]) { + window.location.hash = "#chat"; + switchSection("chat"); + } else { + switchSection(section); + } }); // Make switchSection globally accessible