diff --git a/bot/static/index.html b/bot/static/index.html
index b39aae0..0dd15e1 100644
--- a/bot/static/index.html
+++ b/bot/static/index.html
@@ -1848,28 +1848,32 @@ function switchTab(tabId) {
}
}
-// Initialize
-document.addEventListener('DOMContentLoaded', function() {
- // Restore persisted tab from localStorage
+// ============================================================================
+// Initialization — all setup in one DOMContentLoaded
+// ============================================================================
+
+let statusInterval, logsInterval, argsInterval;
+
+function startPolling() {
+ if (!statusInterval) statusInterval = setInterval(loadStatus, 10000);
+ if (!logsInterval) logsInterval = setInterval(loadLogs, 5000);
+ if (!argsInterval) argsInterval = setInterval(loadActiveArguments, 5000);
+}
+
+function stopPolling() {
+ clearInterval(statusInterval); statusInterval = null;
+ clearInterval(logsInterval); logsInterval = null;
+ clearInterval(argsInterval); argsInterval = null;
+}
+
+function initTabState() {
const savedTab = localStorage.getItem('miku-active-tab');
if (savedTab && document.getElementById(savedTab)) {
switchTab(savedTab);
}
-
- loadStatus();
- loadServers();
- loadLastPrompt();
- loadLogs();
- checkEvilModeStatus(); // Check evil mode on load
- checkBipolarModeStatus(); // Check bipolar mode on load
- checkGPUStatus(); // Check GPU selection on load
- refreshLanguageStatus(); // Check language mode on load
- console.log('🚀 DOMContentLoaded - initializing figurine subscribers list');
- refreshFigurineSubscribers();
- loadProfilePictureMetadata();
- initLogsScrollDetection(); // Set up log auto-scroll tracking
-
- // Enable mouse wheel horizontal scrolling on tab bar
+}
+
+function initTabWheelScroll() {
const tabButtonsEl = document.querySelector('.tab-buttons');
if (tabButtonsEl) {
tabButtonsEl.addEventListener('wheel', function(e) {
@@ -1879,22 +1883,9 @@ document.addEventListener('DOMContentLoaded', function() {
}
}, { passive: false });
}
-
- // Set up periodic updates with visibility-aware polling
- let statusInterval, logsInterval, argsInterval;
-
- function startPolling() {
- if (!statusInterval) statusInterval = setInterval(loadStatus, 10000);
- if (!logsInterval) logsInterval = setInterval(loadLogs, 5000);
- if (!argsInterval) argsInterval = setInterval(loadActiveArguments, 5000);
- }
-
- function stopPolling() {
- clearInterval(statusInterval); statusInterval = null;
- clearInterval(logsInterval); logsInterval = null;
- clearInterval(argsInterval); argsInterval = null;
- }
-
+}
+
+function initVisibilityPolling() {
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
stopPolling();
@@ -1905,7 +1896,71 @@ document.addEventListener('DOMContentLoaded', function() {
console.log('▶️ Tab visible — polling resumed');
}
});
+}
+
+function initChatImagePreview() {
+ const imageInput = document.getElementById('chat-image-file');
+ if (imageInput) {
+ imageInput.addEventListener('change', function(e) {
+ const file = e.target.files[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = function(event) {
+ const preview = document.getElementById('chat-image-preview');
+ const previewImg = document.getElementById('chat-image-preview-img');
+ previewImg.src = event.target.result;
+ preview.style.display = 'block';
+ };
+ reader.readAsDataURL(file);
+ }
+ });
+ }
+}
+
+function initModalAccessibility() {
+ const editModal = document.getElementById('edit-memory-modal');
+ const createModal = document.getElementById('create-memory-modal');
+ if (editModal) {
+ editModal.setAttribute('role', 'dialog');
+ editModal.setAttribute('aria-modal', 'true');
+ editModal.setAttribute('aria-label', 'Edit Memory');
+ editModal.addEventListener('click', function(e) {
+ if (e.target === this) closeEditMemoryModal();
+ });
+ }
+ if (createModal) {
+ createModal.setAttribute('role', 'dialog');
+ createModal.setAttribute('aria-modal', 'true');
+ createModal.setAttribute('aria-label', 'Create Memory');
+ createModal.addEventListener('click', function(e) {
+ if (e.target === this) closeCreateMemoryModal();
+ });
+ }
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+ // Tab & UI initialization
+ initTabState();
+ initTabWheelScroll();
+ initLogsScrollDetection();
+ initChatImagePreview();
+ initModalAccessibility();
+ // Load initial data
+ loadStatus();
+ loadServers();
+ loadLastPrompt();
+ loadLogs();
+ checkEvilModeStatus();
+ checkBipolarModeStatus();
+ checkGPUStatus();
+ refreshLanguageStatus();
+ refreshFigurineSubscribers();
+ loadProfilePictureMetadata();
+ loadVoiceDebugMode();
+
+ // Start polling with visibility awareness
+ initVisibilityPolling();
startPolling();
});
@@ -4980,28 +5035,7 @@ function toggleChatImageUpload() {
}
}
-// Preview uploaded image
-document.addEventListener('DOMContentLoaded', function() {
- const imageInput = document.getElementById('chat-image-file');
- if (imageInput) {
- imageInput.addEventListener('change', function(e) {
- const file = e.target.files[0];
- if (file) {
- const reader = new FileReader();
- reader.onload = function(event) {
- const preview = document.getElementById('chat-image-preview');
- const previewImg = document.getElementById('chat-image-preview-img');
- previewImg.src = event.target.result;
- preview.style.display = 'block';
- };
- reader.readAsDataURL(file);
- }
- });
- }
-
- // Load voice debug mode setting
- loadVoiceDebugMode();
-});
+// (Chat image preview + voice debug mode init moved to consolidated DOMContentLoaded)
// Load voice debug mode setting from server
async function loadVoiceDebugMode() {
@@ -5889,26 +5923,7 @@ document.addEventListener('keydown', function(e) {
}
});
-document.addEventListener('DOMContentLoaded', function() {
- const editModal = document.getElementById('edit-memory-modal');
- const createModal = document.getElementById('create-memory-modal');
- if (editModal) {
- editModal.setAttribute('role', 'dialog');
- editModal.setAttribute('aria-modal', 'true');
- editModal.setAttribute('aria-label', 'Edit Memory');
- editModal.addEventListener('click', function(e) {
- if (e.target === this) closeEditMemoryModal();
- });
- }
- if (createModal) {
- createModal.setAttribute('role', 'dialog');
- createModal.setAttribute('aria-modal', 'true');
- createModal.setAttribute('aria-label', 'Create Memory');
- createModal.addEventListener('click', function(e) {
- if (e.target === this) closeCreateMemoryModal();
- });
- }
-});
+// (Modal accessibility init moved to consolidated DOMContentLoaded)
async function saveNewMemory() {
const collection = document.getElementById('create-memory-collection').value;