refactor: Modularize monolithic HTML control panel into organized components
This commit completes a major refactoring of the Miku control panel from a single 7,191-line monolithic HTML file to a modern modular architecture: CHANGES: - Extracted 872 lines of CSS into css/style.css - Created 10 specialized JavaScript modules (4,964 lines total): * core.js: Global state, utilities, initialization, polling system * servers.js: Server management and mood handling * modes.js: Evil mode, GPU selection, bipolar mode, scoreboard * actions.js: Autonomous/manual actions, custom prompts, reactions * image-gen.js: Image generation system * status.js: Status display and statistics * dm.js: DM user management and conversation analysis * chat.js: LLM chat interface with streaming and voice calls * memories.js: Cheshire Cat memory integration (episodic/declarative/procedural) * profile.js: Profile picture, album gallery, activities editor - Cleaned index.html to 1,351 lines (structure only, zero inline JS/CSS) - Removed 12 duplicate variable declarations - Maintained strict script load order for dependency resolution - Added backup comment to index.html.bak for historical reference VERIFICATION COMPLETED: ✓ All 191 functions/variables from original accounted for ✓ Cross-referenced with backup to ensure nothing lost ✓ All onclick handlers and modal systems validated ✓ No circular dependencies or broken references ✓ HTML structure integrity verified (11 tabs, all buttons/modals intact) ✓ CropperJS CDN links preserved The refactored code is production-ready with improved maintainability and clear separation of concerns.
This commit is contained in:
127
bot/static/js/image-gen.js
Normal file
127
bot/static/js/image-gen.js
Normal file
@@ -0,0 +1,127 @@
|
||||
// ============================================================================
|
||||
// Miku Control Panel — Image Generation Module
|
||||
// ============================================================================
|
||||
|
||||
async function checkImageSystemStatus() {
|
||||
try {
|
||||
const statusDisplay = document.getElementById('image-status-display');
|
||||
statusDisplay.innerHTML = '🔄 Checking system status...';
|
||||
|
||||
const result = await apiCall('/image/status');
|
||||
|
||||
const workflowStatus = result.workflow_template_exists ? '✅ Found' : '❌ Missing';
|
||||
const comfyuiStatus = result.comfyui_running ? '✅ Running' : '❌ Not running';
|
||||
|
||||
statusDisplay.innerHTML = `
|
||||
<strong>System Status:</strong>
|
||||
• Workflow Template (Miku_BasicWorkflow.json): ${workflowStatus}
|
||||
• ComfyUI Server: ${comfyuiStatus}
|
||||
${result.comfyui_running ? `• Detected ComfyUI URL: ${result.comfyui_url}` : ''}
|
||||
|
||||
<strong>Overall Status:</strong> ${result.ready ? '✅ Ready for image generation' : '⚠️ Setup required'}
|
||||
|
||||
${!result.workflow_template_exists ? '⚠️ Place Miku_BasicWorkflow.json in bot directory\n' : ''}${!result.comfyui_running ? '⚠️ Start ComfyUI server on localhost:8188 (bot will auto-detect correct URL)\n' : ''}`;
|
||||
} catch (error) {
|
||||
console.error('Failed to check image system status:', error);
|
||||
document.getElementById('image-status-display').innerHTML = `❌ Error: ${error.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
async function testImageDetection() {
|
||||
const message = document.getElementById('detection-test-message').value.trim();
|
||||
const resultsDiv = document.getElementById('detection-test-results');
|
||||
|
||||
if (!message) {
|
||||
resultsDiv.innerHTML = '❌ Please enter a test message';
|
||||
resultsDiv.style.color = 'red';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
resultsDiv.innerHTML = '🔍 Testing detection...';
|
||||
resultsDiv.style.color = '#4CAF50';
|
||||
|
||||
const result = await apiCall('/image/test-detection', 'POST', { message: message });
|
||||
|
||||
const detectionIcon = result.is_image_request ? '✅' : '❌';
|
||||
const detectionText = result.is_image_request ? 'WILL trigger image generation' : 'will NOT trigger image generation';
|
||||
|
||||
resultsDiv.innerHTML = `
|
||||
<strong>Detection Result:</strong> ${detectionIcon} This message ${detectionText}
|
||||
${result.is_image_request ? `<br><strong>Extracted Prompt:</strong> "${result.extracted_prompt}"` : ''}
|
||||
<br><strong>Original Message:</strong> "${result.original_message}"`;
|
||||
|
||||
resultsDiv.style.color = result.is_image_request ? '#4CAF50' : '#ff9800';
|
||||
} catch (error) {
|
||||
console.error('Failed to test image detection:', error);
|
||||
resultsDiv.innerHTML = `❌ Error: ${error.message}`;
|
||||
resultsDiv.style.color = 'red';
|
||||
}
|
||||
}
|
||||
|
||||
async function generateManualImage() {
|
||||
const prompt = document.getElementById('manual-image-prompt').value.trim();
|
||||
const statusDiv = document.getElementById('manual-image-status');
|
||||
const previewDiv = document.getElementById('manual-image-preview');
|
||||
|
||||
if (!prompt) {
|
||||
statusDiv.innerHTML = '❌ Please enter an image prompt';
|
||||
statusDiv.style.color = 'red';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
previewDiv.innerHTML = '';
|
||||
|
||||
statusDiv.innerHTML = '🎨 Generating image... This may take a few minutes.';
|
||||
statusDiv.style.color = '#4CAF50';
|
||||
|
||||
const result = await apiCall('/image/generate', 'POST', { prompt: prompt });
|
||||
|
||||
statusDiv.innerHTML = `✅ Image generated successfully!`;
|
||||
statusDiv.style.color = '#4CAF50';
|
||||
|
||||
if (result.image_path) {
|
||||
const filename = result.image_path.split('/').pop();
|
||||
const imageUrl = `/image/view/${encodeURIComponent(filename)}`;
|
||||
|
||||
const imgContainer = document.createElement('div');
|
||||
imgContainer.style.cssText = 'background: #1e1e1e; padding: 1rem; border-radius: 8px; border: 1px solid #333;';
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = imageUrl;
|
||||
img.alt = 'Generated Image';
|
||||
img.style.cssText = 'max-width: 100%; max-height: 600px; border-radius: 4px; display: block; margin: 0 auto;';
|
||||
|
||||
img.onload = function() {
|
||||
console.log('Image loaded successfully:', imageUrl);
|
||||
};
|
||||
|
||||
img.onerror = function() {
|
||||
console.error('Failed to load image:', imageUrl);
|
||||
imgContainer.innerHTML = `
|
||||
<div style="color: #f44336; padding: 1rem; text-align: center;">
|
||||
❌ Failed to load image<br>
|
||||
<span style="font-size: 0.85rem;">Path: ${result.image_path}</span><br>
|
||||
<span style="font-size: 0.85rem;">URL: ${imageUrl}</span>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
||||
imgContainer.appendChild(img);
|
||||
|
||||
const pathInfo = document.createElement('div');
|
||||
pathInfo.style.cssText = 'margin-top: 0.5rem; color: #aaa; font-size: 0.85rem; text-align: center;';
|
||||
pathInfo.innerHTML = `<strong>File:</strong> ${filename}`;
|
||||
imgContainer.appendChild(pathInfo);
|
||||
|
||||
previewDiv.appendChild(imgContainer);
|
||||
}
|
||||
|
||||
document.getElementById('manual-image-prompt').value = '';
|
||||
} catch (error) {
|
||||
console.error('Failed to generate image:', error);
|
||||
statusDiv.innerHTML = `❌ Error: ${error.message}`;
|
||||
statusDiv.style.color = 'red';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user