. Adjust chat layout dimensions and remove context indicator
Reduced footer height from 90px to 75px and adjusted related spacing throughout
This commit is contained in:
parent
8c2b17c615
commit
564ad32417
5 changed files with 76 additions and 99 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,4 @@
|
|||
</div>
|
||||
</footer>
|
||||
<button class="scroll-to-bottom" id="scrollToBottom">↓</button>
|
||||
<div class="context-indicator" id="contextIndicator">
|
||||
<div>Context</div></div>
|
||||
<div id="contextPercentage">0%</div>
|
||||
<div class="context-progress">
|
||||
<div
|
||||
class="context-progress-bar"
|
||||
id="contextProgressBar"
|
||||
style="width: 0%"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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 = `<div class="user-message"><div class="user-message-content">${this.escapeHtml(content)}</div></div>`;
|
||||
this.updateContextUsage(contextUsage + 0.05);
|
||||
} else if (role === "assistant") {
|
||||
m.innerHTML = `<div class="assistant-message"><div class="assistant-avatar"></div><div class="assistant-message-content markdown-content" id="${msgId || ""}">${streaming ? "" : marked.parse(content)}</div></div>`;
|
||||
this.updateContextUsage(contextUsage + 0.03);
|
||||
} else if (role === "voice") {
|
||||
m.innerHTML = `<div class="assistant-message"><div class="assistant-avatar">🎤</div><div class="assistant-message-content">${content}</div></div>`;
|
||||
} 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();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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 @@
|
|||
<div class="header-left">
|
||||
<div class="logo-wrapper" onclick="window.location.reload()">
|
||||
<div class="logo-icon"></div>
|
||||
<div class="logo-text">General Bots</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -344,18 +342,6 @@
|
|||
<div class="app-icon">✉</div>
|
||||
<span>Mail</span>
|
||||
</a>
|
||||
<a
|
||||
class="app-item"
|
||||
href="#calendar"
|
||||
data-section="calendar"
|
||||
>
|
||||
<div class="app-icon">📅</div>
|
||||
<span>Calendar</span>
|
||||
</a>
|
||||
<a class="app-item" href="#notes" data-section="notes">
|
||||
<div class="app-icon">📝</div>
|
||||
<span>Notes</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-avatar" id="userAvatar" title="User Account">
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue