refactor: unify API client usage across models and remove deprecated API files

This commit is contained in:
Will Miao
2025-07-25 21:38:54 +08:00
parent c5a3af2399
commit 1a3751acfa
11 changed files with 26 additions and 173 deletions

View File

@@ -26,7 +26,7 @@ export const MODEL_CONFIG = {
[MODEL_TYPES.CHECKPOINT]: { [MODEL_TYPES.CHECKPOINT]: {
displayName: 'Checkpoint', displayName: 'Checkpoint',
singularName: 'checkpoint', singularName: 'checkpoint',
defaultPageSize: 50, defaultPageSize: 100,
supportsLetterFilter: false, supportsLetterFilter: false,
supportsBulkOperations: true, supportsBulkOperations: true,
supportsMove: false, supportsMove: false,

View File

@@ -1,39 +0,0 @@
import { createModelApiClient } from './baseModelApi.js';
import { MODEL_TYPES } from './apiConfig.js';
// Create Checkpoint-specific API client
const checkpointApiClient = createModelApiClient(MODEL_TYPES.CHECKPOINT);
// Export all common operations using the unified client
export const deleteModel = (filePath) => checkpointApiClient.deleteModel(filePath);
export const excludeCheckpoint = (filePath) => checkpointApiClient.excludeModel(filePath);
export const renameCheckpointFile = (filePath, newFileName) => checkpointApiClient.renameModelFile(filePath, newFileName);
export const replacePreview = (filePath) => checkpointApiClient.replaceModelPreview(filePath);
export const saveModelMetadata = (filePath, data) => checkpointApiClient.saveModelMetadata(filePath, data);
export const refreshCheckpoints = (fullRebuild = false) => checkpointApiClient.refreshModels(fullRebuild);
export const refreshSingleCheckpointMetadata = (filePath) => checkpointApiClient.refreshSingleModelMetadata(filePath);
export const fetchCivitai = () => checkpointApiClient.fetchCivitaiMetadata();
// Pagination functions
export const fetchCheckpointsPage = (page = 1, pageSize = 50) => checkpointApiClient.fetchModelsPage(page, pageSize);
// Virtual scrolling operations
export async function loadMoreCheckpoints(resetPage = false, updateFolders = false) {
return checkpointApiClient.loadMoreWithVirtualScroll(resetPage, updateFolders);
}
// Checkpoint-specific functions
export async function getCheckpointInfo(name) {
try {
const response = await fetch(`${checkpointApiClient.apiConfig.endpoints.specific.info}/${encodeURIComponent(name)}`);
if (!response.ok) {
throw new Error(`Failed to fetch checkpoint info: ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error('Error fetching checkpoint info:', error);
throw error;
}
}

View File

@@ -1,84 +0,0 @@
import { createModelApiClient } from './baseModelApi.js';
import { MODEL_TYPES } from './apiConfig.js';
// Create LoRA-specific API client
const loraApiClient = createModelApiClient(MODEL_TYPES.LORA);
// Export all common operations using the unified client
export const deleteModel = (filePath) => loraApiClient.deleteModel(filePath);
export const excludeLora = (filePath) => loraApiClient.excludeModel(filePath);
export const renameLoraFile = (filePath, newFileName) => loraApiClient.renameModelFile(filePath, newFileName);
export const replacePreview = (filePath) => loraApiClient.replaceModelPreview(filePath);
export const saveModelMetadata = (filePath, data) => loraApiClient.saveModelMetadata(filePath, data);
export const refreshLoras = (fullRebuild = false) => loraApiClient.refreshModels(fullRebuild);
export const refreshSingleLoraMetadata = (filePath) => loraApiClient.refreshSingleModelMetadata(filePath);
export const fetchCivitai = () => loraApiClient.fetchCivitaiMetadata();
// Pagination functions
export const fetchLorasPage = (page = 1, pageSize = 100) => loraApiClient.fetchModelsPage(page, pageSize);
// Virtual scrolling operations
export async function loadMoreLoras(resetPage = false, updateFolders = false) {
return loraApiClient.loadMoreWithVirtualScroll(resetPage, updateFolders);
}
// LoRA-specific functions that don't have common equivalents
export async function fetchModelDescription(modelId, filePath) {
try {
const response = await fetch(`${loraApiClient.apiConfig.endpoints.specific.modelDescription}?model_id=${modelId}&file_path=${encodeURIComponent(filePath)}`);
if (!response.ok) {
throw new Error(`Failed to fetch model description: ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error('Error fetching model description:', error);
throw error;
}
}
// Move operations (LoRA-specific)
export async function moveModel(filePath, targetPath) {
try {
const response = await fetch(loraApiClient.apiConfig.endpoints.specific.moveModel, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
file_path: filePath,
target_path: targetPath
})
});
if (!response.ok) {
throw new Error('Failed to move model');
}
return await response.json();
} catch (error) {
console.error('Error moving model:', error);
throw error;
}
}
export async function moveModelsBulk(filePaths, targetPath) {
try {
const response = await fetch(loraApiClient.apiConfig.endpoints.specific.moveBulk, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
file_paths: filePaths,
target_path: targetPath
})
});
if (!response.ok) {
throw new Error('Failed to move models');
}
return await response.json();
} catch (error) {
console.error('Error moving models in bulk:', error);
throw error;
}
}

