mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
Add centralized example images setting and update related UI components
This commit is contained in:
@@ -375,6 +375,12 @@ 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;
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { saveModelMetadata } from '../../api/checkpointApi.js';
|
||||
import { renderCompactTags, setupTagTooltip, formatFileSize } from './utils.js';
|
||||
import { updateCheckpointCard } from '../../utils/cardUpdater.js';
|
||||
import { state } from '../../state/index.js';
|
||||
|
||||
/**
|
||||
* Display the checkpoint modal with the given checkpoint data
|
||||
@@ -149,28 +150,41 @@ export function showCheckpointModal(checkpoint) {
|
||||
}
|
||||
|
||||
// Load example images asynchronously
|
||||
loadExampleImages(checkpoint.civitai?.images, checkpoint.sha256);
|
||||
loadExampleImages(checkpoint.civitai?.images, checkpoint.sha256, checkpoint.file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load example images asynchronously
|
||||
* @param {Array} images - Array of image objects
|
||||
* @param {string} modelHash - Model hash for fetching local files
|
||||
* @param {string} filePath - File path for fetching local files
|
||||
*/
|
||||
async function loadExampleImages(images, modelHash) {
|
||||
async function loadExampleImages(images, modelHash, filePath) {
|
||||
try {
|
||||
const showcaseTab = document.getElementById('showcase-tab');
|
||||
if (!showcaseTab) return;
|
||||
|
||||
// First fetch local example files
|
||||
let localFiles = [];
|
||||
if (modelHash) {
|
||||
try {
|
||||
localFiles = await getExampleImageFiles(modelHash);
|
||||
} catch (error) {
|
||||
console.error("Failed to get example files:", error);
|
||||
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';
|
||||
|
||||
// Use different params based on endpoint
|
||||
const params = useCentralized ?
|
||||
`model_hash=${modelHash}` :
|
||||
`file_path=${encodeURIComponent(filePath)}`;
|
||||
|
||||
const response = await fetch(`${endpoint}?${params}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
localFiles = result.files;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to get example files:", error);
|
||||
}
|
||||
|
||||
// Then render with both remote images and local files
|
||||
showcaseTab.innerHTML = renderShowcaseContent(images, localFiles);
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
import { saveModelMetadata } from '../../api/loraApi.js';
|
||||
import { renderCompactTags, setupTagTooltip, formatFileSize } from './utils.js';
|
||||
import { updateLoraCard } from '../../utils/cardUpdater.js';
|
||||
import { state } from '../../state/index.js';
|
||||
|
||||
/**
|
||||
* 显示LoRA模型弹窗
|
||||
@@ -186,28 +187,42 @@ export function showLoraModal(lora) {
|
||||
loadRecipesForLora(lora.model_name, lora.sha256);
|
||||
|
||||
// Load example images asynchronously
|
||||
loadExampleImages(lora.civitai?.images, lora.sha256);
|
||||
loadExampleImages(lora.civitai?.images, lora.sha256, lora.file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load example images asynchronously
|
||||
* @param {Array} images - Array of image objects
|
||||
* @param {string} modelHash - Model hash for fetching local files
|
||||
* @param {string} filePath - File path for fetching local files
|
||||
*/
|
||||
async function loadExampleImages(images, modelHash) {
|
||||
async function loadExampleImages(images, modelHash, filePath) {
|
||||
try {
|
||||
const showcaseTab = document.getElementById('showcase-tab');
|
||||
if (!showcaseTab) return;
|
||||
|
||||
// First fetch local example files
|
||||
let localFiles = [];
|
||||
if (modelHash) {
|
||||
try {
|
||||
localFiles = await getExampleImageFiles(modelHash);
|
||||
} catch (error) {
|
||||
console.error("Failed to get example files:", error);
|
||||
|
||||
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';
|
||||
|
||||
// Use different params based on endpoint
|
||||
const params = useCentralized ?
|
||||
`model_hash=${modelHash}` :
|
||||
`file_path=${encodeURIComponent(filePath)}`;
|
||||
|
||||
const response = await fetch(`${endpoint}?${params}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
localFiles = result.files;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to get example files:", error);
|
||||
}
|
||||
|
||||
// Then render with both remote images and local files
|
||||
showcaseTab.innerHTML = renderShowcaseContent(images, localFiles);
|
||||
|
||||
@@ -37,6 +37,11 @@ export class SettingsManager {
|
||||
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') {
|
||||
if (state.global.settings.compactMode === true) {
|
||||
@@ -109,6 +114,14 @@ 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();
|
||||
|
||||
@@ -183,6 +196,10 @@ 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;
|
||||
@@ -193,7 +210,7 @@ export class SettingsManager {
|
||||
|
||||
try {
|
||||
// For backend settings, make API call
|
||||
if (['show_only_sfw', 'blur_mature_content', 'autoplay_on_hover', 'optimize_example_images'].includes(settingKey)) {
|
||||
if (['show_only_sfw', 'blur_mature_content', 'autoplay_on_hover', 'optimize_example_images', 'use_centralized_examples'].includes(settingKey)) {
|
||||
const payload = {};
|
||||
payload[settingKey] = value;
|
||||
|
||||
@@ -506,6 +523,42 @@ 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 = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user