Spaces:
Sleeping
Sleeping
GitHub Copilot commited on
Commit ·
ef36da0
1
Parent(s): 2c8d5e7
Fix deployment logo rendering and add CPU heads-up toast
Browse files- app.py +6 -2
- static/index.html +161 -2
- static/logo.svg +13 -0
app.py
CHANGED
|
@@ -95,8 +95,12 @@ async def root():
|
|
| 95 |
|
| 96 |
@app.get("/logo.png")
|
| 97 |
async def logo():
|
| 98 |
-
#
|
| 99 |
-
return FileResponse(os.path.join(STATIC_DIR, "logo.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
@app.post("/chat")
|
| 102 |
async def chat(request: ChatRequest):
|
|
|
|
| 95 |
|
| 96 |
@app.get("/logo.png")
|
| 97 |
async def logo():
|
| 98 |
+
# Backward-compatible route: serve SVG logo even when clients request /logo.png.
|
| 99 |
+
return FileResponse(os.path.join(STATIC_DIR, "logo.svg"), media_type="image/svg+xml")
|
| 100 |
+
|
| 101 |
+
@app.get("/logo.svg")
|
| 102 |
+
async def logo_svg():
|
| 103 |
+
return FileResponse(os.path.join(STATIC_DIR, "logo.svg"), media_type="image/svg+xml")
|
| 104 |
|
| 105 |
@app.post("/chat")
|
| 106 |
async def chat(request: ChatRequest):
|
static/index.html
CHANGED
|
@@ -1140,6 +1140,114 @@
|
|
| 1140 |
::-webkit-scrollbar-thumb:hover {
|
| 1141 |
background: var(--text-muted);
|
| 1142 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1143 |
</style>
|
| 1144 |
</head>
|
| 1145 |
|
|
@@ -1178,7 +1286,7 @@
|
|
| 1178 |
<line x1="3" y1="18" x2="21" y2="18"></line>
|
| 1179 |
</svg>
|
| 1180 |
</button>
|
| 1181 |
-
<
|
| 1182 |
</div>
|
| 1183 |
<div class="header-actions">
|
| 1184 |
<button class="icon-btn" onclick="toggleTheme()" title="Toggle theme">
|
|
@@ -1199,7 +1307,7 @@
|
|
| 1199 |
<div class="chat-container" id="chatContainer">
|
| 1200 |
<!-- Welcome Screen -->
|
| 1201 |
<div class="welcome-screen" id="welcomeScreen">
|
| 1202 |
-
<
|
| 1203 |
<h1 class="welcome-title">Hello! I'm Krish Mind</h1>
|
| 1204 |
<p class="welcome-subtitle">Your AI assistant, developed by Krish CS</p>
|
| 1205 |
<div class="suggestions-grid">
|
|
@@ -1278,6 +1386,30 @@
|
|
| 1278 |
</div>
|
| 1279 |
</div>
|
| 1280 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1281 |
<script>
|
| 1282 |
// State
|
| 1283 |
let serverUrl = ''; // Empty = relative URL (works on HF Spaces or any host)
|
|
@@ -1289,6 +1421,7 @@
|
|
| 1289 |
let chatHistory = JSON.parse(sessionStorage.getItem('krishMindChatHistory') || '[]');
|
| 1290 |
let chatConversations = JSON.parse(sessionStorage.getItem('krishMindConversations') || '{}');
|
| 1291 |
let currentChatId = null;
|
|
|
|
| 1292 |
|
| 1293 |
// Icons
|
| 1294 |
const SEND_ICON = '<svg width="16" height="16" viewBox="0 0 24 24" fill="white"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" /></svg>';
|
|
@@ -1318,6 +1451,11 @@
|
|
| 1318 |
// Auto-check connection (optional)
|
| 1319 |
checkConnection();
|
| 1320 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1321 |
// Enable send button on input (only if not generating)
|
| 1322 |
document.getElementById('messageInput').addEventListener('input', (e) => {
|
| 1323 |
if (!isGenerating) {
|
|
@@ -1340,6 +1478,27 @@
|
|
| 1340 |
document.getElementById('themeIcon').innerHTML = theme === 'dark' ? '☀' : '🌙';
|
| 1341 |
}
|
| 1342 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1343 |
// Sidebar toggle
|
| 1344 |
function toggleSidebar() {
|
| 1345 |
document.getElementById('sidebar').classList.toggle('open');
|
|
|
|
| 1140 |
::-webkit-scrollbar-thumb:hover {
|
| 1141 |
background: var(--text-muted);
|
| 1142 |
}
|
| 1143 |
+
|
| 1144 |
+
/* CPU heads-up toast */
|
| 1145 |
+
.notification-toast {
|
| 1146 |
+
position: fixed;
|
| 1147 |
+
bottom: 24px;
|
| 1148 |
+
left: 24px;
|
| 1149 |
+
background: var(--bg-primary);
|
| 1150 |
+
border-radius: 16px;
|
| 1151 |
+
padding: 16px 20px;
|
| 1152 |
+
max-width: 380px;
|
| 1153 |
+
z-index: 9999;
|
| 1154 |
+
opacity: 0;
|
| 1155 |
+
visibility: hidden;
|
| 1156 |
+
transform: translateY(20px) scale(0.95);
|
| 1157 |
+
transition: all 0.35s ease;
|
| 1158 |
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28), 0 0 0 1px rgba(64, 201, 201, 0.28);
|
| 1159 |
+
}
|
| 1160 |
+
|
| 1161 |
+
.notification-toast.show {
|
| 1162 |
+
opacity: 1;
|
| 1163 |
+
visibility: visible;
|
| 1164 |
+
transform: translateY(0) scale(1);
|
| 1165 |
+
}
|
| 1166 |
+
|
| 1167 |
+
.toast-header {
|
| 1168 |
+
display: flex;
|
| 1169 |
+
align-items: center;
|
| 1170 |
+
justify-content: space-between;
|
| 1171 |
+
margin-bottom: 8px;
|
| 1172 |
+
}
|
| 1173 |
+
|
| 1174 |
+
.toast-title {
|
| 1175 |
+
display: flex;
|
| 1176 |
+
align-items: center;
|
| 1177 |
+
gap: 8px;
|
| 1178 |
+
font-size: 15px;
|
| 1179 |
+
font-weight: 700;
|
| 1180 |
+
color: var(--text-primary);
|
| 1181 |
+
}
|
| 1182 |
+
|
| 1183 |
+
.toast-icon {
|
| 1184 |
+
width: 18px;
|
| 1185 |
+
height: 18px;
|
| 1186 |
+
color: #2d8cbe;
|
| 1187 |
+
}
|
| 1188 |
+
|
| 1189 |
+
.toast-close {
|
| 1190 |
+
background: none;
|
| 1191 |
+
border: none;
|
| 1192 |
+
color: var(--text-muted);
|
| 1193 |
+
cursor: pointer;
|
| 1194 |
+
padding: 3px;
|
| 1195 |
+
border-radius: 6px;
|
| 1196 |
+
}
|
| 1197 |
+
|
| 1198 |
+
.toast-close:hover {
|
| 1199 |
+
background: var(--bg-hover);
|
| 1200 |
+
color: var(--text-primary);
|
| 1201 |
+
}
|
| 1202 |
+
|
| 1203 |
+
.toast-message {
|
| 1204 |
+
font-size: 13px;
|
| 1205 |
+
color: var(--text-primary);
|
| 1206 |
+
line-height: 1.5;
|
| 1207 |
+
margin-bottom: 12px;
|
| 1208 |
+
}
|
| 1209 |
+
|
| 1210 |
+
.toast-btn {
|
| 1211 |
+
background: var(--accent-gradient);
|
| 1212 |
+
color: white;
|
| 1213 |
+
border: none;
|
| 1214 |
+
padding: 10px 14px;
|
| 1215 |
+
border-radius: 10px;
|
| 1216 |
+
font-size: 13px;
|
| 1217 |
+
font-weight: 600;
|
| 1218 |
+
cursor: pointer;
|
| 1219 |
+
width: 100%;
|
| 1220 |
+
}
|
| 1221 |
+
|
| 1222 |
+
.toast-progress {
|
| 1223 |
+
position: absolute;
|
| 1224 |
+
left: 0;
|
| 1225 |
+
bottom: 0;
|
| 1226 |
+
height: 3px;
|
| 1227 |
+
width: 100%;
|
| 1228 |
+
border-radius: 0 0 16px 16px;
|
| 1229 |
+
background: linear-gradient(90deg, #00d4aa, #00bcd4);
|
| 1230 |
+
animation: toast-progress-shrink 10s linear forwards;
|
| 1231 |
+
}
|
| 1232 |
+
|
| 1233 |
+
@keyframes toast-progress-shrink {
|
| 1234 |
+
from {
|
| 1235 |
+
width: 100%;
|
| 1236 |
+
}
|
| 1237 |
+
|
| 1238 |
+
to {
|
| 1239 |
+
width: 0;
|
| 1240 |
+
}
|
| 1241 |
+
}
|
| 1242 |
+
|
| 1243 |
+
@media (max-width: 480px) {
|
| 1244 |
+
.notification-toast {
|
| 1245 |
+
left: 12px;
|
| 1246 |
+
right: 12px;
|
| 1247 |
+
bottom: 12px;
|
| 1248 |
+
max-width: none;
|
| 1249 |
+
}
|
| 1250 |
+
}
|
| 1251 |
</style>
|
| 1252 |
</head>
|
| 1253 |
|
|
|
|
| 1286 |
<line x1="3" y1="18" x2="21" y2="18"></line>
|
| 1287 |
</svg>
|
| 1288 |
</button>
|
| 1289 |
+
<img src="/static/logo.svg" alt="Krish Mind" class="logo-img">
|
| 1290 |
</div>
|
| 1291 |
<div class="header-actions">
|
| 1292 |
<button class="icon-btn" onclick="toggleTheme()" title="Toggle theme">
|
|
|
|
| 1307 |
<div class="chat-container" id="chatContainer">
|
| 1308 |
<!-- Welcome Screen -->
|
| 1309 |
<div class="welcome-screen" id="welcomeScreen">
|
| 1310 |
+
<img src="/static/logo.svg" alt="Krish Mind" class="welcome-logo">
|
| 1311 |
<h1 class="welcome-title">Hello! I'm Krish Mind</h1>
|
| 1312 |
<p class="welcome-subtitle">Your AI assistant, developed by Krish CS</p>
|
| 1313 |
<div class="suggestions-grid">
|
|
|
|
| 1386 |
</div>
|
| 1387 |
</div>
|
| 1388 |
|
| 1389 |
+
<div class="notification-toast" id="notificationToast">
|
| 1390 |
+
<div class="toast-header">
|
| 1391 |
+
<div class="toast-title">
|
| 1392 |
+
<svg class="toast-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
| 1393 |
+
<circle cx="12" cy="12" r="10"></circle>
|
| 1394 |
+
<line x1="12" y1="8" x2="12" y2="12"></line>
|
| 1395 |
+
<line x1="12" y1="16" x2="12.01" y2="16"></line>
|
| 1396 |
+
</svg>
|
| 1397 |
+
Heads Up
|
| 1398 |
+
</div>
|
| 1399 |
+
<button class="toast-close" onclick="closeToast()">
|
| 1400 |
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
| 1401 |
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
| 1402 |
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
| 1403 |
+
</svg>
|
| 1404 |
+
</button>
|
| 1405 |
+
</div>
|
| 1406 |
+
<p class="toast-message">
|
| 1407 |
+
CPU resources are limited here, so responses may be slow. Please wait for your response.
|
| 1408 |
+
</p>
|
| 1409 |
+
<button class="toast-btn" onclick="closeToast()">OK, got it</button>
|
| 1410 |
+
<div class="toast-progress"></div>
|
| 1411 |
+
</div>
|
| 1412 |
+
|
| 1413 |
<script>
|
| 1414 |
// State
|
| 1415 |
let serverUrl = ''; // Empty = relative URL (works on HF Spaces or any host)
|
|
|
|
| 1421 |
let chatHistory = JSON.parse(sessionStorage.getItem('krishMindChatHistory') || '[]');
|
| 1422 |
let chatConversations = JSON.parse(sessionStorage.getItem('krishMindConversations') || '{}');
|
| 1423 |
let currentChatId = null;
|
| 1424 |
+
let toastTimeout = null;
|
| 1425 |
|
| 1426 |
// Icons
|
| 1427 |
const SEND_ICON = '<svg width="16" height="16" viewBox="0 0 24 24" fill="white"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" /></svg>';
|
|
|
|
| 1451 |
// Auto-check connection (optional)
|
| 1452 |
checkConnection();
|
| 1453 |
|
| 1454 |
+
if (sessionStorage.getItem('cpuHeadsUpShown') !== 'true') {
|
| 1455 |
+
showToast();
|
| 1456 |
+
sessionStorage.setItem('cpuHeadsUpShown', 'true');
|
| 1457 |
+
}
|
| 1458 |
+
|
| 1459 |
// Enable send button on input (only if not generating)
|
| 1460 |
document.getElementById('messageInput').addEventListener('input', (e) => {
|
| 1461 |
if (!isGenerating) {
|
|
|
|
| 1478 |
document.getElementById('themeIcon').innerHTML = theme === 'dark' ? '☀' : '🌙';
|
| 1479 |
}
|
| 1480 |
|
| 1481 |
+
function showToast() {
|
| 1482 |
+
const toast = document.getElementById('notificationToast');
|
| 1483 |
+
if (!toast) return;
|
| 1484 |
+
setTimeout(() => {
|
| 1485 |
+
toast.classList.add('show');
|
| 1486 |
+
toastTimeout = setTimeout(() => {
|
| 1487 |
+
closeToast();
|
| 1488 |
+
}, 10000);
|
| 1489 |
+
}, 400);
|
| 1490 |
+
}
|
| 1491 |
+
|
| 1492 |
+
function closeToast() {
|
| 1493 |
+
const toast = document.getElementById('notificationToast');
|
| 1494 |
+
if (!toast) return;
|
| 1495 |
+
toast.classList.remove('show');
|
| 1496 |
+
if (toastTimeout) {
|
| 1497 |
+
clearTimeout(toastTimeout);
|
| 1498 |
+
toastTimeout = null;
|
| 1499 |
+
}
|
| 1500 |
+
}
|
| 1501 |
+
|
| 1502 |
// Sidebar toggle
|
| 1503 |
function toggleSidebar() {
|
| 1504 |
document.getElementById('sidebar').classList.toggle('open');
|
static/logo.svg
ADDED
|
|