View File

@@ -1,7 +1,6 @@
import { appCore } from './core.js'; import { appCore } from './core.js';
import { confirmDelete, closeDeleteModal, confirmExclude, closeExcludeModal } from './utils/modalUtils.js'; import { confirmDelete, closeDeleteModal, confirmExclude, closeExcludeModal } from './utils/modalUtils.js';
import { createPageControls } from './components/controls/index.js'; import { createPageControls } from './components/controls/index.js';
import { loadMoreCheckpoints } from './api/checkpointApi.js';
import { CheckpointContextMenu } from './components/ContextMenu/index.js'; import { CheckpointContextMenu } from './components/ContextMenu/index.js';
import { ModelDuplicatesManager } from './components/ModelDuplicatesManager.js'; import { ModelDuplicatesManager } from './components/ModelDuplicatesManager.js';
import { MODEL_TYPES } from './api/apiConfig.js'; import { MODEL_TYPES } from './api/apiConfig.js';
@@ -26,11 +25,6 @@ class CheckpointsPageManager {
window.confirmExclude = confirmExclude; window.confirmExclude = confirmExclude;
window.closeExcludeModal = closeExcludeModal; window.closeExcludeModal = closeExcludeModal;
// Add loadCheckpoints function to window for FilterManager compatibility
window.checkpointManager = {
loadCheckpoints: (reset) => loadMoreCheckpoints(reset)
};
// Expose duplicates manager // Expose duplicates manager
window.modelDuplicatesManager = this.duplicatesManager; window.modelDuplicatesManager = this.duplicatesManager;
} }

View File

