mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
feat: add auto download setting for example images with UI toggle and functionality, fixes #288
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { showToast } from '../utils/uiHelpers.js';
|
import { showToast } from '../utils/uiHelpers.js';
|
||||||
|
import { state } from '../state/index.js';
|
||||||
import { getStorageItem, setStorageItem } from '../utils/storageHelpers.js';
|
import { getStorageItem, setStorageItem } from '../utils/storageHelpers.js';
|
||||||
|
|
||||||
// ExampleImagesManager.js
|
// ExampleImagesManager.js
|
||||||
@@ -14,6 +15,12 @@ class ExampleImagesManager {
|
|||||||
this.isMigrating = false; // Track migration state separately from downloading
|
this.isMigrating = false; // Track migration state separately from downloading
|
||||||
this.hasShownCompletionToast = false; // Flag to track if completion toast has been shown
|
this.hasShownCompletionToast = false; // Flag to track if completion toast has been shown
|
||||||
|
|
||||||
|
// Auto download properties
|
||||||
|
this.autoDownloadInterval = null;
|
||||||
|
this.lastAutoDownloadCheck = 0;
|
||||||
|
this.autoDownloadCheckInterval = 10 * 60 * 1000; // 10 minutes in milliseconds
|
||||||
|
this.pageInitTime = Date.now(); // Track when page was initialized
|
||||||
|
|
||||||
// Initialize download path field and check download status
|
// Initialize download path field and check download status
|
||||||
this.initializePathOptions();
|
this.initializePathOptions();
|
||||||
this.checkDownloadStatus();
|
this.checkDownloadStatus();
|
||||||
@@ -48,6 +55,14 @@ class ExampleImagesManager {
|
|||||||
if (collapseBtn) {
|
if (collapseBtn) {
|
||||||
collapseBtn.onclick = () => this.toggleProgressPanel();
|
collapseBtn.onclick = () => this.toggleProgressPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup auto download if enabled
|
||||||
|
if (state.global.settings.autoDownloadExampleImages) {
|
||||||
|
this.setupAutoDownload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make this instance globally accessible
|
||||||
|
window.exampleImagesManager = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize event listeners for buttons
|
// Initialize event listeners for buttons
|
||||||
@@ -133,6 +148,15 @@ class ExampleImagesManager {
|
|||||||
console.error('Failed to update example images path:', error);
|
console.error('Failed to update example images path:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup or clear auto download based on path availability
|
||||||
|
if (state.global.settings.autoDownloadExampleImages) {
|
||||||
|
if (hasPath) {
|
||||||
|
this.setupAutoDownload();
|
||||||
|
} else {
|
||||||
|
this.clearAutoDownload();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to initialize path options:', error);
|
console.error('Failed to initialize path options:', error);
|
||||||
@@ -646,6 +670,121 @@ class ExampleImagesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupAutoDownload() {
|
||||||
|
// Only setup if conditions are met
|
||||||
|
if (!this.canAutoDownload()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear any existing interval
|
||||||
|
this.clearAutoDownload();
|
||||||
|
|
||||||
|
// Wait at least 30 seconds after page initialization before first check
|
||||||
|
const timeSinceInit = Date.now() - this.pageInitTime;
|
||||||
|
const initialDelay = Math.max(60000 - timeSinceInit, 5000); // At least 5 seconds, up to 60 seconds
|
||||||
|
|
||||||
|
console.log(`Setting up auto download with initial delay of ${initialDelay}ms`);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
// Do initial check
|
||||||
|
this.performAutoDownloadCheck();
|
||||||
|
|
||||||
|
// Set up recurring interval
|
||||||
|
this.autoDownloadInterval = setInterval(() => {
|
||||||
|
this.performAutoDownloadCheck();
|
||||||
|
}, this.autoDownloadCheckInterval);
|
||||||
|
|
||||||
|
}, initialDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearAutoDownload() {
|
||||||
|
if (this.autoDownloadInterval) {
|
||||||
|
clearInterval(this.autoDownloadInterval);
|
||||||
|
this.autoDownloadInterval = null;
|
||||||
|
console.log('Auto download interval cleared');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
canAutoDownload() {
|
||||||
|
// Check if auto download is enabled
|
||||||
|
if (!state.global.settings.autoDownloadExampleImages) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if download path is set
|
||||||
|
const pathInput = document.getElementById('exampleImagesPath');
|
||||||
|
if (!pathInput || !pathInput.value.trim()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if already downloading
|
||||||
|
if (this.isDownloading) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async performAutoDownloadCheck() {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
// Prevent too frequent checks (minimum 2 minutes between checks)
|
||||||
|
if (now - this.lastAutoDownloadCheck < 2 * 60 * 1000) {
|
||||||
|
console.log('Skipping auto download check - too soon since last check');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastAutoDownloadCheck = now;
|
||||||
|
|
||||||
|
if (!this.canAutoDownload()) {
|
||||||
|
console.log('Auto download conditions not met, skipping check');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Performing auto download check...');
|
||||||
|
|
||||||
|
const outputDir = document.getElementById('exampleImagesPath').value;
|
||||||
|
const optimize = document.getElementById('optimizeExampleImages').checked;
|
||||||
|
|
||||||
|
const response = await fetch('/api/download-example-images', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
output_dir: outputDir,
|
||||||
|
optimize: optimize,
|
||||||
|
model_types: ['lora', 'checkpoint', 'embedding'],
|
||||||
|
auto_mode: true // Flag to indicate this is an automatic download
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
// Only show progress if there are actually items to download
|
||||||
|
if (data.status && data.status.total > 0) {
|
||||||
|
this.isDownloading = true;
|
||||||
|
this.isPaused = false;
|
||||||
|
this.hasShownCompletionToast = false;
|
||||||
|
this.startTime = new Date();
|
||||||
|
this.updateUI(data.status);
|
||||||
|
this.showProgressPanel();
|
||||||
|
this.startProgressUpdates();
|
||||||
|
this.updateDownloadButtonText();
|
||||||
|
console.log(`Auto download started: ${data.status.total} items to process`);
|
||||||
|
} else {
|
||||||
|
console.log('Auto download check completed - no new items to download');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('Auto download check failed:', data.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Auto download check error:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create singleton instance
|
// Create singleton instance
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ export class SettingsManager {
|
|||||||
state.global.settings.optimizeExampleImages = true;
|
state.global.settings.optimizeExampleImages = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set default for autoDownloadExampleImages if undefined
|
||||||
|
if (state.global.settings.autoDownloadExampleImages === undefined) {
|
||||||
|
state.global.settings.autoDownloadExampleImages = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Set default for cardInfoDisplay if undefined
|
// Set default for cardInfoDisplay if undefined
|
||||||
if (state.global.settings.cardInfoDisplay === undefined) {
|
if (state.global.settings.cardInfoDisplay === undefined) {
|
||||||
state.global.settings.cardInfoDisplay = 'always';
|
state.global.settings.cardInfoDisplay = 'always';
|
||||||
@@ -195,6 +200,12 @@ export class SettingsManager {
|
|||||||
optimizeExampleImagesCheckbox.checked = state.global.settings.optimizeExampleImages || false;
|
optimizeExampleImagesCheckbox.checked = state.global.settings.optimizeExampleImages || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set auto download example images setting
|
||||||
|
const autoDownloadExampleImagesCheckbox = document.getElementById('autoDownloadExampleImages');
|
||||||
|
if (autoDownloadExampleImagesCheckbox) {
|
||||||
|
autoDownloadExampleImagesCheckbox.checked = state.global.settings.autoDownloadExampleImages || false;
|
||||||
|
}
|
||||||
|
|
||||||
// Set download path template setting
|
// Set download path template setting
|
||||||
const downloadPathTemplateSelect = document.getElementById('downloadPathTemplate');
|
const downloadPathTemplateSelect = document.getElementById('downloadPathTemplate');
|
||||||
if (downloadPathTemplateSelect) {
|
if (downloadPathTemplateSelect) {
|
||||||
@@ -547,6 +558,8 @@ export class SettingsManager {
|
|||||||
state.global.settings.autoplayOnHover = value;
|
state.global.settings.autoplayOnHover = value;
|
||||||
} else if (settingKey === 'optimize_example_images') {
|
} else if (settingKey === 'optimize_example_images') {
|
||||||
state.global.settings.optimizeExampleImages = value;
|
state.global.settings.optimizeExampleImages = value;
|
||||||
|
} else if (settingKey === 'auto_download_example_images') {
|
||||||
|
state.global.settings.autoDownloadExampleImages = value;
|
||||||
} else if (settingKey === 'compact_mode') {
|
} else if (settingKey === 'compact_mode') {
|
||||||
state.global.settings.compactMode = value;
|
state.global.settings.compactMode = value;
|
||||||
} else {
|
} else {
|
||||||
@@ -581,6 +594,15 @@ export class SettingsManager {
|
|||||||
// Apply frontend settings immediately
|
// Apply frontend settings immediately
|
||||||
this.applyFrontendSettings();
|
this.applyFrontendSettings();
|
||||||
|
|
||||||
|
// Trigger auto download setup/teardown when setting changes
|
||||||
|
if (settingKey === 'auto_download_example_images' && window.exampleImagesManager) {
|
||||||
|
if (value) {
|
||||||
|
window.exampleImagesManager.setupAutoDownload();
|
||||||
|
} else {
|
||||||
|
window.exampleImagesManager.clearAutoDownload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (settingKey === 'show_only_sfw') {
|
if (settingKey === 'show_only_sfw') {
|
||||||
this.reloadContent();
|
this.reloadContent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,6 +272,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="setting-item">
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-info">
|
||||||
|
<label for="autoDownloadExampleImages">Auto Download Example Images</label>
|
||||||
|
</div>
|
||||||
|
<div class="setting-control">
|
||||||
|
<label class="toggle-switch">
|
||||||
|
<input type="checkbox" id="autoDownloadExampleImages" checked
|
||||||
|
onchange="settingsManager.saveToggleSetting('autoDownloadExampleImages', 'auto_download_example_images')">
|
||||||
|
<span class="toggle-slider"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-help">
|
||||||
|
Automatically download example images for models that don't have them (requires download location to be set)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<div class="setting-row">
|
<div class="setting-row">
|
||||||
<div class="setting-info">
|
<div class="setting-info">
|
||||||
|
|||||||
Reference in New Issue
Block a user