mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
Refactor example images management by removing centralized examples settings and migration functionality
This commit is contained in:
@@ -306,18 +306,6 @@ body.modal-open {
|
||||
width: 100%; /* Full width */
|
||||
}
|
||||
|
||||
/* Migrate control styling */
|
||||
.migrate-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.migrate-control input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 统一各个 section 的样式 */
|
||||
.support-section,
|
||||
.changelog-section,
|
||||
@@ -375,12 +363,6 @@ body.modal-open {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
/* Add disabled style for setting items */
|
||||
.setting-item[data-requires-centralized="true"].disabled {
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Control row with label and input together */
|
||||
.setting-row {
|
||||
display: flex;
|
||||
|
||||
@@ -169,14 +169,9 @@ async function loadExampleImages(images, modelHash, filePath) {
|
||||
// First fetch local example files
|
||||
let localFiles = [];
|
||||
try {
|
||||
// Choose endpoint based on centralized examples setting
|
||||
const useCentralized = state.global.settings.useCentralizedExamples !== false;
|
||||
const endpoint = useCentralized ? '/api/example-image-files' : '/api/model-example-files';
|
||||
const endpoint = '/api/example-image-files';
|
||||
|
||||
// Use different params based on endpoint
|
||||
const params = useCentralized ?
|
||||
`model_hash=${modelHash}` :
|
||||
`file_path=${encodeURIComponent(filePath)}`;
|
||||
const params = `model_hash=${modelHash}`;
|
||||
|
||||
const response = await fetch(`${endpoint}?${params}`);
|
||||
const result = await response.json();
|
||||
|
||||
@@ -48,12 +48,6 @@ class ExampleImagesManager {
|
||||
if (collapseBtn) {
|
||||
collapseBtn.onclick = () => this.toggleProgressPanel();
|
||||
}
|
||||
|
||||
// Initialize migration button handler
|
||||
const migrateBtn = document.getElementById('exampleImagesMigrateBtn');
|
||||
if (migrateBtn) {
|
||||
migrateBtn.onclick = () => this.handleMigrateButton();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize event listeners for buttons
|
||||
@@ -149,95 +143,6 @@ class ExampleImagesManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Method to handle migrate button click
|
||||
async handleMigrateButton() {
|
||||
if (this.isDownloading || this.isMigrating) {
|
||||
if (this.isPaused) {
|
||||
// If paused, resume
|
||||
this.resumeDownload();
|
||||
} else {
|
||||
showToast('Migration or download already in progress', 'info');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Start migration
|
||||
this.startMigrate();
|
||||
}
|
||||
|
||||
async startMigrate() {
|
||||
try {
|
||||
const outputDir = document.getElementById('exampleImagesPath').value || '';
|
||||
|
||||
if (!outputDir) {
|
||||
showToast('Please enter a download location first', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update path in backend settings before starting migration
|
||||
try {
|
||||
const pathUpdateResponse = await fetch('/api/settings', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
example_images_path: outputDir
|
||||
})
|
||||
});
|
||||
|
||||
if (!pathUpdateResponse.ok) {
|
||||
throw new Error(`HTTP error! Status: ${pathUpdateResponse.status}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update example images path:', error);
|
||||
}
|
||||
|
||||
const pattern = document.getElementById('exampleImagesMigratePattern').value || '{model}.example.{index}.{ext}';
|
||||
const optimize = document.getElementById('optimizeExampleImages').checked;
|
||||
|
||||
const response = await fetch('/api/migrate-example-images', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
output_dir: outputDir,
|
||||
pattern: pattern,
|
||||
optimize: optimize,
|
||||
model_types: ['lora', 'checkpoint']
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
this.isDownloading = true;
|
||||
this.isMigrating = true;
|
||||
this.isPaused = false;
|
||||
this.hasShownCompletionToast = false; // Reset toast flag when starting new migration
|
||||
this.startTime = new Date();
|
||||
this.updateUI(data.status);
|
||||
this.showProgressPanel();
|
||||
this.startProgressUpdates();
|
||||
// Update button text
|
||||
const btnTextElement = document.getElementById('exampleDownloadBtnText');
|
||||
if (btnTextElement) {
|
||||
btnTextElement.textContent = "Resume";
|
||||
}
|
||||
showToast('Example images migration started', 'success');
|
||||
|
||||
// Close settings modal
|
||||
modalManager.closeModal('settingsModal');
|
||||
} else {
|
||||
showToast(data.error || 'Failed to start migration', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to start migration:', error);
|
||||
showToast('Failed to start migration', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async checkDownloadStatus() {
|
||||
try {
|
||||
const response = await fetch('/api/example-images-status');
|
||||
|
||||
@@ -36,11 +36,6 @@ export class SettingsManager {
|
||||
if (state.global.settings.optimizeExampleImages === undefined) {
|
||||
state.global.settings.optimizeExampleImages = true;
|
||||
}
|
||||
|
||||
// Set default for useCentralizedExamples if undefined
|
||||
if (state.global.settings.useCentralizedExamples === undefined) {
|
||||
state.global.settings.useCentralizedExamples = true;
|
||||
}
|
||||
|
||||
// Convert old boolean compactMode to new displayDensity string
|
||||
if (typeof state.global.settings.displayDensity === 'undefined') {
|
||||
@@ -114,14 +109,6 @@ export class SettingsManager {
|
||||
optimizeExampleImagesCheckbox.checked = state.global.settings.optimizeExampleImages || false;
|
||||
}
|
||||
|
||||
// Set centralized examples setting
|
||||
const useCentralizedExamplesCheckbox = document.getElementById('useCentralizedExamples');
|
||||
if (useCentralizedExamplesCheckbox) {
|
||||
useCentralizedExamplesCheckbox.checked = state.global.settings.useCentralizedExamples !== false;
|
||||
// Update dependent controls
|
||||
this.updateExamplesControlsState();
|
||||
}
|
||||
|
||||
// Load default lora root
|
||||
await this.loadLoraRoots();
|
||||
|
||||
@@ -196,10 +183,6 @@ export class SettingsManager {
|
||||
state.global.settings.optimizeExampleImages = value;
|
||||
} else if (settingKey === 'compact_mode') {
|
||||
state.global.settings.compactMode = value;
|
||||
} else if (settingKey === 'use_centralized_examples') {
|
||||
state.global.settings.useCentralizedExamples = value;
|
||||
// Update dependent controls state
|
||||
this.updateExamplesControlsState();
|
||||
} else {
|
||||
// For any other settings that might be added in the future
|
||||
state.global.settings[settingKey] = value;
|
||||
@@ -523,42 +506,6 @@ export class SettingsManager {
|
||||
// Add the appropriate density class
|
||||
grid.classList.add(`${density}-density`);
|
||||
}
|
||||
|
||||
// Apply centralized examples toggle state
|
||||
this.updateExamplesControlsState();
|
||||
}
|
||||
|
||||
// Add new method to update example control states
|
||||
updateExamplesControlsState() {
|
||||
const useCentralized = state.global.settings.useCentralizedExamples !== false;
|
||||
|
||||
// Find all controls that require centralized mode
|
||||
const exampleSections = document.querySelectorAll('[data-requires-centralized="true"]');
|
||||
exampleSections.forEach(section => {
|
||||
// Enable/disable all inputs and buttons in the section
|
||||
const controls = section.querySelectorAll('input, button, select');
|
||||
controls.forEach(control => {
|
||||
control.disabled = !useCentralized;
|
||||
|
||||
// Add/remove disabled class for styling
|
||||
if (control.classList.contains('primary-btn') || control.classList.contains('secondary-btn')) {
|
||||
if (!useCentralized) {
|
||||
control.classList.add('disabled');
|
||||
} else {
|
||||
control.classList.remove('disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Visually show the section as disabled
|
||||
if (!useCentralized) {
|
||||
section.style.opacity = '0.6';
|
||||
section.style.pointerEvents = 'none';
|
||||
} else {
|
||||
section.style.opacity = '';
|
||||
section.style.pointerEvents = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -256,26 +256,6 @@
|
||||
<h3>Example Images</h3>
|
||||
|
||||
<div class="setting-item">
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<label for="useCentralizedExamples">Use Centralized Example Storage</label>
|
||||
</div>
|
||||
<div class="setting-control">
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="useCentralizedExamples" checked
|
||||
onchange="settingsManager.saveToggleSetting('useCentralizedExamples', 'use_centralized_examples')">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-help">
|
||||
When enabled (recommended), example images are stored in a central folder for better organization and performance.
|
||||
When disabled, only example images stored alongside models (e.g., model-name.example.0.jpg) will be shown, but download
|
||||
and management features will be unavailable.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-item" data-requires-centralized="true">
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<label for="exampleImagesPath">Download Location <i class="fas fa-sync-alt restart-required-icon" title="Requires restart"></i></label>
|
||||
@@ -291,29 +271,8 @@
|
||||
Enter the folder path where example images from Civitai will be saved
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New migrate section -->
|
||||
<div class="setting-item" data-requires-centralized="true">
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<label for="exampleImagesMigratePattern">Migrate Existing Example Images</label>
|
||||
</div>
|
||||
<div class="setting-control migrate-control">
|
||||
<input type="text" id="exampleImagesMigratePattern"
|
||||
placeholder="{model}.example.{index}.{ext}"
|
||||
value="{model}.example.{index}.{ext}" />
|
||||
<button id="exampleImagesMigrateBtn" class="secondary-btn">
|
||||
<i class="fas fa-file-import"></i> <span>Migrate</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-help">
|
||||
Pattern to find existing example images. Use {model} for model filename, {index} for numbering, and {ext} for file extension.<br>
|
||||
Example patterns: "{model}.example.{index}.{ext}", "{model}_{index}.{ext}", "{model}/{model}.example.{index}.{ext}"
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-item" data-requires-centralized="true">
|
||||
<div class="setting-item">
|
||||
<div class="setting-row">
|
||||
<div class="setting-info">
|
||||
<label for="optimizeExampleImages">Optimize Downloaded Images</label>
|
||||
|
||||
Reference in New Issue
Block a user