Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -939,8 +939,6 @@ def format_project_ideas(ideas):
|
|
939 |
|
940 |
return result
|
941 |
|
942 |
-
# Missing function implementations
|
943 |
-
|
944 |
# Dictionary to store user profiles by session ID
|
945 |
user_profiles = {}
|
946 |
|
@@ -1167,8 +1165,8 @@ def create_chatbot():
|
|
1167 |
|
1168 |
# Create CSS with theme variables
|
1169 |
custom_css = """
|
1170 |
-
/*
|
1171 |
-
|
1172 |
--primary-color: #4a6fa5;
|
1173 |
--secondary-color: #6c757d;
|
1174 |
--success-color: #28a745;
|
@@ -1183,21 +1181,41 @@ def create_chatbot():
|
|
1183 |
--info-box-bg: #e7f5fe;
|
1184 |
}
|
1185 |
|
1186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1187 |
@media (prefers-color-scheme: dark) {
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
--
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
|
|
|
|
|
|
|
|
|
|
1201 |
}
|
1202 |
}
|
1203 |
|
@@ -1338,42 +1356,43 @@ def create_chatbot():
|
|
1338 |
}
|
1339 |
"""
|
1340 |
|
1341 |
-
# JavaScript to detect and apply theme
|
1342 |
theme_script = """
|
1343 |
<script>
|
1344 |
-
//
|
1345 |
-
|
1346 |
-
//
|
1347 |
-
|
1348 |
-
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
1349 |
-
|
1350 |
-
// Force any specific elements that might need extra help
|
1351 |
-
const codeBlocks = document.querySelectorAll('pre code');
|
1352 |
-
codeBlocks.forEach(block => {
|
1353 |
-
block.style.color = isDarkMode ? '#f1f1f1' : '#212529';
|
1354 |
-
block.style.backgroundColor = isDarkMode ? '#2d2d2d' : '#f8f9fa';
|
1355 |
-
});
|
1356 |
-
|
1357 |
-
// Ensure markdown-rendered content is visible
|
1358 |
-
const markdownContent = document.querySelectorAll('.prose *');
|
1359 |
-
markdownContent.forEach(element => {
|
1360 |
-
// Skip elements that already have specific styling
|
1361 |
-
if (element.tagName === 'A' ||
|
1362 |
-
element.tagName.match(/^H[1-6]$/) ||
|
1363 |
-
element.tagName === 'CODE') {
|
1364 |
-
return;
|
1365 |
-
}
|
1366 |
-
|
1367 |
-
element.style.color = isDarkMode ? '#f1f1f1' : '#212529';
|
1368 |
-
});
|
1369 |
-
}
|
1370 |
|
1371 |
-
|
1372 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1373 |
|
1374 |
-
//
|
1375 |
-
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change',
|
1376 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1377 |
</script>
|
1378 |
"""
|
1379 |
|
@@ -1494,6 +1513,70 @@ def create_chatbot():
|
|
1494 |
|
1495 |
generate_plan_btn = gr.Button("Generate Study Plan", variant="primary")
|
1496 |
plan_output = gr.Markdown(label="Personalized Study Plan")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1497 |
|
1498 |
gr.HTML("""<div class="footer">
|
1499 |
AI Teaching Assistant | Version 2.0 | © 2025 | Powered by Groq AI
|
|
|
939 |
|
940 |
return result
|
941 |
|
|
|
|
|
942 |
# Dictionary to store user profiles by session ID
|
943 |
user_profiles = {}
|
944 |
|
|
|
1165 |
|
1166 |
# Create CSS with theme variables
|
1167 |
custom_css = """
|
1168 |
+
/* Theme variables - will be applied based on user's theme preference */
|
1169 |
+
.light-theme {
|
1170 |
--primary-color: #4a6fa5;
|
1171 |
--secondary-color: #6c757d;
|
1172 |
--success-color: #28a745;
|
|
|
1181 |
--info-box-bg: #e7f5fe;
|
1182 |
}
|
1183 |
|
1184 |
+
.dark-theme {
|
1185 |
+
--primary-color: #5b88c7;
|
1186 |
+
--secondary-color: #adb5bd;
|
1187 |
+
--success-color: #48c774;
|
1188 |
+
--bg-color: #1a1a1a;
|
1189 |
+
--text-color: #f1f1f1;
|
1190 |
+
--card-bg: #2d2d2d;
|
1191 |
+
--card-border: #444444;
|
1192 |
+
--input-bg: #333333;
|
1193 |
+
--highlight-color: #193652;
|
1194 |
+
--accent-color: #3291ff;
|
1195 |
+
--completed-color: #204829;
|
1196 |
+
--info-box-bg: #193652;
|
1197 |
+
}
|
1198 |
+
|
1199 |
+
/* Automatically detect theme preference and apply appropriate theme class */
|
1200 |
@media (prefers-color-scheme: dark) {
|
1201 |
+
body {
|
1202 |
+
color-scheme: dark;
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
body:not(.light-theme):not(.force-light) {
|
1206 |
+
background-color: var(--bg-color);
|
1207 |
+
color: var(--text-color);
|
1208 |
+
}
|
1209 |
+
}
|
1210 |
+
|
1211 |
+
@media (prefers-color-scheme: light) {
|
1212 |
+
body {
|
1213 |
+
color-scheme: light;
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
body:not(.dark-theme):not(.force-dark) {
|
1217 |
+
background-color: var(--bg-color);
|
1218 |
+
color: var(--text-color);
|
1219 |
}
|
1220 |
}
|
1221 |
|
|
|
1356 |
}
|
1357 |
"""
|
1358 |
|
1359 |
+
# JavaScript to detect and apply theme
|
1360 |
theme_script = """
|
1361 |
<script>
|
1362 |
+
// Function to detect and apply theme
|
1363 |
+
function applyTheme() {
|
1364 |
+
// Check if user has a saved preference
|
1365 |
+
const savedTheme = localStorage.getItem('preferredTheme');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1366 |
|
1367 |
+
if (savedTheme) {
|
1368 |
+
// Apply saved preference
|
1369 |
+
document.body.classList.add(savedTheme + '-theme');
|
1370 |
+
} else {
|
1371 |
+
// Check system preference
|
1372 |
+
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
1373 |
+
document.body.classList.add('dark-theme');
|
1374 |
+
} else {
|
1375 |
+
document.body.classList.add('light-theme');
|
1376 |
+
}
|
1377 |
+
}
|
1378 |
|
1379 |
+
// Listen for theme changes
|
1380 |
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
1381 |
+
// Only apply if no saved preference
|
1382 |
+
if (!savedTheme) {
|
1383 |
+
document.body.classList.remove('light-theme', 'dark-theme');
|
1384 |
+
document.body.classList.add(event.matches ? 'dark-theme' : 'light-theme');
|
1385 |
+
}
|
1386 |
+
});
|
1387 |
+
}
|
1388 |
+
|
1389 |
+
// Apply theme when DOM is loaded
|
1390 |
+
document.addEventListener('DOMContentLoaded', applyTheme);
|
1391 |
+
|
1392 |
+
// For Gradio that might load content dynamically
|
1393 |
+
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
1394 |
+
setTimeout(applyTheme, 1);
|
1395 |
+
}
|
1396 |
</script>
|
1397 |
"""
|
1398 |
|
|
|
1513 |
|
1514 |
generate_plan_btn = gr.Button("Generate Study Plan", variant="primary")
|
1515 |
plan_output = gr.Markdown(label="Personalized Study Plan")
|
1516 |
+
|
1517 |
+
# Theme Selector Tab (New)
|
1518 |
+
with gr.Tab("Settings"):
|
1519 |
+
with gr.Column(elem_classes=["card"]):
|
1520 |
+
gr.HTML("<h3>App Settings</h3>")
|
1521 |
+
|
1522 |
+
theme_selector = gr.Radio(
|
1523 |
+
choices=["System Default", "Light Theme", "Dark Theme"],
|
1524 |
+
label="Theme Preference",
|
1525 |
+
value="System Default"
|
1526 |
+
)
|
1527 |
+
|
1528 |
+
# Add JavaScript to handle theme changes
|
1529 |
+
theme_js = """
|
1530 |
+
<script>
|
1531 |
+
// Get the radio input once it exists
|
1532 |
+
function setupThemeSelector() {
|
1533 |
+
const radioInputs = document.querySelectorAll('input[type="radio"][name="theme"]');
|
1534 |
+
if (radioInputs.length === 0) {
|
1535 |
+
setTimeout(setupThemeSelector, 300);
|
1536 |
+
return;
|
1537 |
+
}
|
1538 |
+
|
1539 |
+
// Set initial value based on stored preference
|
1540 |
+
const savedTheme = localStorage.getItem('preferredTheme');
|
1541 |
+
if (savedTheme === 'light') {
|
1542 |
+
radioInputs[1].checked = true;
|
1543 |
+
} else if (savedTheme === 'dark') {
|
1544 |
+
radioInputs[2].checked = true;
|
1545 |
+
} else {
|
1546 |
+
radioInputs[0].checked = true;
|
1547 |
+
}
|
1548 |
+
|
1549 |
+
// Add event listeners
|
1550 |
+
radioInputs.forEach(input => {
|
1551 |
+
input.addEventListener('change', function() {
|
1552 |
+
const body = document.body;
|
1553 |
+
body.classList.remove('light-theme', 'dark-theme', 'force-light', 'force-dark');
|
1554 |
+
|
1555 |
+
if (this.value === "Light Theme") {
|
1556 |
+
body.classList.add('light-theme', 'force-light');
|
1557 |
+
localStorage.setItem('preferredTheme', 'light');
|
1558 |
+
} else if (this.value === "Dark Theme") {
|
1559 |
+
body.classList.add('dark-theme', 'force-dark');
|
1560 |
+
localStorage.setItem('preferredTheme', 'dark');
|
1561 |
+
} else {
|
1562 |
+
localStorage.removeItem('preferredTheme');
|
1563 |
+
applyTheme(); // Reapply system theme
|
1564 |
+
}
|
1565 |
+
});
|
1566 |
+
});
|
1567 |
+
}
|
1568 |
+
|
1569 |
+
// Start setup
|
1570 |
+
setupThemeSelector();
|
1571 |
+
</script>
|
1572 |
+
"""
|
1573 |
+
gr.HTML(theme_js)
|
1574 |
+
|
1575 |
+
gr.HTML("""
|
1576 |
+
<div class="info-box">
|
1577 |
+
<p>These settings will be saved in your browser for future visits.</p>
|
1578 |
+
</div>
|
1579 |
+
""")
|
1580 |
|
1581 |
gr.HTML("""<div class="footer">
|
1582 |
AI Teaching Assistant | Version 2.0 | © 2025 | Powered by Groq AI
|