mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-06-21 09:52:03 -03:00
Store the originating page type alongside VLM data in sessionStorage; validate it on every page load before applying the filter or showing the indicator. Stale data is auto-cleaned on mismatch. This prevents the 'View all local versions' custom filter from leaking into the checkpoints (or embeddings) page, which caused an empty grid.
158 lines
5.8 KiB
JavaScript
158 lines
5.8 KiB
JavaScript
// LorasControls.js - Specific implementation for the LoRAs page
|
|
import { PageControls } from './PageControls.js';
|
|
import { getModelApiClient, resetAndReload } from '../../api/modelApiFactory.js';
|
|
import { getSessionItem, removeSessionItem } from '../../utils/storageHelpers.js';
|
|
import { createAlphabetBar } from '../alphabet/index.js';
|
|
import { downloadManager } from '../../managers/DownloadManager.js';
|
|
|
|
/**
|
|
* LorasControls class - Extends PageControls for LoRA-specific functionality
|
|
*/
|
|
export class LorasControls extends PageControls {
|
|
constructor() {
|
|
// Initialize with 'loras' page type
|
|
super('loras');
|
|
|
|
// Register API methods specific to the LoRAs page
|
|
this.registerLorasAPI();
|
|
|
|
// Check for custom filters (e.g., from recipe navigation)
|
|
this.checkCustomFilters();
|
|
|
|
// Initialize alphabet bar component
|
|
this.initAlphabetBar();
|
|
}
|
|
|
|
/**
|
|
* Register LoRA-specific API methods
|
|
*/
|
|
registerLorasAPI() {
|
|
const lorasAPI = {
|
|
// Core API functions
|
|
loadMoreModels: async (resetPage = false, updateFolders = false) => {
|
|
return await getModelApiClient().loadMoreWithVirtualScroll(resetPage, updateFolders);
|
|
},
|
|
|
|
resetAndReload: async (updateFolders = false) => {
|
|
return await resetAndReload(updateFolders);
|
|
},
|
|
|
|
refreshModels: async (fullRebuild = false) => {
|
|
return await getModelApiClient().refreshModels(fullRebuild);
|
|
},
|
|
|
|
// LoRA-specific API functions
|
|
fetchFromCivitai: async () => {
|
|
return await getModelApiClient().fetchCivitaiMetadata();
|
|
},
|
|
|
|
showDownloadModal: () => {
|
|
downloadManager.showDownloadModal();
|
|
},
|
|
|
|
toggleBulkMode: () => {
|
|
if (window.bulkManager) {
|
|
window.bulkManager.toggleBulkMode();
|
|
} else {
|
|
console.error('Bulk manager not available');
|
|
}
|
|
},
|
|
|
|
clearCustomFilter: async () => {
|
|
await this.clearCustomFilter();
|
|
}
|
|
};
|
|
|
|
// Register the API
|
|
this.registerAPI(lorasAPI);
|
|
}
|
|
|
|
/**
|
|
* Check for custom filter parameters in session storage (e.g., from recipe page navigation)
|
|
*/
|
|
checkCustomFilters() {
|
|
const filterLoraHash = getSessionItem('recipe_to_lora_filterLoraHash');
|
|
const filterLoraHashes = getSessionItem('recipe_to_lora_filterLoraHashes');
|
|
const filterRecipeName = getSessionItem('filterRecipeName');
|
|
const viewLoraDetail = getSessionItem('viewLoraDetail');
|
|
|
|
if ((filterLoraHash || filterLoraHashes) && filterRecipeName) {
|
|
// Found custom filter parameters, set up the custom filter
|
|
|
|
// Show the filter indicator
|
|
const indicator = document.getElementById('customFilterIndicator');
|
|
const filterText = indicator?.querySelector('.customFilterText');
|
|
|
|
if (indicator && filterText) {
|
|
indicator.classList.remove('hidden');
|
|
|
|
// Set text content with recipe name
|
|
const filterType = filterLoraHash && viewLoraDetail ? "Viewing LoRA from" : "Viewing LoRAs from";
|
|
const displayText = `${filterType}: ${filterRecipeName}`;
|
|
|
|
filterText.textContent = this._truncateText(displayText, 30);
|
|
filterText.setAttribute('title', displayText);
|
|
|
|
// Add pulse animation
|
|
const filterElement = indicator.querySelector('.filter-active');
|
|
if (filterElement) {
|
|
filterElement.classList.add('animate');
|
|
setTimeout(() => filterElement.classList.remove('animate'), 600);
|
|
}
|
|
}
|
|
|
|
// If we're viewing a specific LoRA detail, set up to open the modal
|
|
if (filterLoraHash && viewLoraDetail) {
|
|
this.pageState.pendingLoraHash = filterLoraHash;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear the custom filter and reload the page
|
|
*/
|
|
async clearCustomFilter() {
|
|
// Check for View Local Versions filter first (handles VLM and reloads)
|
|
const vlmModelId = getSessionItem('vlm_model_id');
|
|
if (vlmModelId) {
|
|
removeSessionItem('vlm_model_id');
|
|
removeSessionItem('vlm_model_name');
|
|
removeSessionItem('vlm_base_model');
|
|
removeSessionItem('vlm_page_type');
|
|
window.location.reload();
|
|
return;
|
|
}
|
|
|
|
console.log("Clearing custom filter...");
|
|
// Remove filter parameters from session storage
|
|
removeSessionItem('recipe_to_lora_filterLoraHash');
|
|
removeSessionItem('recipe_to_lora_filterLoraHashes');
|
|
removeSessionItem('filterRecipeName');
|
|
removeSessionItem('viewLoraDetail');
|
|
|
|
// Hide the filter indicator
|
|
const indicator = document.getElementById('customFilterIndicator');
|
|
if (indicator) {
|
|
indicator.classList.add('hidden');
|
|
}
|
|
|
|
// Reset state
|
|
if (this.pageState.pendingLoraHash) {
|
|
delete this.pageState.pendingLoraHash;
|
|
}
|
|
|
|
// Reload the loras
|
|
await resetAndReload();
|
|
}
|
|
|
|
/**
|
|
* Initialize the alphabet bar component
|
|
*/
|
|
initAlphabetBar() {
|
|
// Create the alphabet bar component
|
|
this.alphabetBar = createAlphabetBar('loras');
|
|
|
|
// Expose the alphabet bar to the global scope for debugging
|
|
window.alphabetBar = this.alphabetBar;
|
|
}
|
|
} |