From 59716ce3c34970341eb1437b3cd44af90cca0608 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Fri, 7 Mar 2025 14:00:15 +0800 Subject: [PATCH] Fix bulk multi select --- static/css/components/card.css | 1 + static/js/components/LoraCard.js | 21 ++++++++----- static/js/managers/BulkManager.js | 51 +++++++++++++++++++++---------- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/static/css/components/card.css b/static/css/components/card.css index a896b6c7..d0c0212b 100644 --- a/static/css/components/card.css +++ b/static/css/components/card.css @@ -5,6 +5,7 @@ gap: 12px; /* Reduced from var(--space-2) for tighter horizontal spacing */ margin-top: var(--space-2); padding-top: 4px; /* 添加顶部内边距,为悬停动画提供空间 */ + padding-bottom: 4px; /* 添加底部内边距,为悬停动画提供空间 */ max-width: 1400px; /* Container width control */ margin-left: auto; margin-right: auto; diff --git a/static/js/components/LoraCard.js b/static/js/components/LoraCard.js index d839b242..e886641d 100644 --- a/static/js/components/LoraCard.js +++ b/static/js/components/LoraCard.js @@ -1,6 +1,7 @@ import { showToast } from '../utils/uiHelpers.js'; import { state } from '../state/index.js'; import { showLoraModal } from './LoraModal.js'; +import { bulkManager } from '../managers/BulkManager.js'; export function createLoraCard(lora) { const card = document.createElement('div'); @@ -18,6 +19,11 @@ export function createLoraCard(lora) { card.dataset.notes = lora.notes; card.dataset.meta = JSON.stringify(lora.civitai || {}); + // Apply selection state if in bulk mode and this card is in the selected set + if (state.bulkMode && state.selectedLoras.has(lora.file_path)) { + card.classList.add('selected'); + } + const version = state.previewVersions.get(lora.file_path); const previewUrl = lora.preview_url || '/loras_static/images/no-preview.png'; const versionedPreviewUrl = version ? `${previewUrl}?t=${version}` : previewUrl; @@ -64,8 +70,8 @@ export function createLoraCard(lora) { card.addEventListener('click', () => { // Check if we're in bulk mode if (state.bulkMode) { - // Toggle selection - toggleCardSelection(card); + // Toggle selection using the bulk manager + bulkManager.toggleCardSelection(card); } else { // Normal behavior - show modal const loraMeta = { @@ -146,12 +152,6 @@ export function createLoraCard(lora) { return card; } -// Function to toggle selection of a card -function toggleCardSelection(card) { - card.classList.toggle('selected'); - updateSelectedCount(); -} - // Add a method to update card appearance based on bulk mode export function updateCardsForBulkMode(isBulkMode) { // Update the state @@ -165,4 +165,9 @@ export function updateCardsForBulkMode(isBulkMode) { actionGroup.style.display = isBulkMode ? 'none' : 'flex'; }); }); + + // Apply selection state to cards if entering bulk mode + if (isBulkMode) { + bulkManager.applySelectionState(); + } } \ No newline at end of file diff --git a/static/js/managers/BulkManager.js b/static/js/managers/BulkManager.js index 349cc12a..68419554 100644 --- a/static/js/managers/BulkManager.js +++ b/static/js/managers/BulkManager.js @@ -59,42 +59,61 @@ export class BulkManager { } updateSelectedCount() { - const selectedCards = document.querySelectorAll('.lora-card.selected'); const countElement = document.getElementById('selectedCount'); if (countElement) { - countElement.textContent = `${selectedCards.length} selected`; + countElement.textContent = `${state.selectedLoras.size} selected`; } - - // Update state with selected loras - state.selectedLoras.clear(); - selectedCards.forEach(card => { - state.selectedLoras.add(card.dataset.filepath); - }); } toggleCardSelection(card) { - card.classList.toggle('selected'); + const filepath = card.dataset.filepath; + + if (card.classList.contains('selected')) { + card.classList.remove('selected'); + state.selectedLoras.delete(filepath); + } else { + card.classList.add('selected'); + state.selectedLoras.add(filepath); + } + + this.updateSelectedCount(); + } + + // Apply selection state to cards after they are refreshed + applySelectionState() { + if (!state.bulkMode) return; + + document.querySelectorAll('.lora-card').forEach(card => { + const filepath = card.dataset.filepath; + if (state.selectedLoras.has(filepath)) { + card.classList.add('selected'); + } else { + card.classList.remove('selected'); + } + }); + this.updateSelectedCount(); } async copyAllLorasSyntax() { - const selectedCards = document.querySelectorAll('.lora-card.selected'); - if (selectedCards.length === 0) { + if (state.selectedLoras.size === 0) { showToast('No LoRAs selected', 'warning'); return; } const loraSyntaxes = []; - selectedCards.forEach(card => { - const usageTips = JSON.parse(card.dataset.usage_tips || '{}'); - const strength = usageTips.strength || 1; - loraSyntaxes.push(``); + document.querySelectorAll('.lora-card').forEach(card => { + if (state.selectedLoras.has(card.dataset.filepath)) { + const usageTips = JSON.parse(card.dataset.usage_tips || '{}'); + const strength = usageTips.strength || 1; + loraSyntaxes.push(``); + } }); try { await navigator.clipboard.writeText(loraSyntaxes.join(', ')); - showToast(`Copied ${selectedCards.length} LoRA syntaxes to clipboard`, 'success'); + showToast(`Copied ${state.selectedLoras.size} LoRA syntaxes to clipboard`, 'success'); } catch (err) { console.error('Copy failed:', err); showToast('Copy failed', 'error');