+
+
+
@@ -340,8 +501,75 @@
}
}
+ // Dark Mode Management
+ class DarkModeManager {
+ constructor() {
+ this.theme = this.getStoredTheme() || this.getSystemPreference();
+ this.applyTheme();
+ this.setupToggle();
+ }
+
+ getStoredTheme() {
+ return localStorage.getItem('theme');
+ }
+
+ getSystemPreference() {
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+ }
+
+ setTheme(theme) {
+ this.theme = theme;
+ localStorage.setItem('theme', theme);
+ this.applyTheme();
+ }
+
+ applyTheme() {
+ const root = document.documentElement;
+ if (this.theme === 'dark') {
+ root.setAttribute('data-theme', 'dark');
+ const icon = document.getElementById('dark-mode-icon');
+ if (icon) {
+ icon.classList.remove('fa-moon');
+ icon.classList.add('fa-sun');
+ }
+ } else {
+ root.setAttribute('data-theme', 'light');
+ const icon = document.getElementById('dark-mode-icon');
+ if (icon) {
+ icon.classList.remove('fa-sun');
+ icon.classList.add('fa-moon');
+ }
+ }
+ }
+
+ toggleTheme() {
+ const newTheme = this.theme === 'dark' ? 'light' : 'dark';
+ this.setTheme(newTheme);
+ }
+
+ setupToggle() {
+ const toggle = document.getElementById('dark-mode-toggle');
+ if (toggle) {
+ toggle.addEventListener('click', () => {
+ this.toggleTheme();
+ });
+ }
+
+ // Listen for system theme changes
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
+ // Only apply system preference if user hasn't set a preference
+ if (!this.getStoredTheme()) {
+ this.setTheme(e.matches ? 'dark' : 'light');
+ }
+ });
+ }
+ }
+
// Initialize connection manager when page loads
document.addEventListener('DOMContentLoaded', () => {
+ // Initialize dark mode manager first
+ window.darkModeManager = new DarkModeManager();
+
window.connectionManager = new ModernConnectionManager();
// Update timestamp immediately and every second
diff --git a/modules/web_viewer/templates/contacts.html b/modules/web_viewer/templates/contacts.html
index ecb1439..da51fbd 100644
--- a/modules/web_viewer/templates/contacts.html
+++ b/modules/web_viewer/templates/contacts.html
@@ -66,9 +66,11 @@
-
-
-
0
- Total Messages
-
0
24h Messages
+
+
0
+ Total Messages
+
@@ -211,14 +211,14 @@
-
-
0
- Total Commands
-
0
24h Commands
+
+
0
+ Total Commands
+
@@ -738,7 +738,7 @@ window.addEventListener('beforeunload', () => {
/* Status indicators moved to enhanced section below */
.loading {
- color: #6c757d;
+ color: var(--text-muted);
font-style: italic;
}
@@ -748,7 +748,7 @@ window.addEventListener('beforeunload', () => {
.card:hover {
transform: translateY(-2px);
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
+ box-shadow: 0 4px 8px var(--shadow-color);
}
.metric-value {
@@ -758,7 +758,7 @@ window.addEventListener('beforeunload', () => {
.metric-label {
font-size: 0.875rem;
- color: #6c757d;
+ color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.5px;
}
@@ -767,7 +767,7 @@ window.addEventListener('beforeunload', () => {
/* Health status card styling */
.health-status-card .col-md-3 {
- border-right: 1px solid #e9ecef;
+ border-right: 1px solid var(--border-color);
padding: 0.75rem 0.5rem;
position: relative;
}
@@ -793,7 +793,7 @@ window.addEventListener('beforeunload', () => {
.card.shadow-sm:hover {
transform: translateY(-2px);
- box-shadow: 0 8px 25px rgba(0,0,0,0.1) !important;
+ box-shadow: 0 8px 25px var(--shadow-color) !important;
}
.bg-gradient-primary {
@@ -841,5 +841,16 @@ window.addEventListener('beforeunload', () => {
70% { box-shadow: 0 0 0 6px rgba(40, 167, 69, 0); }
100% { box-shadow: 0 0 0 0 rgba(40, 167, 69, 0); }
}
+
+[data-theme="dark"] .status-indicator {
+ box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.4);
+ animation: pulse-dark 2s infinite;
+}
+
+@keyframes pulse-dark {
+ 0% { box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.6); }
+ 70% { box-shadow: 0 0 0 6px rgba(40, 167, 69, 0); }
+ 100% { box-shadow: 0 0 0 0 rgba(40, 167, 69, 0); }
+}
{% endblock %}
diff --git a/modules/web_viewer/templates/realtime.html b/modules/web_viewer/templates/realtime.html
index cfb04a7..ae07754 100644
--- a/modules/web_viewer/templates/realtime.html
+++ b/modules/web_viewer/templates/realtime.html
@@ -189,7 +189,7 @@
const userMessage = document.createElement('div');
userMessage.className = 'd-flex justify-content-start mb-2';
userMessage.innerHTML = `
-
+
${data.user || 'Unknown'}
${data.channel || 'Unknown'}
@@ -204,8 +204,9 @@
botMessage.className = 'd-flex justify-content-end mb-2';
const responseText = data.response || 'No response';
const responseClass = data.success ? 'success' : 'danger';
+ const botMessageClass = data.success ? 'bot-message-success' : 'bot-message-danger';
botMessage.innerHTML = `
-
+
🤖 Bot
${data.success ? 'Success' : 'Failed'}
@@ -340,20 +341,21 @@
height: calc(100vh - 300px); /* Use full viewport height minus header/nav space */
min-height: 400px; /* Ensure minimum usable height */
overflow-y: auto;
- background-color: #f8f9fa;
- border: 1px solid #dee2e6;
+ background-color: var(--bg-secondary);
+ border: 1px solid var(--border-color);
border-radius: 0.375rem;
padding: 0.5rem;
}
.stream-entry {
- background-color: white;
+ background-color: var(--card-bg);
transition: all 0.3s ease;
border-left: 3px solid #007bff;
+ color: var(--text-color);
}
.stream-entry:hover {
- box-shadow: 0 2px 8px rgba(0,0,0,0.15);
+ box-shadow: 0 2px 8px var(--shadow-color);
transform: translateY(-1px);
}
@@ -377,13 +379,45 @@
}
.user-message {
+ background-color: #e3f2fd;
border: 1px solid #bbdefb;
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+ box-shadow: 0 1px 3px var(--shadow-color);
+ color: var(--text-color);
+ }
+
+ [data-theme="dark"] .user-message {
+ background-color: #1a237e;
+ border-color: #283593;
+ color: #e3f2fd;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
- .bot-message {
+ .bot-message-success {
+ background-color: #e8f5e8;
border: 1px solid #c8e6c9;
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+ box-shadow: 0 1px 3px var(--shadow-color);
+ color: var(--text-color);
+ }
+
+ [data-theme="dark"] .bot-message-success {
+ background-color: #1b5e20;
+ border-color: #2e7d32;
+ color: #c8e6c9;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+ }
+
+ .bot-message-danger {
+ background-color: #ffebee;
+ border: 1px solid #ffcdd2;
+ box-shadow: 0 1px 3px var(--shadow-color);
+ color: var(--text-color);
+ }
+
+ [data-theme="dark"] .bot-message-danger {
+ background-color: #4a148c;
+ border-color: #6a1b9a;
+ color: #f8bbd0;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.response-text {