Update app.py
Browse files
app.py
CHANGED
|
@@ -10,7 +10,7 @@ tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
| 10 |
model = AutoModelForCausalLM.from_pretrained(model_name)
|
| 11 |
|
| 12 |
# Function to generate chatbot response
|
| 13 |
-
def get_chatbot_response(user_input: str, max_length=
|
| 14 |
if not user_input:
|
| 15 |
return "Please say something!"
|
| 16 |
|
|
@@ -28,7 +28,7 @@ def get_chatbot_response(user_input: str, max_length=100):
|
|
| 28 |
response = tokenizer.decode(chat_history_ids[:, input_ids.shape[-1]:][0], skip_special_tokens=True)
|
| 29 |
return response.strip()
|
| 30 |
|
| 31 |
-
# HTML, CSS, and JS
|
| 32 |
HTML_CONTENT = """
|
| 33 |
<!DOCTYPE html>
|
| 34 |
<html lang="en">
|
|
@@ -49,16 +49,17 @@ HTML_CONTENT = """
|
|
| 49 |
--placeholder-color: #78797A; --accent-color: #00A3FF; --star-color: #FFFFFF;
|
| 50 |
--background-color: #000; --error-color: #FF4D4D; --success-color: #4CAF50;
|
| 51 |
}
|
| 52 |
-
.
|
| 53 |
-
--primary-color:
|
| 54 |
-
--
|
| 55 |
-
--
|
| 56 |
-
--
|
| 57 |
-
--
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
--
|
| 61 |
-
--
|
|
|
|
| 62 |
}
|
| 63 |
body {
|
| 64 |
min-height: 100vh; display: flex; flex-direction: row; justify-content: space-between;
|
|
@@ -67,15 +68,11 @@ HTML_CONTENT = """
|
|
| 67 |
.stars {
|
| 68 |
position: fixed; width: 100%; height: 100%;
|
| 69 |
background: url('https://www.transparenttextures.com/patterns/stardust.png');
|
| 70 |
-
animation: starsAnim 100s linear infinite; z-index: -1; transition: opacity 0.3s ease;
|
| 71 |
-
}
|
| 72 |
-
.light_mode .stars {
|
| 73 |
-
background: url('https://www.transparenttextures.com/patterns/stardust.png') rgba(245, 245, 245, 0.4);
|
| 74 |
-
opacity: 0.2;
|
| 75 |
}
|
| 76 |
-
.
|
| 77 |
-
background: url('https://www.transparenttextures.com/patterns/stardust.png') rgba(
|
| 78 |
-
opacity: 0.
|
| 79 |
}
|
| 80 |
@keyframes starsAnim { from { background-position: 0 0; } to { background-position: 10000px 10000px; } }
|
| 81 |
@keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } }
|
|
@@ -85,24 +82,23 @@ HTML_CONTENT = """
|
|
| 85 |
align-items: center; padding: 1rem 0; position: fixed; left: 0; top: 0; transition: width 0.3s ease; z-index: 1001;
|
| 86 |
}
|
| 87 |
.sidebar:hover { width: 200px; }
|
|
|
|
| 88 |
.sidebar__item {
|
| 89 |
width: 100%; padding: 1rem; color: var(--text-secondary-color); text-decoration: none;
|
| 90 |
display: flex; align-items: center; gap: 1rem; transition: all 0.3s ease; position: relative;
|
| 91 |
}
|
| 92 |
-
.sidebar__item:hover {
|
| 93 |
background: var(--secondary-hover-color); color: var(--accent-color); padding-left: 1.5rem; transform: scale(1.05);
|
| 94 |
}
|
| 95 |
.sidebar__item i { font-size: 1.5rem; }
|
| 96 |
.sidebar__item span { display: none; font-size: 1rem; }
|
| 97 |
.sidebar:hover .sidebar__item span { display: inline; }
|
| 98 |
-
.light_mode .sidebar { background: rgba(240, 236, 248, 0.95); }
|
| 99 |
-
.starry_night .sidebar { background: rgba(46, 59, 62, 0.95); }
|
| 100 |
.tooltip {
|
| 101 |
visibility: hidden; background: var(--secondary-color); color: var(--text-color); font-size: 0.8rem;
|
| 102 |
padding: 0.5rem; border-radius: 0.3rem; position: absolute; top: -30px; left: 50%; transform: translateX(-50%);
|
| 103 |
white-space: nowrap; z-index: 1002; transition: visibility 0.2s, opacity 0.2s; opacity: 0;
|
| 104 |
}
|
| 105 |
-
.sidebar__item:hover .tooltip { visibility: visible; opacity: 1; }
|
| 106 |
.main-content {
|
| 107 |
flex: 1; display: flex; flex-direction: column; padding-bottom: 100px; padding-top: 2rem; margin-left: 70px;
|
| 108 |
height: 100vh; overflow: hidden;
|
|
@@ -130,24 +126,20 @@ HTML_CONTENT = """
|
|
| 130 |
border-radius: 0.5rem; cursor: pointer; transition: all 0.3s ease; border: 1px solid var(--focus-color);
|
| 131 |
position: relative;
|
| 132 |
}
|
| 133 |
-
.
|
| 134 |
-
.
|
| 135 |
-
.suggests__item:hover {
|
| 136 |
background: var(--secondary-hover-color); border-color: var(--accent-color); color: var(--text-color);
|
| 137 |
transform: translateY(-3px);
|
| 138 |
}
|
| 139 |
.suggests__item-icon { margin-top: 1rem; color: var(--accent-color); transition: transform 0.2s ease; }
|
| 140 |
-
.suggests__item:hover .suggests__item-icon { transform: scale(1.2); }
|
| 141 |
-
.suggests__item .tooltip {
|
| 142 |
-
|
| 143 |
-
}
|
| 144 |
-
.suggests__item:hover .tooltip { visibility: visible; opacity: 1; }
|
| 145 |
.prompt {
|
| 146 |
position: fixed; background: rgba(10, 10, 11, 0.9); z-index: 1000; width: calc(100% - 70px);
|
| 147 |
left: 70px; bottom: 0; padding: 1rem; border-top: 1px solid var(--secondary-color); transition: all 0.3s ease;
|
| 148 |
}
|
| 149 |
-
.
|
| 150 |
-
.starry_night .prompt { background: rgba(28, 37, 38, 0.9); }
|
| 151 |
.prompt__input-wrapper {
|
| 152 |
max-width: 900px; margin: 0 auto; position: relative; display: flex; align-items: center;
|
| 153 |
background: var(--secondary-color); border: 1px solid var(--focus-color); border-radius: 0.5rem;
|
|
@@ -174,12 +166,10 @@ HTML_CONTENT = """
|
|
| 174 |
background: none; border: none; color: var(--text-secondary-color); font-size: 1.3rem;
|
| 175 |
cursor: pointer; padding: 0.3rem; transition: all 0.3s ease; position: relative;
|
| 176 |
}
|
| 177 |
-
.prompt__form-button:hover { color: var(--accent-color); transform: scale(1.1); }
|
| 178 |
.prompt__form-button.send { font-size: 1.5rem; }
|
| 179 |
-
.prompt__form-button .tooltip {
|
| 180 |
-
|
| 181 |
-
}
|
| 182 |
-
.prompt__form-button:hover .tooltip { visibility: visible; opacity: 1; }
|
| 183 |
.prompt__disclaim {
|
| 184 |
text-align: center; color: var(--placeholder-color); font-size: 0.8rem; margin-top: 1rem;
|
| 185 |
max-width: 900px; margin-left: auto; margin-right: auto; transition: opacity 0.3s ease;
|
|
@@ -193,12 +183,12 @@ HTML_CONTENT = """
|
|
| 193 |
margin-bottom: 1rem; padding: 1rem; border-radius: 0.5rem; background: rgba(26, 27, 30, 0.9);
|
| 194 |
color: var(--text-color); word-wrap: break-word; animation: fadeIn 0.3s ease-in; position: relative;
|
| 195 |
}
|
| 196 |
-
.
|
| 197 |
-
.starry_night .chat-message { background: rgba(46, 59, 62, 0.9); }
|
| 198 |
.chat-message.user {
|
| 199 |
background: rgba(122, 92, 250, 0.2); border: 1px solid var(--accent-color); border-radius: 0.5rem;
|
| 200 |
}
|
| 201 |
.chat-message.bot { background: rgba(36, 37, 40, 0.9); }
|
|
|
|
| 202 |
.chat-message.user.bubble-rounded { border-radius: 1rem; }
|
| 203 |
.chat-message.user.bubble-sharp { border-radius: 0; border: 2px solid var(--accent-color); }
|
| 204 |
.chat-message.user.bubble-starry {
|
|
@@ -218,7 +208,7 @@ HTML_CONTENT = """
|
|
| 218 |
background: none; border: none; color: var(--text-secondary-color); font-size: 1rem; cursor: pointer;
|
| 219 |
transition: color 0.2s ease;
|
| 220 |
}
|
| 221 |
-
.feedback-options button:hover { color: var(--accent-color); }
|
| 222 |
.error-message {
|
| 223 |
background: rgba(255, 77, 77, 0.2); border: 1px solid var(--error-color); color: var(--text-color);
|
| 224 |
padding: 1rem; border-radius: 0.5rem; margin-bottom: 1rem; animation: fadeIn 0.3s ease-in;
|
|
@@ -228,14 +218,14 @@ HTML_CONTENT = """
|
|
| 228 |
background: var(--error-color); color: var(--text-color); border: none; padding: 0.3rem 0.6rem;
|
| 229 |
border-radius: 0.3rem; cursor: pointer; transition: background 0.2s ease;
|
| 230 |
}
|
| 231 |
-
.error-message button:hover { background: var(--button-hover-color); }
|
| 232 |
.back-to-latest {
|
| 233 |
display: none; position: fixed; bottom: 100px; right: 2rem; background: var(--secondary-color);
|
| 234 |
color: var(--text-color); padding: 0.5rem 1rem; border-radius: 0.5rem; cursor: pointer;
|
| 235 |
border: 1px solid var(--accent-color); transition: all 0.3s ease; z-index: 1000;
|
| 236 |
}
|
| 237 |
.back-to-latest.visible { display: block; }
|
| 238 |
-
.back-to-latest:hover { background: var(--secondary-hover-color); transform: scale(1.05); }
|
| 239 |
.processing-dots {
|
| 240 |
display: none; position: absolute; right: 60px; color: var(--accent-color); font-size: 1.2rem;
|
| 241 |
}
|
|
@@ -246,31 +236,16 @@ HTML_CONTENT = """
|
|
| 246 |
.processing-dots span {
|
| 247 |
animation: blink 1s infinite; animation-delay: calc(0.2s * var(--i));
|
| 248 |
}
|
| 249 |
-
.theme-selector {
|
| 250 |
-
display: none; position: fixed; top: 10px; right: 10px; background: var(--secondary-color);
|
| 251 |
-
border: 1px solid var(--focus-color); border-radius: 0.5rem; padding: 0.5rem; z-index: 1002;
|
| 252 |
-
}
|
| 253 |
-
.theme-selector.active { display: block; }
|
| 254 |
-
.theme-selector button {
|
| 255 |
-
background: none; border: none; color: var(--text-color); padding: 0.3rem 0.6rem;
|
| 256 |
-
cursor: pointer; transition: all 0.2s ease;
|
| 257 |
-
}
|
| 258 |
-
.theme-selector button:hover { color: var(--accent-color); }
|
| 259 |
</style>
|
| 260 |
</head>
|
| 261 |
<body>
|
| 262 |
<div class="stars"></div>
|
| 263 |
<nav class="sidebar" aria-label="Main navigation">
|
| 264 |
-
<a href="#" class="sidebar__item" aria-label="Home"><i class='bx bx-home'></i><span>Home</span><div class="tooltip">Go to Home</div></a>
|
| 265 |
-
<a href="#" class="sidebar__item" aria-label="Profile"><i class='bx bx-user'></i><span>Profile</span><div class="tooltip">View Profile</div></a>
|
| 266 |
-
<a href="#" class="sidebar__item" aria-label="Settings"><i class='bx bx-cog'></i><span>Settings</span><div class="tooltip">Adjust Settings</div></a>
|
| 267 |
-
<a href="#" class="sidebar__item" aria-label="Help"><i class='bx bx-help-circle'></i><span>Help</span><div class="tooltip">Get Help</div></a>
|
| 268 |
</nav>
|
| 269 |
-
<div class="theme-selector" id="themeSelector">
|
| 270 |
-
<button onclick="setTheme('dark')">Dark</button>
|
| 271 |
-
<button onclick="setTheme('light')">Light</button>
|
| 272 |
-
<button onclick="setTheme('starry')">Starry Night</button>
|
| 273 |
-
</div>
|
| 274 |
<div class="main-content">
|
| 275 |
<header class="header">
|
| 276 |
<div class="header__title">
|
|
@@ -279,29 +254,29 @@ HTML_CONTENT = """
|
|
| 279 |
</div>
|
| 280 |
</header>
|
| 281 |
<div class="suggests">
|
| 282 |
-
<div class="suggests__item"><p class="suggests__item-text">What is the meaning of life?</p><div class="suggests__item-icon"><i class='bx bx-bulb'></i></div><div class="tooltip">Explore life's purpose</div></div>
|
| 283 |
-
<div class="suggests__item"><p class="suggests__item-text">Explain quantum physics simply</p><div class="suggests__item-icon"><i class='bx bx-atom'></i></div><div class="tooltip">Learn about quantum physics</div></div>
|
| 284 |
-
<div class="suggests__item"><p class="suggests__item-text">How does the universe work?</p><div class="suggests__item-icon"><i class='bx bx-planet'></i></div><div class="tooltip">Discover the universe</div></div>
|
| 285 |
</div>
|
| 286 |
<div class="chat-bar" id="chatBar" aria-live="polite"></div>
|
| 287 |
-
<button class="back-to-latest" id="backToLatest">Back to Latest</button>
|
| 288 |
</div>
|
| 289 |
<section class="prompt">
|
| 290 |
<form action="#" class="prompt__form" novalidate>
|
| 291 |
<div class="prompt__input-wrapper">
|
| 292 |
<input type="text" placeholder="Ask me anything..." class="prompt__form-input" id="chatInput" required aria-label="Chat input">
|
| 293 |
<div class="prompt__action-buttons basic">
|
| 294 |
-
<button type="button" class="prompt__form-button send" id="sendButton" aria-label="Send message"><i class='bx bx-send'></i><div class="tooltip">Send Message</div></button>
|
| 295 |
-
<button type="button" class="prompt__form-button" id="moreOptions" aria-label="Show more options"><i class='bx bx-dots-horizontal-rounded'></i><div class="tooltip">More Options</div></button>
|
| 296 |
</div>
|
| 297 |
<div class="prompt__action-buttons advanced" id="advancedOptions">
|
| 298 |
-
<label for="fileInput" class="prompt__form-button" aria-label="Upload file"><i class='bx bx-upload'></i><div class="tooltip">Upload File</div></label>
|
| 299 |
<input type="file" id="fileInput" style="display: none;" accept=".txt,.pdf,.jpg,.png">
|
| 300 |
-
<button type="button" class="prompt__form-button" id="deepSearchButton" aria-label="Deep search"><i class='bx bx-search'></i><div class="tooltip">Deep Search</div></button>
|
| 301 |
-
<button type="button" class="prompt__form-button" id="thinkButton" aria-label="Think mode"><i class='bx bx-brain'></i><div class="tooltip">Think Mode</div></button>
|
| 302 |
-
<button type="button" class="prompt__form-button" id="bubbleToggle" aria-label="Toggle bubble style"><i class='bx bx-chat'></i><div class="tooltip">Change Bubble Style</div></button>
|
| 303 |
-
<button type="button" class="prompt__form-button" id="soundToggle" aria-label="Toggle sound"><i class='bx bx-volume-full'></i><div class="tooltip">Toggle Sound</div></button>
|
| 304 |
-
<button type="button" class="prompt__form-button" id="themeToggler" aria-label="Toggle theme"><i class='bx bx-
|
| 305 |
<span class="processing-dots" id="processingDots"><span style="--i:1">.</span><span style="--i:2">.</span><span style="--i:3">.</span></span>
|
| 306 |
</div>
|
| 307 |
</div>
|
|
@@ -329,7 +304,6 @@ HTML_CONTENT = """
|
|
| 329 |
const soundToggle = document.getElementById('soundToggle');
|
| 330 |
const advancedOptions = document.getElementById('advancedOptions');
|
| 331 |
const moreOptions = document.getElementById('moreOptions');
|
| 332 |
-
const themeSelector = document.getElementById('themeSelector');
|
| 333 |
|
| 334 |
// Personalized greeting
|
| 335 |
function setGreeting() {
|
|
@@ -341,21 +315,27 @@ HTML_CONTENT = """
|
|
| 341 |
}
|
| 342 |
setGreeting();
|
| 343 |
|
| 344 |
-
// Theme management
|
| 345 |
function setTheme(theme) {
|
| 346 |
-
document.body.classList.remove('
|
| 347 |
-
if (theme === '
|
| 348 |
-
|
| 349 |
-
themeToggler.innerHTML = theme === 'light' ? "<i class='bx bx-moon'></i>" : "<i class='bx bx-sun'></i>";
|
| 350 |
localStorage.setItem('theme', theme);
|
| 351 |
-
themeSelector.classList.remove('active');
|
| 352 |
}
|
| 353 |
const savedTheme = localStorage.getItem('theme') || 'dark';
|
| 354 |
setTheme(savedTheme);
|
| 355 |
|
| 356 |
-
// Toggle theme
|
| 357 |
themeToggler.addEventListener('click', () => {
|
| 358 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
});
|
| 360 |
|
| 361 |
// Sound toggle
|
|
@@ -391,7 +371,7 @@ HTML_CONTENT = """
|
|
| 391 |
if (isError) {
|
| 392 |
const errorDiv = document.createElement('div');
|
| 393 |
errorDiv.classList.add('error-message');
|
| 394 |
-
errorDiv.innerHTML = `${content} <button onclick="retryLastMessage()">Retry</button>`;
|
| 395 |
chatBar.appendChild(errorDiv);
|
| 396 |
} else {
|
| 397 |
const messageDiv = document.createElement('div');
|
|
@@ -403,8 +383,8 @@ HTML_CONTENT = """
|
|
| 403 |
const feedbackDiv = document.createElement('div');
|
| 404 |
feedbackDiv.classList.add('feedback-options');
|
| 405 |
feedbackDiv.innerHTML = `
|
| 406 |
-
<button onclick="handleFeedback('up')" aria-label="Thumbs up"><i class='bx bx-thumbs-up'></i></button>
|
| 407 |
-
<button onclick="handleFeedback('down')" aria-label="Thumbs down"><i class='bx bx-thumbs-down'></i></button>
|
| 408 |
`;
|
| 409 |
messageDiv.appendChild(feedbackDiv);
|
| 410 |
}
|
|
@@ -448,8 +428,14 @@ HTML_CONTENT = """
|
|
| 448 |
if (e.key === 'Enter' && !e.shiftKey) {
|
| 449 |
e.preventDefault();
|
| 450 |
sendMessage();
|
| 451 |
-
} else if (e.ctrlKey && e.key === '
|
| 452 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 453 |
}
|
| 454 |
});
|
| 455 |
|
|
@@ -480,6 +466,12 @@ HTML_CONTENT = """
|
|
| 480 |
item.addEventListener('dblclick', () => {
|
| 481 |
alert(`Pinned suggestion: ${item.querySelector('.suggests__item-text').textContent} (Placeholder)`);
|
| 482 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 483 |
});
|
| 484 |
|
| 485 |
// Scroll handling
|
|
@@ -494,6 +486,12 @@ HTML_CONTENT = """
|
|
| 494 |
backToLatest.addEventListener('click', () => {
|
| 495 |
chatBar.scrollTop = chatBar.scrollHeight;
|
| 496 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
|
| 498 |
// Placeholder for loading more messages
|
| 499 |
function loadMoreMessages() {
|
|
@@ -542,6 +540,12 @@ HTML_CONTENT = """
|
|
| 542 |
}
|
| 543 |
|
| 544 |
sendButton.addEventListener('click', () => sendMessage());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 545 |
|
| 546 |
// Placeholder button actions
|
| 547 |
document.getElementById('deepSearchButton').addEventListener('click', () => {
|
|
@@ -567,14 +571,9 @@ HTML_CONTENT = """
|
|
| 567 |
let y = e.clientY / window.innerHeight;
|
| 568 |
document.querySelector('.stars').style.transform = `translate(${x * 50}px, ${y * 50}px)`;
|
| 569 |
});
|
| 570 |
-
window.addEventListener('scroll', () => {
|
| 571 |
-
const scrollPosition = window.scrollY;
|
| 572 |
-
const stars = document.querySelector('.stars');
|
| 573 |
-
stars.style.animationDuration = `${100 - scrollPosition / 10}s`;
|
| 574 |
-
});
|
| 575 |
|
| 576 |
-
//
|
| 577 |
-
document.querySelectorAll('.prompt__form-button, .
|
| 578 |
el.addEventListener('keydown', (e) => {
|
| 579 |
if (e.key === 'Enter' || e.key === ' ') {
|
| 580 |
e.preventDefault();
|
|
|
|
| 10 |
model = AutoModelForCausalLM.from_pretrained(model_name)
|
| 11 |
|
| 12 |
# Function to generate chatbot response
|
| 13 |
+
def get_chatbot_response(user_input: str, max_length=1000):
|
| 14 |
if not user_input:
|
| 15 |
return "Please say something!"
|
| 16 |
|
|
|
|
| 28 |
response = tokenizer.decode(chat_history_ids[:, input_ids.shape[-1]:][0], skip_special_tokens=True)
|
| 29 |
return response.strip()
|
| 30 |
|
| 31 |
+
# HTML, CSS, and JS with two modes (dark and soft)
|
| 32 |
HTML_CONTENT = """
|
| 33 |
<!DOCTYPE html>
|
| 34 |
<html lang="en">
|
|
|
|
| 49 |
--placeholder-color: #78797A; --accent-color: #00A3FF; --star-color: #FFFFFF;
|
| 50 |
--background-color: #000; --error-color: #FF4D4D; --success-color: #4CAF50;
|
| 51 |
}
|
| 52 |
+
.soft_mode {
|
| 53 |
+
--primary-color: rgb(220, 230, 240); /* Soft pastel blue */
|
| 54 |
+
--secondary-color: rgb(235, 240, 245); /* Lighter pastel */
|
| 55 |
+
--secondary-hover-color: rgb(200, 210, 225);
|
| 56 |
+
--focus-color: rgb(245, 245, 250); --focus-hover-color: rgb(230, 230, 235);
|
| 57 |
+
--button-hover-color: rgb(210, 220, 230);
|
| 58 |
+
--text-color: rgb(40, 50, 60); --text-secondary-color: rgb(90, 100, 110);
|
| 59 |
+
--heading-secondary-color: rgb(150, 160, 170);
|
| 60 |
+
--placeholder-color: rgb(120, 130, 140); --accent-color: rgb(100, 150, 255); /* Softer blue */
|
| 61 |
+
--star-color: rgb(180, 190, 200); --background-color: rgb(240, 245, 250); /* Very light pastel */
|
| 62 |
+
--error-color: rgb(255, 100, 100); --success-color: rgb(100, 200, 100);
|
| 63 |
}
|
| 64 |
body {
|
| 65 |
min-height: 100vh; display: flex; flex-direction: row; justify-content: space-between;
|
|
|
|
| 68 |
.stars {
|
| 69 |
position: fixed; width: 100%; height: 100%;
|
| 70 |
background: url('https://www.transparenttextures.com/patterns/stardust.png');
|
| 71 |
+
animation: starsAnim 100s linear infinite; z-index: -1; transition: opacity 0.3s ease; opacity: 0.8;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
}
|
| 73 |
+
.soft_mode .stars {
|
| 74 |
+
background: url('https://www.transparenttextures.com/patterns/stardust.png') rgba(240, 245, 250, 0.4);
|
| 75 |
+
opacity: 0.3;
|
| 76 |
}
|
| 77 |
@keyframes starsAnim { from { background-position: 0 0; } to { background-position: 10000px 10000px; } }
|
| 78 |
@keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } }
|
|
|
|
| 82 |
align-items: center; padding: 1rem 0; position: fixed; left: 0; top: 0; transition: width 0.3s ease; z-index: 1001;
|
| 83 |
}
|
| 84 |
.sidebar:hover { width: 200px; }
|
| 85 |
+
.soft_mode .sidebar { background: rgba(235, 240, 245, 0.95); }
|
| 86 |
.sidebar__item {
|
| 87 |
width: 100%; padding: 1rem; color: var(--text-secondary-color); text-decoration: none;
|
| 88 |
display: flex; align-items: center; gap: 1rem; transition: all 0.3s ease; position: relative;
|
| 89 |
}
|
| 90 |
+
.sidebar__item:hover, .sidebar__item:focus {
|
| 91 |
background: var(--secondary-hover-color); color: var(--accent-color); padding-left: 1.5rem; transform: scale(1.05);
|
| 92 |
}
|
| 93 |
.sidebar__item i { font-size: 1.5rem; }
|
| 94 |
.sidebar__item span { display: none; font-size: 1rem; }
|
| 95 |
.sidebar:hover .sidebar__item span { display: inline; }
|
|
|
|
|
|
|
| 96 |
.tooltip {
|
| 97 |
visibility: hidden; background: var(--secondary-color); color: var(--text-color); font-size: 0.8rem;
|
| 98 |
padding: 0.5rem; border-radius: 0.3rem; position: absolute; top: -30px; left: 50%; transform: translateX(-50%);
|
| 99 |
white-space: nowrap; z-index: 1002; transition: visibility 0.2s, opacity 0.2s; opacity: 0;
|
| 100 |
}
|
| 101 |
+
.sidebar__item:hover .tooltip, .sidebar__item:focus .tooltip { visibility: visible; opacity: 1; }
|
| 102 |
.main-content {
|
| 103 |
flex: 1; display: flex; flex-direction: column; padding-bottom: 100px; padding-top: 2rem; margin-left: 70px;
|
| 104 |
height: 100vh; overflow: hidden;
|
|
|
|
| 126 |
border-radius: 0.5rem; cursor: pointer; transition: all 0.3s ease; border: 1px solid var(--focus-color);
|
| 127 |
position: relative;
|
| 128 |
}
|
| 129 |
+
.soft_mode .suggests__item { background: rgba(235, 240, 245, 0.9); }
|
| 130 |
+
.suggests__item:hover, .suggests__item:focus {
|
|
|
|
| 131 |
background: var(--secondary-hover-color); border-color: var(--accent-color); color: var(--text-color);
|
| 132 |
transform: translateY(-3px);
|
| 133 |
}
|
| 134 |
.suggests__item-icon { margin-top: 1rem; color: var(--accent-color); transition: transform 0.2s ease; }
|
| 135 |
+
.suggests__item:hover .suggests__item-icon, .suggests__item:focus .suggests__item-icon { transform: scale(1.2); }
|
| 136 |
+
.suggests__item .tooltip { top: -40px; left: 50%; transform: translateX(-50%); }
|
| 137 |
+
.suggests__item:hover .tooltip, .suggests__item:focus .tooltip { visibility: visible; opacity: 1; }
|
|
|
|
|
|
|
| 138 |
.prompt {
|
| 139 |
position: fixed; background: rgba(10, 10, 11, 0.9); z-index: 1000; width: calc(100% - 70px);
|
| 140 |
left: 70px; bottom: 0; padding: 1rem; border-top: 1px solid var(--secondary-color); transition: all 0.3s ease;
|
| 141 |
}
|
| 142 |
+
.soft_mode .prompt { background: rgba(235, 240, 245, 0.9); border-top: 1px solid var(--focus-color); }
|
|
|
|
| 143 |
.prompt__input-wrapper {
|
| 144 |
max-width: 900px; margin: 0 auto; position: relative; display: flex; align-items: center;
|
| 145 |
background: var(--secondary-color); border: 1px solid var(--focus-color); border-radius: 0.5rem;
|
|
|
|
| 166 |
background: none; border: none; color: var(--text-secondary-color); font-size: 1.3rem;
|
| 167 |
cursor: pointer; padding: 0.3rem; transition: all 0.3s ease; position: relative;
|
| 168 |
}
|
| 169 |
+
.prompt__form-button:hover, .prompt__form-button:focus { color: var(--accent-color); transform: scale(1.1); }
|
| 170 |
.prompt__form-button.send { font-size: 1.5rem; }
|
| 171 |
+
.prompt__form-button .tooltip { top: -35px; left: 50%; transform: translateX(-50%); }
|
| 172 |
+
.prompt__form-button:hover .tooltip, .prompt__form-button:focus .tooltip { visibility: visible; opacity: 1; }
|
|
|
|
|
|
|
| 173 |
.prompt__disclaim {
|
| 174 |
text-align: center; color: var(--placeholder-color); font-size: 0.8rem; margin-top: 1rem;
|
| 175 |
max-width: 900px; margin-left: auto; margin-right: auto; transition: opacity 0.3s ease;
|
|
|
|
| 183 |
margin-bottom: 1rem; padding: 1rem; border-radius: 0.5rem; background: rgba(26, 27, 30, 0.9);
|
| 184 |
color: var(--text-color); word-wrap: break-word; animation: fadeIn 0.3s ease-in; position: relative;
|
| 185 |
}
|
| 186 |
+
.soft_mode .chat-message { background: rgba(235, 240, 245, 0.9); }
|
|
|
|
| 187 |
.chat-message.user {
|
| 188 |
background: rgba(122, 92, 250, 0.2); border: 1px solid var(--accent-color); border-radius: 0.5rem;
|
| 189 |
}
|
| 190 |
.chat-message.bot { background: rgba(36, 37, 40, 0.9); }
|
| 191 |
+
.soft_mode .chat-message.bot { background: rgba(245, 245, 250, 0.9); }
|
| 192 |
.chat-message.user.bubble-rounded { border-radius: 1rem; }
|
| 193 |
.chat-message.user.bubble-sharp { border-radius: 0; border: 2px solid var(--accent-color); }
|
| 194 |
.chat-message.user.bubble-starry {
|
|
|
|
| 208 |
background: none; border: none; color: var(--text-secondary-color); font-size: 1rem; cursor: pointer;
|
| 209 |
transition: color 0.2s ease;
|
| 210 |
}
|
| 211 |
+
.feedback-options button:hover, .feedback-options button:focus { color: var(--accent-color); }
|
| 212 |
.error-message {
|
| 213 |
background: rgba(255, 77, 77, 0.2); border: 1px solid var(--error-color); color: var(--text-color);
|
| 214 |
padding: 1rem; border-radius: 0.5rem; margin-bottom: 1rem; animation: fadeIn 0.3s ease-in;
|
|
|
|
| 218 |
background: var(--error-color); color: var(--text-color); border: none; padding: 0.3rem 0.6rem;
|
| 219 |
border-radius: 0.3rem; cursor: pointer; transition: background 0.2s ease;
|
| 220 |
}
|
| 221 |
+
.error-message button:hover, .error-message button:focus { background: var(--button-hover-color); }
|
| 222 |
.back-to-latest {
|
| 223 |
display: none; position: fixed; bottom: 100px; right: 2rem; background: var(--secondary-color);
|
| 224 |
color: var(--text-color); padding: 0.5rem 1rem; border-radius: 0.5rem; cursor: pointer;
|
| 225 |
border: 1px solid var(--accent-color); transition: all 0.3s ease; z-index: 1000;
|
| 226 |
}
|
| 227 |
.back-to-latest.visible { display: block; }
|
| 228 |
+
.back-to-latest:hover, .back-to-latest:focus { background: var(--secondary-hover-color); transform: scale(1.05); }
|
| 229 |
.processing-dots {
|
| 230 |
display: none; position: absolute; right: 60px; color: var(--accent-color); font-size: 1.2rem;
|
| 231 |
}
|
|
|
|
| 236 |
.processing-dots span {
|
| 237 |
animation: blink 1s infinite; animation-delay: calc(0.2s * var(--i));
|
| 238 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
</style>
|
| 240 |
</head>
|
| 241 |
<body>
|
| 242 |
<div class="stars"></div>
|
| 243 |
<nav class="sidebar" aria-label="Main navigation">
|
| 244 |
+
<a href="#" class="sidebar__item" tabindex="0" aria-label="Home"><i class='bx bx-home'></i><span>Home</span><div class="tooltip">Go to Home</div></a>
|
| 245 |
+
<a href="#" class="sidebar__item" tabindex="0" aria-label="Profile"><i class='bx bx-user'></i><span>Profile</span><div class="tooltip">View Profile</div></a>
|
| 246 |
+
<a href="#" class="sidebar__item" tabindex="0" aria-label="Settings"><i class='bx bx-cog'></i><span>Settings</span><div class="tooltip">Adjust Settings</div></a>
|
| 247 |
+
<a href="#" class="sidebar__item" tabindex="0" aria-label="Help"><i class='bx bx-help-circle'></i><span>Help</span><div class="tooltip">Get Help</div></a>
|
| 248 |
</nav>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
<div class="main-content">
|
| 250 |
<header class="header">
|
| 251 |
<div class="header__title">
|
|
|
|
| 254 |
</div>
|
| 255 |
</header>
|
| 256 |
<div class="suggests">
|
| 257 |
+
<div class="suggests__item" tabindex="0"><p class="suggests__item-text">What is the meaning of life?</p><div class="suggests__item-icon"><i class='bx bx-bulb'></i></div><div class="tooltip">Explore life's purpose</div></div>
|
| 258 |
+
<div class="suggests__item" tabindex="0"><p class="suggests__item-text">Explain quantum physics simply</p><div class="suggests__item-icon"><i class='bx bx-atom'></i></div><div class="tooltip">Learn about quantum physics</div></div>
|
| 259 |
+
<div class="suggests__item" tabindex="0"><p class="suggests__item-text">How does the universe work?</p><div class="suggests__item-icon"><i class='bx bx-planet'></i></div><div class="tooltip">Discover the universe</div></div>
|
| 260 |
</div>
|
| 261 |
<div class="chat-bar" id="chatBar" aria-live="polite"></div>
|
| 262 |
+
<button class="back-to-latest" id="backToLatest" tabindex="0">Back to Latest</button>
|
| 263 |
</div>
|
| 264 |
<section class="prompt">
|
| 265 |
<form action="#" class="prompt__form" novalidate>
|
| 266 |
<div class="prompt__input-wrapper">
|
| 267 |
<input type="text" placeholder="Ask me anything..." class="prompt__form-input" id="chatInput" required aria-label="Chat input">
|
| 268 |
<div class="prompt__action-buttons basic">
|
| 269 |
+
<button type="button" class="prompt__form-button send" id="sendButton" tabindex="0" aria-label="Send message"><i class='bx bx-send'></i><div class="tooltip">Send Message (Ctrl+S)</div></button>
|
| 270 |
+
<button type="button" class="prompt__form-button" id="moreOptions" tabindex="0" aria-label="Show more options"><i class='bx bx-dots-horizontal-rounded'></i><div class="tooltip">More Options</div></button>
|
| 271 |
</div>
|
| 272 |
<div class="prompt__action-buttons advanced" id="advancedOptions">
|
| 273 |
+
<label for="fileInput" class="prompt__form-button" tabindex="0" aria-label="Upload file"><i class='bx bx-upload'></i><div class="tooltip">Upload File</div></label>
|
| 274 |
<input type="file" id="fileInput" style="display: none;" accept=".txt,.pdf,.jpg,.png">
|
| 275 |
+
<button type="button" class="prompt__form-button" id="deepSearchButton" tabindex="0" aria-label="Deep search"><i class='bx bx-search'></i><div class="tooltip">Deep Search</div></button>
|
| 276 |
+
<button type="button" class="prompt__form-button" id="thinkButton" tabindex="0" aria-label="Think mode"><i class='bx bx-brain'></i><div class="tooltip">Think Mode</div></button>
|
| 277 |
+
<button type="button" class="prompt__form-button" id="bubbleToggle" tabindex="0" aria-label="Toggle bubble style"><i class='bx bx-chat'></i><div class="tooltip">Change Bubble Style</div></button>
|
| 278 |
+
<button type="button" class="prompt__form-button" id="soundToggle" tabindex="0" aria-label="Toggle sound"><i class='bx bx-volume-full'></i><div class="tooltip">Toggle Sound</div></button>
|
| 279 |
+
<button type="button" class="prompt__form-button" id="themeToggler" tabindex="0" aria-label="Toggle theme"><i class='bx bx-adjust'></i><div class="tooltip">Toggle Dark/Soft (Ctrl+T)</div></button>
|
| 280 |
<span class="processing-dots" id="processingDots"><span style="--i:1">.</span><span style="--i:2">.</span><span style="--i:3">.</span></span>
|
| 281 |
</div>
|
| 282 |
</div>
|
|
|
|
| 304 |
const soundToggle = document.getElementById('soundToggle');
|
| 305 |
const advancedOptions = document.getElementById('advancedOptions');
|
| 306 |
const moreOptions = document.getElementById('moreOptions');
|
|
|
|
| 307 |
|
| 308 |
// Personalized greeting
|
| 309 |
function setGreeting() {
|
|
|
|
| 315 |
}
|
| 316 |
setGreeting();
|
| 317 |
|
| 318 |
+
// Theme management (dark or soft)
|
| 319 |
function setTheme(theme) {
|
| 320 |
+
document.body.classList.remove('soft_mode');
|
| 321 |
+
if (theme === 'soft') document.body.classList.add('soft_mode');
|
| 322 |
+
themeToggler.innerHTML = theme === 'soft' ? "<i class='bx bx-moon'></i>" : "<i class='bx bx-adjust'></i>";
|
|
|
|
| 323 |
localStorage.setItem('theme', theme);
|
|
|
|
| 324 |
}
|
| 325 |
const savedTheme = localStorage.getItem('theme') || 'dark';
|
| 326 |
setTheme(savedTheme);
|
| 327 |
|
| 328 |
+
// Toggle theme with button or Ctrl+T
|
| 329 |
themeToggler.addEventListener('click', () => {
|
| 330 |
+
const newTheme = document.body.classList.contains('soft_mode') ? 'dark' : 'soft';
|
| 331 |
+
setTheme(newTheme);
|
| 332 |
+
});
|
| 333 |
+
document.addEventListener('keydown', (e) => {
|
| 334 |
+
if (e.ctrlKey && e.key === 't') {
|
| 335 |
+
e.preventDefault();
|
| 336 |
+
const newTheme = document.body.classList.contains('soft_mode') ? 'dark' : 'soft';
|
| 337 |
+
setTheme(newTheme);
|
| 338 |
+
}
|
| 339 |
});
|
| 340 |
|
| 341 |
// Sound toggle
|
|
|
|
| 371 |
if (isError) {
|
| 372 |
const errorDiv = document.createElement('div');
|
| 373 |
errorDiv.classList.add('error-message');
|
| 374 |
+
errorDiv.innerHTML = `${content} <button onclick="retryLastMessage()" tabindex="0">Retry</button>`;
|
| 375 |
chatBar.appendChild(errorDiv);
|
| 376 |
} else {
|
| 377 |
const messageDiv = document.createElement('div');
|
|
|
|
| 383 |
const feedbackDiv = document.createElement('div');
|
| 384 |
feedbackDiv.classList.add('feedback-options');
|
| 385 |
feedbackDiv.innerHTML = `
|
| 386 |
+
<button onclick="handleFeedback('up')" tabindex="0" aria-label="Thumbs up"><i class='bx bx-thumbs-up'></i></button>
|
| 387 |
+
<button onclick="handleFeedback('down')" tabindex="0" aria-label="Thumbs down"><i class='bx bx-thumbs-down'></i></button>
|
| 388 |
`;
|
| 389 |
messageDiv.appendChild(feedbackDiv);
|
| 390 |
}
|
|
|
|
| 428 |
if (e.key === 'Enter' && !e.shiftKey) {
|
| 429 |
e.preventDefault();
|
| 430 |
sendMessage();
|
| 431 |
+
} else if (e.ctrlKey && e.key === 's') {
|
| 432 |
+
e.preventDefault();
|
| 433 |
+
sendMessage();
|
| 434 |
+
} else if (e.key === 'Escape') {
|
| 435 |
+
e.preventDefault();
|
| 436 |
+
inputField.value = '';
|
| 437 |
+
suggests.classList.remove('hidden');
|
| 438 |
+
welcomeText.classList.remove('hidden');
|
| 439 |
}
|
| 440 |
});
|
| 441 |
|
|
|
|
| 466 |
item.addEventListener('dblclick', () => {
|
| 467 |
alert(`Pinned suggestion: ${item.querySelector('.suggests__item-text').textContent} (Placeholder)`);
|
| 468 |
});
|
| 469 |
+
item.addEventListener('keydown', (e) => {
|
| 470 |
+
if (e.key === 'Enter' || e.key === ' ') {
|
| 471 |
+
e.preventDefault();
|
| 472 |
+
item.click();
|
| 473 |
+
}
|
| 474 |
+
});
|
| 475 |
});
|
| 476 |
|
| 477 |
// Scroll handling
|
|
|
|
| 486 |
backToLatest.addEventListener('click', () => {
|
| 487 |
chatBar.scrollTop = chatBar.scrollHeight;
|
| 488 |
});
|
| 489 |
+
backToLatest.addEventListener('keydown', (e) => {
|
| 490 |
+
if (e.key === 'Enter' || e.key === ' ') {
|
| 491 |
+
e.preventDefault();
|
| 492 |
+
chatBar.scrollTop = chatBar.scrollHeight;
|
| 493 |
+
}
|
| 494 |
+
});
|
| 495 |
|
| 496 |
// Placeholder for loading more messages
|
| 497 |
function loadMoreMessages() {
|
|
|
|
| 540 |
}
|
| 541 |
|
| 542 |
sendButton.addEventListener('click', () => sendMessage());
|
| 543 |
+
sendButton.addEventListener('keydown', (e) => {
|
| 544 |
+
if (e.key === 'Enter' || e.key === ' ') {
|
| 545 |
+
e.preventDefault();
|
| 546 |
+
sendMessage();
|
| 547 |
+
}
|
| 548 |
+
});
|
| 549 |
|
| 550 |
// Placeholder button actions
|
| 551 |
document.getElementById('deepSearchButton').addEventListener('click', () => {
|
|
|
|
| 571 |
let y = e.clientY / window.innerHeight;
|
| 572 |
document.querySelector('.stars').style.transform = `translate(${x * 50}px, ${y * 50}px)`;
|
| 573 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 574 |
|
| 575 |
+
// Enhanced keyboard navigation
|
| 576 |
+
document.querySelectorAll('.sidebar__item, .suggests__item, .prompt__form-button, .back-to-latest, .feedback-options button').forEach(el => {
|
| 577 |
el.addEventListener('keydown', (e) => {
|
| 578 |
if (e.key === 'Enter' || e.key === ' ') {
|
| 579 |
e.preventDefault();
|