diff --git a/static/js/script.js b/static/js/script.js index 05921f77..599e50de 100644 --- a/static/js/script.js +++ b/static/js/script.js @@ -99,38 +99,152 @@ function lazyLoadImages() { }); } -// 优化模态窗口 +// 优化模态窗口管理 class ModalManager { constructor() { - this.modal = document.getElementById('loraModal'); + this.modals = new Map(); this.boundHandleEscape = this.handleEscape.bind(this); - this.boundHandleOutsideClick = this.handleOutsideClick.bind(this); - } + + // 注册所有模态窗口 + this.registerModal('loraModal', { + element: document.getElementById('loraModal'), + onClose: () => { + this.getModal('loraModal').element.style.display = 'none'; + document.body.classList.remove('modal-open'); + } + }); + + this.registerModal('deleteModal', { + element: document.getElementById('deleteModal'), + onClose: () => { + this.getModal('deleteModal').element.classList.remove('show'); + document.body.classList.remove('modal-open'); + pendingDeletePath = null; + } + }); - show(content) { - this.modal.innerHTML = content; - this.modal.style.display = 'block'; - document.body.classList.add('modal-open'); + // 添加全局事件监听 document.addEventListener('keydown', this.boundHandleEscape); - this.modal.addEventListener('click', this.boundHandleOutsideClick); } - close() { - this.modal.style.display = 'none'; - document.body.classList.remove('modal-open'); - document.removeEventListener('keydown', this.boundHandleEscape); - this.modal.removeEventListener('click', this.boundHandleOutsideClick); + registerModal(id, config) { + this.modals.set(id, { + element: config.element, + onClose: config.onClose, + isOpen: false + }); + + // 为每个模态窗口添加点击外部关闭事件 + config.element.addEventListener('click', (e) => { + if (e.target === config.element) { + this.closeModal(id); + } + }); + } + + getModal(id) { + return this.modals.get(id); + } + + showModal(id, content = null) { + const modal = this.getModal(id); + if (!modal) return; + + if (content) { + modal.element.innerHTML = content; + } + + if (id === 'loraModal') { + modal.element.style.display = 'block'; + } else if (id === 'deleteModal') { + modal.element.classList.add('show'); + } + + modal.isOpen = true; + document.body.classList.add('modal-open'); + } + + closeModal(id) { + const modal = this.getModal(id); + if (!modal) return; + + modal.onClose(); + modal.isOpen = false; } handleEscape(e) { - if (e.key === 'Escape') this.close(); - } - - handleOutsideClick(e) { - if (e.target === this.modal) this.close(); + if (e.key === 'Escape') { + // 关闭最后打开的模态窗口 + for (const [id, modal] of this.modals) { + if (modal.isOpen) { + this.closeModal(id); + break; + } + } + } } } - + +// 创建全局 modalManager 实例 +const modalManager = new ModalManager(); + +// 修改现有的 showModal 函数为 showLoraModal +function showLoraModal(lora) { + const escapedWords = lora.trainedWords?.length ? + lora.trainedWords.join(', ').toUpperCase().replace(/'/g, '\\\'') : ''; + + const content = ` + + `; + + modalManager.showModal('loraModal', content); +} + +// 修改现有的 showDeleteModal 函数 +function showDeleteModal(filePath) { + event.stopPropagation(); + pendingDeletePath = filePath; + + const card = document.querySelector(`.lora-card[data-filepath="${filePath}"]`); + const modelName = card.dataset.name; + const modal = modalManager.getModal('deleteModal').element; + const modelInfo = modal.querySelector('.delete-model-info'); + + modelInfo.innerHTML = ` + Model: ${modelName} +
+ File: ${filePath} + `; + + modalManager.showModal('deleteModal'); +} + +// 修改现有的 closeDeleteModal 函数 +function closeDeleteModal() { + modalManager.closeModal('deleteModal'); +} + // 添加 toast 通知功能 function showToast(message, type = 'info') { const toast = document.createElement('div'); @@ -160,7 +274,6 @@ function showToast(message, type = 'info') { // 初始化 document.addEventListener('DOMContentLoaded', () => { const wsClient = new WebSocketClient(`ws://${window.location.host}/ws`); - const modalManager = new ModalManager(); // 优化搜索功能,添加防抖 const debouncedSearch = debounce((term) => { @@ -273,40 +386,6 @@ function openCivitai(modelName) { let pendingDeletePath = null; -function showDeleteModal(filePath) { - event.stopPropagation(); - pendingDeletePath = filePath; - - const card = document.querySelector(`.lora-card[data-filepath="${filePath}"]`); - const modelName = card.dataset.name; - const modal = document.getElementById('deleteModal'); - const modelInfo = modal.querySelector('.delete-model-info'); - - // Format the info with better structure - modelInfo.innerHTML = ` - Model: ${modelName} -
- File: ${filePath} - `; - - modal.classList.add('show'); // Use class instead of style.display - document.body.classList.add('modal-open'); - - // Add click outside to close - modal.onclick = function(event) { - if (event.target === modal) { - closeDeleteModal(); - } - }; -} - -function closeDeleteModal() { - const modal = document.getElementById('deleteModal'); - modal.classList.remove('show'); // Use class instead of style.display - document.body.classList.remove('modal-open'); - pendingDeletePath = null; -} - async function confirmDelete() { if (!pendingDeletePath) return; @@ -372,7 +451,7 @@ document.querySelectorAll('.lora-card').forEach(card => { card.addEventListener('click', () => { if (card.dataset.meta && Object.keys(JSON.parse(card.dataset.meta)).length > 0) { currentLora = JSON.parse(card.dataset.meta); - showModal(currentLora); + showLoraModal(currentLora); } }); }); @@ -398,46 +477,6 @@ document.querySelectorAll('.lora-card').forEach(card => { }); }); -function showModal(lora) { - const modal = document.getElementById('loraModal'); - const escapedWords = lora.trainedWords?.length ? - lora.trainedWords.join(', ').toUpperCase().replace(/'/g, '\\\'') : ''; - - modal.innerHTML = ` - - `; - - modal.style.display = 'block'; - document.body.classList.add('modal-open'); - - modal.onclick = function (event) { - if (event.target === modal) { - closeModal(); - } - }; -} - function copyTriggerWords(words) { if (!words) return; @@ -584,7 +623,7 @@ function initTheme() { // 键盘导航 document.addEventListener('keydown', (e) => { - if (e.key === 'Escape') closeModal(); + if (e.key === 'Escape') modalManager.closeModal('loraModal'); }); // 图片预加载