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();
|