@@ -1,7 +1,6 @@
import { BaseContextMenu } from './BaseContextMenu.js'; import { BaseContextMenu } from './BaseContextMenu.js';
import { ModelContextMenuMixin } from './ModelContextMenuMixin.js'; import { ModelContextMenuMixin } from './ModelContextMenuMixin.js';
import { refreshSingleLoraMetadata, saveModelMetadata, replacePreview } from '../../api/loraApi.js'; import { getModelApiClient, resetAndReload } from '../../api/baseModelApi.js';
import { resetAndReload } from '../../api/baseModelApi.js';
import { copyToClipboard, sendLoraToWorkflow } from '../../utils/uiHelpers.js'; import { copyToClipboard, sendLoraToWorkflow } from '../../utils/uiHelpers.js';
import { showExcludeModal, showDeleteModal } from '../../utils/modalUtils.js'; import { showExcludeModal, showDeleteModal } from '../../utils/modalUtils.js';
@@ -20,7 +19,7 @@ export class LoraContextMenu extends BaseContextMenu {
// Use the saveModelMetadata implementation from loraApi // Use the saveModelMetadata implementation from loraApi
async saveModelMetadata(filePath, data) { async saveModelMetadata(filePath, data) {
return saveModelMetadata(filePath, data); return getModelApiClient().saveModelMetadata(filePath, data);
} }
handleMenuAction(action, menuItem) { handleMenuAction(action, menuItem) {
@@ -49,7 +48,7 @@ export class LoraContextMenu extends BaseContextMenu {
break; break;
case 'replace-preview': case 'replace-preview':
// Add a new action for replacing preview images // Add a new action for replacing preview images
replacePreview(this.currentCard.dataset.filepath); getModelApiClient().replaceModelPreview(this.currentCard.dataset.filepath);
break; break;
case 'delete': case 'delete':
// Call showDeleteModal directly instead of clicking the trash button // Call showDeleteModal directly instead of clicking the trash button
@@ -59,7 +58,7 @@ export class LoraContextMenu extends BaseContextMenu {
moveManager.showMoveModal(this.currentCard.dataset.filepath); moveManager.showMoveModal(this.currentCard.dataset.filepath);
break; break;
case 'refresh-metadata': case 'refresh-metadata':
refreshSingleLoraMetadata(this.currentCard.dataset.filepath); getModelApiClient().refreshSingleModelMetadata(this.currentCard.dataset.filepath);
break; break;
case 'exclude': case 'exclude':
showExcludeModal(this.currentCard.dataset.filepath); showExcludeModal(this.currentCard.dataset.filepath);

View File

@@ -1,7 +1,6 @@
// CheckpointsControls.js - Specific implementation for the Checkpoints page // CheckpointsControls.js - Specific implementation for the Checkpoints page
import { PageControls } from './PageControls.js'; import { PageControls } from './PageControls.js';
import { loadMoreCheckpoints, refreshCheckpoints, fetchCivitai } from '../../api/checkpointApi.js'; import { getModelApiClient, resetAndReload } from '../../api/baseModelApi.js';
import { resetAndReload } from '../../api/baseModelApi.js';
import { showToast } from '../../utils/uiHelpers.js'; import { showToast } from '../../utils/uiHelpers.js';
import { downloadManager } from '../../managers/DownloadManager.js'; import { downloadManager } from '../../managers/DownloadManager.js';
@@ -24,7 +23,7 @@ export class CheckpointsControls extends PageControls {
const checkpointsAPI = { const checkpointsAPI = {
// Core API functions // Core API functions
loadMoreModels: async (resetPage = false, updateFolders = false) => { loadMoreModels: async (resetPage = false, updateFolders = false) => {
return await loadMoreCheckpoints(resetPage, updateFolders); return await getModelApiClient().loadMoreWithVirtualScroll(resetPage, updateFolders);
}, },
resetAndReload: async (updateFolders = false) => { resetAndReload: async (updateFolders = false) => {
@@ -32,12 +31,12 @@ export class CheckpointsControls extends PageControls {
}, },
refreshModels: async (fullRebuild = false) => { refreshModels: async (fullRebuild = false) => {
return await refreshCheckpoints(fullRebuild); return await getModelApiClient().refreshModels(fullRebuild);
}, },
// Add fetch from Civitai functionality for checkpoints // Add fetch from Civitai functionality for checkpoints
fetchFromCivitai: async () => { fetchFromCivitai: async () => {
return await fetchCivitai(); return await getModelApiClient().fetchCivitaiMetadata();
}, },
// Add show download modal functionality // Add show download modal functionality

View File

@@ -1,7 +1,6 @@
// LorasControls.js - Specific implementation for the LoRAs page // LorasControls.js - Specific implementation for the LoRAs page
import { PageControls } from './PageControls.js'; import { PageControls } from './PageControls.js';
import { loadMoreLoras, fetchCivitai, refreshLoras } from '../../api/loraApi.js'; import { getModelApiClient, resetAndReload } from '../../api/baseModelApi.js';
import { resetAndReload } from '../../api/baseModelApi.js';
import { getSessionItem, removeSessionItem } from '../../utils/storageHelpers.js'; import { getSessionItem, removeSessionItem } from '../../utils/storageHelpers.js';
import { createAlphabetBar } from '../alphabet/index.js'; import { createAlphabetBar } from '../alphabet/index.js';
import { downloadManager } from '../../managers/DownloadManager.js'; import { downloadManager } from '../../managers/DownloadManager.js';
@@ -31,7 +30,7 @@ export class LorasControls extends PageControls {
const lorasAPI = { const lorasAPI = {
// Core API functions // Core API functions
loadMoreModels: async (resetPage = false, updateFolders = false) => { loadMoreModels: async (resetPage = false, updateFolders = false) => {
return await loadMoreLoras(resetPage, updateFolders); return await getModelApiClient().loadMoreWithVirtualScroll(resetPage, updateFolders);
}, },
resetAndReload: async (updateFolders = false) => { resetAndReload: async (updateFolders = false) => {
@@ -39,12 +38,12 @@ export class LorasControls extends PageControls {
}, },
refreshModels: async (fullRebuild = false) => { refreshModels: async (fullRebuild = false) => {
return await refreshLoras(fullRebuild); return await getModelApiClient().refreshModels(fullRebuild);
}, },
// LoRA-specific API functions // LoRA-specific API functions
fetchFromCivitai: async () => { fetchFromCivitai: async () => {
return await fetchCivitai(); return await getModelApiClient().fetchCivitaiMetadata();
}, },
showDownloadModal: () => { showDownloadModal: () => {

View File

@@ -1,6 +1,5 @@
import { appCore } from './core.js'; import { appCore } from './core.js';
import { state } from './state/index.js'; import { state } from './state/index.js';
import { loadMoreLoras } from './api/loraApi.js';
import { updateCardsForBulkMode } from './components/LoraCard.js'; import { updateCardsForBulkMode } from './components/LoraCard.js';
import { bulkManager } from './managers/BulkManager.js'; import { bulkManager } from './managers/BulkManager.js';
import { moveManager } from './managers/MoveManager.js'; import { moveManager } from './managers/MoveManager.js';
@@ -30,7 +29,6 @@ class LoraPageManager {
_exposeRequiredGlobalFunctions() { _exposeRequiredGlobalFunctions() {
// Only expose what's still needed globally // Only expose what's still needed globally
// Most functionality is now handled by the PageControls component // Most functionality is now handled by the PageControls component
window.loadMoreLoras = loadMoreLoras;
window.confirmDelete = confirmDelete; window.confirmDelete = confirmDelete;
window.closeDeleteModal = closeDeleteModal; window.closeDeleteModal = closeDeleteModal;
window.confirmExclude = confirmExclude; window.confirmExclude = confirmExclude;

View File

@@ -1,8 +1,7 @@
import { BASE_MODEL_CLASSES } from '../utils/constants.js'; import { BASE_MODEL_CLASSES } from '../utils/constants.js';
import { getCurrentPageState } from '../state/index.js'; import { getCurrentPageState } from '../state/index.js';
import { showToast, updatePanelPositions } from '../utils/uiHelpers.js'; import { showToast, updatePanelPositions } from '../utils/uiHelpers.js';
import { loadMoreLoras } from '../api/loraApi.js'; import { getModelApiClient } from '../api/baseModelApi.js';
import { loadMoreCheckpoints } from '../api/checkpointApi.js';
import { removeStorageItem, setStorageItem, getStorageItem } from '../utils/storageHelpers.js'; import { removeStorageItem, setStorageItem, getStorageItem } from '../utils/storageHelpers.js';
export class FilterManager { export class FilterManager {
@@ -281,11 +280,9 @@ export class FilterManager {
// Call the appropriate manager's load method based on page type // Call the appropriate manager's load method based on page type
if (this.currentPage === 'recipes' && window.recipeManager) { if (this.currentPage === 'recipes' && window.recipeManager) {
await window.recipeManager.loadRecipes(true); await window.recipeManager.loadRecipes(true);
} else if (this.currentPage === 'loras') { } else if (this.currentPage === 'loras' || this.currentPage === 'embeddings' || this.currentPage === 'checkpoints') {
// For loras page, reset the page and reload // For models page, reset the page and reload
await loadMoreLoras(true, true); await getModelApiClient().loadMoreWithVirtualScroll(true, false);
} else if (this.currentPage === 'checkpoints' && window.checkpointManager) {
await loadMoreCheckpoints(true);
} }
// Update filter button to show active state // Update filter button to show active state
@@ -339,10 +336,8 @@ export class FilterManager {
// Reload data using the appropriate method for the current page // Reload data using the appropriate method for the current page
if (this.currentPage === 'recipes' && window.recipeManager) { if (this.currentPage === 'recipes' && window.recipeManager) {
await window.recipeManager.loadRecipes(true); await window.recipeManager.loadRecipes(true);
} else if (this.currentPage === 'loras') { } else if (this.currentPage === 'loras' || this.currentPage === 'checkpoints' || this.currentPage === 'embeddings') {
await loadMoreLoras(true, true); await getModelApiClient().loadMoreWithVirtualScroll(true, true);
} else if (this.currentPage === 'checkpoints') {
await loadMoreCheckpoints(true);
} }
showToast(`Filters cleared`, 'info'); showToast(`Filters cleared`, 'info');

View File

@@ -1,5 +1,6 @@
import { updatePanelPositions } from "../utils/uiHelpers.js"; import { updatePanelPositions } from "../utils/uiHelpers.js";
import { getCurrentPageState } from "../state/index.js"; import { getCurrentPageState } from "../state/index.js";
import { getModelApiClient } from "../api/baseModelApi.js";
import { setStorageItem, getStorageItem } from "../utils/storageHelpers.js"; import { setStorageItem, getStorageItem } from "../utils/storageHelpers.js";
/** /**
* SearchManager - Handles search functionality across different pages * SearchManager - Handles search functionality across different pages
@@ -332,15 +333,9 @@ export class SearchManager {
// Call the appropriate manager's load method based on page type // Call the appropriate manager's load method based on page type
if (this.currentPage === 'recipes' && window.recipeManager) { if (this.currentPage === 'recipes' && window.recipeManager) {
window.recipeManager.loadRecipes(true); // true to reset pagination window.recipeManager.loadRecipes(true); // true to reset pagination
} else if (this.currentPage === 'loras' && window.loadMoreLoras) { } else if (this.currentPage === 'loras' || this.currentPage === 'embeddings' || this.currentPage === 'checkpoints') {
// Reset loras page and reload // For models page, reset the page and reload
if (pageState) { getModelApiClient().loadMoreWithVirtualScroll(true, false);
pageState.currentPage = 1;
pageState.hasMore = true;
}
window.loadMoreLoras(true); // true to reset pagination
} else if (this.currentPage === 'checkpoints' && window.checkpointManager) {
window.checkpointManager.loadCheckpoints(true); // true to reset pagination
} }
} }
} }

View File

@@ -2,8 +2,7 @@ import { state, getCurrentPageState } from '../state/index.js';
import { VirtualScroller } from './VirtualScroller.js'; import { VirtualScroller } from './VirtualScroller.js';
import { createLoraCard, setupLoraCardEventDelegation } from '../components/LoraCard.js'; import { createLoraCard, setupLoraCardEventDelegation } from '../components/LoraCard.js';
import { createCheckpointCard, setupCheckpointCardEventDelegation } from '../components/CheckpointCard.js'; import { createCheckpointCard, setupCheckpointCardEventDelegation } from '../components/CheckpointCard.js';
import { fetchLorasPage } from '../api/loraApi.js'; import { getModelApiClient } from '../api/baseModelApi.js';
import { fetchCheckpointsPage } from '../api/checkpointApi.js';
import { showToast } from './uiHelpers.js'; import { showToast } from './uiHelpers.js';
// Function to dynamically import the appropriate card creator based on page type // Function to dynamically import the appropriate card creator based on page type
@@ -31,14 +30,12 @@ async function getCardCreator(pageType) {
// Function to get the appropriate data fetcher based on page type // Function to get the appropriate data fetcher based on page type
async function getDataFetcher(pageType) { async function getDataFetcher(pageType) {
if (pageType === 'loras') { if (pageType === 'loras' || pageType === 'embeddings' || pageType === 'checkpoints') {
return fetchLorasPage; return (page = 1, pageSize = 100) => getModelApiClient().fetchModelsPage(page, pageSize);
} else if (pageType === 'recipes') { } else if (pageType === 'recipes') {
// Import the recipeApi module and use the fetchRecipesPage function // Import the recipeApi module and use the fetchRecipesPage function
const { fetchRecipesPage } = await import('../api/recipeApi.js'); const { fetchRecipesPage } = await import('../api/recipeApi.js');
return fetchRecipesPage; return fetchRecipesPage;
} else if (pageType === 'checkpoints') {
return fetchCheckpointsPage;
} }
return null; return null;
} }