Files
ComfyUI-Lora-Manager/static/js/managers/SettingsManager.js
Will Miao 372d74ec71 Enhance settings management and localStorage integration
- Added functionality to load settings from localStorage in the SettingsManager, ensuring user preferences are retained across sessions.
- Updated the state management to initialize settings from localStorage, improving user experience.
- Refactored the UpdateService to streamline update notification preferences.
- Improved migration logic in storageHelpers to prevent duplicate migrations and ensure data integrity.
- Removed unnecessary console logs for cleaner output in various modules.
2025-03-22 08:46:36 +08:00

163 lines
5.8 KiB
JavaScript

import { modalManager } from './ModalManager.js';
import { showToast } from '../utils/uiHelpers.js';
import { state } from '../state/index.js';
import { resetAndReload } from '../api/loraApi.js';
import { setStorageItem, getStorageItem } from '../utils/storageHelpers.js';
export class SettingsManager {
constructor() {
this.initialized = false;
this.isOpen = false;
// Add initialization to sync with modal state
this.currentPage = document.body.dataset.page || 'loras';
// Ensure settings are loaded from localStorage
this.loadSettingsFromStorage();
this.initialize();
}
loadSettingsFromStorage() {
// Get saved settings from localStorage
const savedSettings = getStorageItem('settings');
// Apply saved settings to state if available
if (savedSettings) {
state.global.settings = { ...state.global.settings, ...savedSettings };
}
}
initialize() {
if (this.initialized) return;
// Add event listener to sync state when modal is closed via other means (like Escape key)
const settingsModal = document.getElementById('settingsModal');
if (settingsModal) {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
this.isOpen = settingsModal.style.display === 'block';
// When modal is opened, update checkbox state from current settings
if (this.isOpen) {
this.loadSettingsToUI();
}
}
});
});
observer.observe(settingsModal, { attributes: true });
}
this.initialized = true;
}
loadSettingsToUI() {
// Set frontend settings from state
const blurMatureContentCheckbox = document.getElementById('blurMatureContent');
if (blurMatureContentCheckbox) {
blurMatureContentCheckbox.checked = state.global.settings.blurMatureContent;
}
const showOnlySFWCheckbox = document.getElementById('showOnlySFW');
if (showOnlySFWCheckbox) {
// Sync with state (backend will set this via template)
state.global.settings.show_only_sfw = showOnlySFWCheckbox.checked;
}
// Backend settings are loaded from the template directly
}
toggleSettings() {
if (this.isOpen) {
modalManager.closeModal('settingsModal');
} else {
modalManager.showModal('settingsModal');
}
this.isOpen = !this.isOpen;
}
async saveSettings() {
// Get frontend settings from UI
const blurMatureContent = document.getElementById('blurMatureContent').checked;
// Get backend settings
const apiKey = document.getElementById('civitaiApiKey').value;
const showOnlySFW = document.getElementById('showOnlySFW').checked;
// Update frontend state and save to localStorage
state.global.settings.blurMatureContent = blurMatureContent;
state.global.settings.show_only_sfw = showOnlySFW;
// 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
})
});
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() {
// Apply blur setting to existing content
const blurSetting = state.global.settings.blurMatureContent;
document.querySelectorAll('.lora-card[data-nsfw="true"] .card-image').forEach(img => {
if (blurSetting) {
img.classList.add('nsfw-blur');
} else {
img.classList.remove('nsfw-blur');
}
});
// For show_only_sfw, there's no immediate action needed as it affects content loading
// The setting will take effect on next reload
}
}
// Helper function for toggling API key visibility
export function toggleApiKeyVisibility(button) {
const input = button.parentElement.querySelector('input');
const icon = button.querySelector('i');
if (input.type === 'password') {
input.type = 'text';
icon.className = 'fas fa-eye-slash';
} else {
input.type = 'password';
icon.className = 'fas fa-eye';
}
}