Enhance duplicates mode functionality: add toggle for entering/exiting mode, improve exit button styling, and manage control button states during duplicates mode.

This commit is contained in:
Will Miao
2025-06-04 16:46:57 +08:00
parent add9269706
commit 641fa8a3d9
6 changed files with 124 additions and 20 deletions

View File

@@ -16,6 +16,9 @@ export class ModelDuplicatesManager {
this.renderTooltip = this.renderTooltip.bind(this);
this.checkDuplicatesCount = this.checkDuplicatesCount.bind(this);
// Keep track of which controls need to be re-enabled
this.disabledControls = [];
// Check for duplicates on load
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', this.checkDuplicatesCount);
@@ -62,6 +65,15 @@ export class ModelDuplicatesManager {
}
}
// Toggle method to enter/exit duplicates mode
toggleDuplicateMode() {
if (this.inDuplicateMode) {
this.exitDuplicateMode();
} else {
this.findDuplicates();
}
}
async findDuplicates() {
try {
// Determine API endpoint based on model type
@@ -126,6 +138,18 @@ export class ModelDuplicatesManager {
// Update selected count
this.updateSelectedCount();
// Update Duplicates button to show active state
const duplicatesBtn = document.getElementById('findDuplicatesBtn');
if (duplicatesBtn) {
duplicatesBtn.classList.add('active');
duplicatesBtn.title = 'Exit Duplicates Mode';
// Change icon and text to indicate it's now an exit button
duplicatesBtn.innerHTML = '<i class="fas fa-times"></i> Exit Duplicates';
}
// Disable all control buttons except the duplicates button
this.disableControlButtons();
}
exitDuplicateMode() {
@@ -153,6 +177,53 @@ export class ModelDuplicatesManager {
// Re-enable virtual scrolling
state.virtualScroller.enable();
// Restore Duplicates button to its original state
const duplicatesBtn = document.getElementById('findDuplicatesBtn');
if (duplicatesBtn) {
duplicatesBtn.classList.remove('active');
duplicatesBtn.title = 'Find duplicate models';
duplicatesBtn.innerHTML = '<i class="fas fa-clone"></i> Duplicates <span id="duplicatesBadge" class="badge"></span>';
// Restore badge
const newBadge = duplicatesBtn.querySelector('#duplicatesBadge');
const oldBadge = document.getElementById('duplicatesBadge');
if (oldBadge && oldBadge.textContent) {
newBadge.textContent = oldBadge.textContent;
newBadge.classList.add('pulse');
}
}
// Re-enable all control buttons
this.enableControlButtons();
this.checkDuplicatesCount();
}
// Disable all control buttons except the duplicates button
disableControlButtons() {
this.disabledControls = [];
// Select all control buttons except the duplicates button
const controlButtons = document.querySelectorAll('.control-group button:not(#findDuplicatesBtn), .dropdown-group, .toggle-folders-btn, #favoriteFilterBtn');
controlButtons.forEach(button => {
// Only disable enabled buttons (don't disable already disabled buttons)
if (!button.disabled && !button.classList.contains('disabled')) {
this.disabledControls.push(button);
button.disabled = true;
button.classList.add('disabled-during-duplicates');
}
});
}
// Re-enable all previously disabled control buttons
enableControlButtons() {
this.disabledControls.forEach(button => {
button.disabled = false;
button.classList.remove('disabled-during-duplicates');
});
this.disabledControls = [];
}
renderDuplicateGroups() {

View File

@@ -516,7 +516,8 @@ export class PageControls {
*/
findDuplicates() {
if (window.modelDuplicatesManager) {
window.modelDuplicatesManager.findDuplicates();
// Change to toggle functionality
window.modelDuplicatesManager.toggleDuplicateMode();
} else {
console.error('Model duplicates manager not available');
}

View File

@@ -2,7 +2,6 @@
import { PageControls } from './PageControls.js';
import { LorasControls } from './LorasControls.js';
import { CheckpointsControls } from './CheckpointsControls.js';
import { refreshVirtualScroll } from '../../utils/infiniteScroll.js';
// Export the classes
export { PageControls, LorasControls, CheckpointsControls };
@@ -21,17 +20,4 @@ export function createPageControls(pageType) {
console.error(`Unknown page type: ${pageType}`);
return null;
}
}
// Example for a filter method:
function applyFilter(filterType, value) {
// ...existing filter logic...
// After filters are applied, refresh the virtual scroll if it exists
if (state.virtualScroller) {
refreshVirtualScroll();
} else {
// Fall back to existing reset and reload logic
resetAndReload(true);
}
}