mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
feat: implement settings synchronization with backend and migrate legacy settings
This commit is contained in:
@@ -167,6 +167,9 @@ class MiscRoutes:
|
|||||||
|
|
||||||
# Validate and update settings
|
# Validate and update settings
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
|
if value == settings.get(key):
|
||||||
|
# No change, skip
|
||||||
|
continue
|
||||||
# Special handling for example_images_path - verify path exists
|
# Special handling for example_images_path - verify path exists
|
||||||
if key == 'example_images_path' and value:
|
if key == 'example_images_path' and value:
|
||||||
if not os.path.exists(value):
|
if not os.path.exists(value):
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class MoveManager {
|
|||||||
).join('');
|
).join('');
|
||||||
|
|
||||||
// Set default lora root if available
|
// Set default lora root if available
|
||||||
const defaultRoot = getStorageItem('settings', {}).default_loras_root;
|
const defaultRoot = getStorageItem('settings', {}).default_lora_root;
|
||||||
if (defaultRoot && rootsData.roots.includes(defaultRoot)) {
|
if (defaultRoot && rootsData.roots.includes(defaultRoot)) {
|
||||||
this.loraRootSelect.value = defaultRoot;
|
this.loraRootSelect.value = defaultRoot;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,29 +15,39 @@ export class SettingsManager {
|
|||||||
|
|
||||||
// Ensure settings are loaded from localStorage
|
// Ensure settings are loaded from localStorage
|
||||||
this.loadSettingsFromStorage();
|
this.loadSettingsFromStorage();
|
||||||
|
|
||||||
|
// Sync settings to backend if needed
|
||||||
|
this.syncSettingsToBackendIfNeeded();
|
||||||
|
|
||||||
this.initialize();
|
this.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSettingsFromStorage() {
|
loadSettingsFromStorage() {
|
||||||
// Get saved settings from localStorage
|
// Get saved settings from localStorage
|
||||||
const savedSettings = getStorageItem('settings');
|
const savedSettings = getStorageItem('settings');
|
||||||
|
|
||||||
|
// Migrate legacy default_loras_root to default_lora_root if present
|
||||||
|
if (savedSettings && savedSettings.default_loras_root && !savedSettings.default_lora_root) {
|
||||||
|
savedSettings.default_lora_root = savedSettings.default_loras_root;
|
||||||
|
delete savedSettings.default_loras_root;
|
||||||
|
setStorageItem('settings', savedSettings);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply saved settings to state if available
|
// Apply saved settings to state if available
|
||||||
if (savedSettings) {
|
if (savedSettings) {
|
||||||
state.global.settings = { ...state.global.settings, ...savedSettings };
|
state.global.settings = { ...state.global.settings, ...savedSettings };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize default values for new settings if they don't exist
|
// Initialize default values for new settings if they don't exist
|
||||||
if (state.global.settings.compactMode === undefined) {
|
if (state.global.settings.compactMode === undefined) {
|
||||||
state.global.settings.compactMode = false;
|
state.global.settings.compactMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default for optimizeExampleImages if undefined
|
// Set default for optimizeExampleImages if undefined
|
||||||
if (state.global.settings.optimizeExampleImages === undefined) {
|
if (state.global.settings.optimizeExampleImages === undefined) {
|
||||||
state.global.settings.optimizeExampleImages = true;
|
state.global.settings.optimizeExampleImages = 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';
|
||||||
@@ -74,6 +84,50 @@ export class SettingsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async syncSettingsToBackendIfNeeded() {
|
||||||
|
// Get local settings from storage
|
||||||
|
const localSettings = getStorageItem('settings') || {};
|
||||||
|
|
||||||
|
// Fields that need to be synced to backend
|
||||||
|
const fieldsToSync = [
|
||||||
|
'civitai_api_key',
|
||||||
|
'default_lora_root',
|
||||||
|
'default_checkpoint_root',
|
||||||
|
'default_embedding_root',
|
||||||
|
'base_model_path_mappings',
|
||||||
|
'download_path_template'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Build payload for syncing
|
||||||
|
const payload = {};
|
||||||
|
|
||||||
|
fieldsToSync.forEach(key => {
|
||||||
|
if (localSettings[key] !== undefined) {
|
||||||
|
if (key === 'base_model_path_mappings') {
|
||||||
|
payload[key] = JSON.stringify(localSettings[key]);
|
||||||
|
} else {
|
||||||
|
payload[key] = localSettings[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Only send request if there is something to sync
|
||||||
|
if (Object.keys(payload).length > 0) {
|
||||||
|
try {
|
||||||
|
await fetch('/api/settings', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
});
|
||||||
|
// Log success to console
|
||||||
|
console.log('Settings synced to backend');
|
||||||
|
} catch (e) {
|
||||||
|
// Log error to console
|
||||||
|
console.error('Failed to sync settings to backend:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
if (this.initialized) return;
|
if (this.initialized) return;
|
||||||
|
|
||||||
@@ -159,8 +213,6 @@ export class SettingsManager {
|
|||||||
|
|
||||||
// Load default embedding root
|
// Load default embedding root
|
||||||
await this.loadEmbeddingRoots();
|
await this.loadEmbeddingRoots();
|
||||||
|
|
||||||
// Backend settings are loaded from the template directly
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadLoraRoots() {
|
async loadLoraRoots() {
|
||||||
@@ -193,7 +245,7 @@ export class SettingsManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Set selected value from settings
|
// Set selected value from settings
|
||||||
const defaultRoot = state.global.settings.default_loras_root || '';
|
const defaultRoot = state.global.settings.default_lora_root || '';
|
||||||
defaultLoraRootSelect.value = defaultRoot;
|
defaultLoraRootSelect.value = defaultRoot;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -507,7 +559,7 @@ export class SettingsManager {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// For backend settings, make API call
|
// For backend settings, make API call
|
||||||
if (['show_only_sfw', 'blur_mature_content', 'autoplay_on_hover', 'optimize_example_images', 'use_centralized_examples'].includes(settingKey)) {
|
if (['show_only_sfw'].includes(settingKey)) {
|
||||||
const payload = {};
|
const payload = {};
|
||||||
payload[settingKey] = value;
|
payload[settingKey] = value;
|
||||||
|
|
||||||
@@ -552,7 +604,7 @@ export class SettingsManager {
|
|||||||
|
|
||||||
// Update frontend state
|
// Update frontend state
|
||||||
if (settingKey === 'default_lora_root') {
|
if (settingKey === 'default_lora_root') {
|
||||||
state.global.settings.default_loras_root = value;
|
state.global.settings.default_lora_root = value;
|
||||||
} else if (settingKey === 'default_checkpoint_root') {
|
} else if (settingKey === 'default_checkpoint_root') {
|
||||||
state.global.settings.default_checkpoint_root = value;
|
state.global.settings.default_checkpoint_root = value;
|
||||||
} else if (settingKey === 'default_embedding_root') {
|
} else if (settingKey === 'default_embedding_root') {
|
||||||
@@ -632,10 +684,7 @@ export class SettingsManager {
|
|||||||
// Update state
|
// Update state
|
||||||
state.global.settings[settingKey] = value;
|
state.global.settings[settingKey] = value;
|
||||||
|
|
||||||
// Save to localStorage if appropriate
|
setStorageItem('settings', state.global.settings);
|
||||||
if (!settingKey.includes('api_key')) { // Don't store API keys in localStorage for security
|
|
||||||
setStorageItem('settings', state.global.settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For backend settings, make API call
|
// For backend settings, make API call
|
||||||
const payload = {};
|
const payload = {};
|
||||||
@@ -717,69 +766,6 @@ export class SettingsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveSettings() {
|
|
||||||
// Get frontend settings from UI
|
|
||||||
const blurMatureContent = document.getElementById('blurMatureContent').checked;
|
|
||||||
const showOnlySFW = document.getElementById('showOnlySFW').checked;
|
|
||||||
const defaultLoraRoot = document.getElementById('defaultLoraRoot').value;
|
|
||||||
const defaultCheckpointRoot = document.getElementById('defaultCheckpointRoot').value;
|
|
||||||
const autoplayOnHover = document.getElementById('autoplayOnHover').checked;
|
|
||||||
const optimizeExampleImages = document.getElementById('optimizeExampleImages').checked;
|
|
||||||
|
|
||||||
// Get backend settings
|
|
||||||
const apiKey = document.getElementById('civitaiApiKey').value;
|
|
||||||
|
|
||||||
// Update frontend state and save to localStorage
|
|
||||||
state.global.settings.blurMatureContent = blurMatureContent;
|
|
||||||
state.global.settings.show_only_sfw = showOnlySFW;
|
|
||||||
state.global.settings.default_loras_root = defaultLoraRoot;
|
|
||||||
state.global.settings.default_checkpoint_root = defaultCheckpointRoot;
|
|
||||||
state.global.settings.autoplayOnHover = autoplayOnHover;
|
|
||||||
state.global.settings.optimizeExampleImages = optimizeExampleImages;
|
|
||||||
|
|
||||||
// Save settings to localStorage
|
|
||||||
setStorageItem('settings', state.global.settings);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Save backend settings via API
|
|
||||||
const response = await fetch('/api/settings', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
civitai_api_key: apiKey,
|
|
||||||
show_only_sfw: showOnlySFW,
|
|
||||||
optimize_example_images: optimizeExampleImages,
|
|
||||||
default_checkpoint_root: defaultCheckpointRoot
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Failed to save settings');
|
|
||||||
}
|
|
||||||
|
|
||||||
showToast('Settings saved successfully', 'success');
|
|
||||||
modalManager.closeModal('settingsModal');
|
|
||||||
|
|
||||||
// Apply frontend settings immediately
|
|
||||||
this.applyFrontendSettings();
|
|
||||||
|
|
||||||
if (this.currentPage === 'loras') {
|
|
||||||
// Reload the loras without updating folders
|
|
||||||
await resetAndReload(false);
|
|
||||||
} else if (this.currentPage === 'recipes') {
|
|
||||||
// Reload the recipes without updating folders
|
|
||||||
await window.recipeManager.loadRecipes();
|
|
||||||
} else if (this.currentPage === 'checkpoints') {
|
|
||||||
// Reload the checkpoints without updating folders
|
|
||||||
await window.checkpointsManager.loadCheckpoints();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
showToast('Failed to save settings: ' + error.message, 'error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applyFrontendSettings() {
|
applyFrontendSettings() {
|
||||||
// Apply blur setting to existing content
|
// Apply blur setting to existing content
|
||||||
const blurSetting = state.global.settings.blurMatureContent;
|
const blurSetting = state.global.settings.blurMatureContent;
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export class FolderBrowser {
|
|||||||
).join('');
|
).join('');
|
||||||
|
|
||||||
// Set default lora root if available
|
// Set default lora root if available
|
||||||
const defaultRoot = getStorageItem('settings', {}).default_loras_root;
|
const defaultRoot = getStorageItem('settings', {}).default_lora_root;
|
||||||
if (defaultRoot && rootsData.roots.includes(defaultRoot)) {
|
if (defaultRoot && rootsData.roots.includes(defaultRoot)) {
|
||||||
loraRoot.value = defaultRoot;
|
loraRoot.value = defaultRoot;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user