diff --git a/static/js/api/baseModelApi.js b/static/js/api/baseModelApi.js index 230d642b..c2e6a7da 100644 --- a/static/js/api/baseModelApi.js +++ b/static/js/api/baseModelApi.js @@ -1,164 +1,7 @@ -// filepath: d:\Workspace\ComfyUI\custom_nodes\ComfyUI-Lora-Manager\static\js\api\baseModelApi.js import { state, getCurrentPageState } from '../state/index.js'; import { showToast } from '../utils/uiHelpers.js'; import { getSessionItem, saveMapToStorage } from '../utils/storageHelpers.js'; -/** - * Shared functionality for handling models (loras and checkpoints) - */ - -// Generic function to load more models with pagination -export async function loadMoreModels(options = {}) { - const { - resetPage = false, - updateFolders = false, - modelType = 'lora', // 'lora' or 'checkpoint' - createCardFunction, - endpoint = '/api/loras' - } = options; - - const pageState = getCurrentPageState(); - - if (pageState.isLoading || (!pageState.hasMore && !resetPage)) return; - - pageState.isLoading = true; - document.body.classList.add('loading'); - - try { - // Reset to first page if requested - if (resetPage) { - pageState.currentPage = 1; - // Clear grid if resetting - const gridId = modelType === 'checkpoint' ? 'checkpointGrid' : 'loraGrid'; - const grid = document.getElementById(gridId); - if (grid) grid.innerHTML = ''; - } - - const params = new URLSearchParams({ - page: pageState.currentPage, - page_size: pageState.pageSize || 20, - sort_by: pageState.sortBy - }); - - if (pageState.activeFolder !== null) { - params.append('folder', pageState.activeFolder); - } - - // Add favorites filter parameter if enabled - if (pageState.showFavoritesOnly) { - params.append('favorites_only', 'true'); - } - - // Add active letter filter if set - if (pageState.activeLetterFilter) { - params.append('first_letter', pageState.activeLetterFilter); - } - - // Add search parameters if there's a search term - if (pageState.filters?.search) { - params.append('search', pageState.filters.search); - params.append('fuzzy', 'true'); - - // Add search option parameters if available - if (pageState.searchOptions) { - params.append('search_filename', pageState.searchOptions.filename.toString()); - params.append('search_modelname', pageState.searchOptions.modelname.toString()); - if (pageState.searchOptions.tags !== undefined) { - params.append('search_tags', pageState.searchOptions.tags.toString()); - } - params.append('recursive', (pageState.searchOptions?.recursive ?? false).toString()); - } - } - - // Add filter parameters if active - if (pageState.filters) { - // Handle tags filters - if (pageState.filters.tags && pageState.filters.tags.length > 0) { - // Checkpoints API expects individual 'tag' parameters, Loras API expects comma-separated 'tags' - if (modelType === 'checkpoint') { - pageState.filters.tags.forEach(tag => { - params.append('tag', tag); - }); - } else { - params.append('tags', pageState.filters.tags.join(',')); - } - } - - // Handle base model filters - if (pageState.filters.baseModel && pageState.filters.baseModel.length > 0) { - if (modelType === 'checkpoint') { - pageState.filters.baseModel.forEach(model => { - params.append('base_model', model); - }); - } else { - params.append('base_models', pageState.filters.baseModel.join(',')); - } - } - } - - // Add model-specific parameters - if (modelType === 'lora') { - // Check for recipe-based filtering parameters from session storage - const filterLoraHash = getSessionItem('recipe_to_lora_filterLoraHash'); - const filterLoraHashes = getSessionItem('recipe_to_lora_filterLoraHashes'); - - // Add hash filter parameter if present - if (filterLoraHash) { - params.append('lora_hash', filterLoraHash); - } - // Add multiple hashes filter if present - else if (filterLoraHashes) { - try { - if (Array.isArray(filterLoraHashes) && filterLoraHashes.length > 0) { - params.append('lora_hashes', filterLoraHashes.join(',')); - } - } catch (error) { - console.error('Error parsing lora hashes from session storage:', error); - } - } - } - - const response = await fetch(`${endpoint}?${params}`); - if (!response.ok) { - throw new Error(`Failed to fetch models: ${response.statusText}`); - } - - const data = await response.json(); - - const gridId = modelType === 'checkpoint' ? 'checkpointGrid' : 'loraGrid'; - const grid = document.getElementById(gridId); - - if (data.items.length === 0 && pageState.currentPage === 1) { - grid.innerHTML = `
No ${modelType}s found in this folder
`; - pageState.hasMore = false; - } else if (data.items.length > 0) { - pageState.hasMore = pageState.currentPage < data.total_pages; - - // Append model cards using the provided card creation function - data.items.forEach(model => { - const card = createCardFunction(model); - grid.appendChild(card); - }); - - // Increment the page number AFTER successful loading - pageState.currentPage++; - } else { - pageState.hasMore = false; - } - - if (updateFolders && data.folders) { - updateFolderTags(data.folders); - } - - } catch (error) { - console.error(`Error loading ${modelType}s:`, error); - showToast(`Failed to load ${modelType}s: ${error.message}`, 'error'); - } finally { - pageState.isLoading = false; - document.body.classList.remove('loading'); - } -} - // New method for virtual scrolling fetch export async function fetchModelsPage(options = {}) { const { @@ -294,7 +137,6 @@ export async function resetAndReloadWithVirtualScroll(options = {}) { try { pageState.isLoading = true; - document.body.classList.add('loading'); // Reset page counter pageState.currentPage = 1; @@ -325,7 +167,6 @@ export async function resetAndReloadWithVirtualScroll(options = {}) { throw error; } finally { pageState.isLoading = false; - document.body.classList.remove('loading'); } } @@ -347,7 +188,6 @@ export async function loadMoreWithVirtualScroll(options = {}) { try { // Start loading state pageState.isLoading = true; - document.body.classList.add('loading'); // Reset to first page if requested if (resetPage) { @@ -380,7 +220,6 @@ export async function loadMoreWithVirtualScroll(options = {}) { throw error; } finally { pageState.isLoading = false; - document.body.classList.remove('loading'); } } @@ -482,22 +321,6 @@ export async function deleteModel(filePath, modelType = 'lora') { } } -// Reset and reload models -export async function resetAndReload(options = {}) { - const { - updateFolders = false, - modelType = 'lora', - loadMoreFunction - } = options; - - const pageState = getCurrentPageState(); - - // Reset pagination and load more models - if (typeof loadMoreFunction === 'function') { - await loadMoreFunction(true, updateFolders); - } -} - // Generic function to refresh models export async function refreshModels(options = {}) { const { diff --git a/static/js/api/checkpointApi.js b/static/js/api/checkpointApi.js index fdbc6c6f..7b9028e9 100644 --- a/static/js/api/checkpointApi.js +++ b/static/js/api/checkpointApi.js @@ -1,8 +1,5 @@ -import { createCheckpointCard } from '../components/CheckpointCard.js'; import { - loadMoreModels, fetchModelsPage, - resetAndReload as baseResetAndReload, resetAndReloadWithVirtualScroll, loadMoreWithVirtualScroll, refreshModels as baseRefreshModels, @@ -36,43 +33,21 @@ export async function fetchCheckpointsPage(page = 1, pageSize = 100) { * @returns {Promise} */ export async function loadMoreCheckpoints(resetPage = false, updateFolders = false) { - // Check if virtual scroller is available - if (state.virtualScroller) { - return loadMoreWithVirtualScroll({ - modelType: 'checkpoint', - resetPage, - updateFolders, - fetchPageFunction: fetchCheckpointsPage - }); - } else { - // Fall back to the original implementation if virtual scroller isn't available - return loadMoreModels({ - resetPage, - updateFolders, - modelType: 'checkpoint', - createCardFunction: createCheckpointCard, - endpoint: '/api/checkpoints' - }); - } + return loadMoreWithVirtualScroll({ + modelType: 'checkpoint', + resetPage, + updateFolders, + fetchPageFunction: fetchCheckpointsPage + }); } // Reset and reload checkpoints export async function resetAndReload(updateFolders = false) { - // Check if virtual scroller is available - if (state.virtualScroller) { - return resetAndReloadWithVirtualScroll({ - modelType: 'checkpoint', - updateFolders, - fetchPageFunction: fetchCheckpointsPage - }); - } else { - // Fall back to original implementation - return baseResetAndReload({ - updateFolders, - modelType: 'checkpoint', - loadMoreFunction: loadMoreCheckpoints - }); - } + return resetAndReloadWithVirtualScroll({ + modelType: 'checkpoint', + updateFolders, + fetchPageFunction: fetchCheckpointsPage + }); } // Refresh checkpoints diff --git a/static/js/api/loraApi.js b/static/js/api/loraApi.js index e70aba45..c7421a42 100644 --- a/static/js/api/loraApi.js +++ b/static/js/api/loraApi.js @@ -1,8 +1,5 @@ -import { createLoraCard } from '../components/LoraCard.js'; import { - loadMoreModels, fetchModelsPage, - resetAndReload as baseResetAndReload, resetAndReloadWithVirtualScroll, loadMoreWithVirtualScroll, refreshModels as baseRefreshModels, @@ -12,7 +9,7 @@ import { refreshSingleModelMetadata, excludeModel as baseExcludeModel } from './baseModelApi.js'; -import { state, getCurrentPageState } from '../state/index.js'; +import { state } from '../state/index.js'; /** * Save model metadata to the server @@ -63,26 +60,12 @@ export async function excludeLora(filePath) { * @returns {Promise} */ export async function loadMoreLoras(resetPage = false, updateFolders = false) { - const pageState = getCurrentPageState(); - - // Check if virtual scroller is available - if (state.virtualScroller) { - return loadMoreWithVirtualScroll({ - modelType: 'lora', - resetPage, - updateFolders, - fetchPageFunction: fetchLorasPage - }); - } else { - // Fall back to the original implementation if virtual scroller isn't available - return loadMoreModels({ - resetPage, - updateFolders, - modelType: 'lora', - createCardFunction: createLoraCard, - endpoint: '/api/loras' - }); - } + return loadMoreWithVirtualScroll({ + modelType: 'lora', + resetPage, + updateFolders, + fetchPageFunction: fetchLorasPage + }); } /** @@ -116,37 +99,12 @@ export async function replacePreview(filePath) { return replaceModelPreview(filePath, 'lora'); } -export function appendLoraCards(loras) { - // This function is no longer needed with virtual scrolling - // but kept for compatibility - if (state.virtualScroller) { - console.warn('appendLoraCards is deprecated when using virtual scrolling'); - } else { - const grid = document.getElementById('loraGrid'); - - loras.forEach(lora => { - const card = createLoraCard(lora); - grid.appendChild(card); - }); - } -} - export async function resetAndReload(updateFolders = false) { - // Check if virtual scroller is available - if (state.virtualScroller) { - return resetAndReloadWithVirtualScroll({ - modelType: 'lora', - updateFolders, - fetchPageFunction: fetchLorasPage - }); - } else { - // Fall back to original implementation - return baseResetAndReload({ - updateFolders, - modelType: 'lora', - loadMoreFunction: loadMoreLoras - }); - } + return resetAndReloadWithVirtualScroll({ + modelType: 'lora', + updateFolders, + fetchPageFunction: fetchLorasPage + }); } export async function refreshLoras(fullRebuild = false) { diff --git a/static/js/api/recipeApi.js b/static/js/api/recipeApi.js index a21314a9..bfcba3f7 100644 --- a/static/js/api/recipeApi.js +++ b/static/js/api/recipeApi.js @@ -1,6 +1,5 @@ import { RecipeCard } from '../components/RecipeCard.js'; import { - fetchModelsPage, resetAndReloadWithVirtualScroll, loadMoreWithVirtualScroll } from './baseModelApi.js';