mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
refactor: Simplify API calls and enhance model moving functionality
This commit is contained in:
@@ -2,6 +2,7 @@ import { showToast, updateFolderTags } from '../utils/uiHelpers.js';
|
||||
import { state, getCurrentPageState } from '../state/index.js';
|
||||
import { modalManager } from './ModalManager.js';
|
||||
import { getStorageItem } from '../utils/storageHelpers.js';
|
||||
import { getModelApiClient } from '../api/baseModelApi.js';
|
||||
|
||||
class MoveManager {
|
||||
constructor() {
|
||||
@@ -145,45 +146,46 @@ class MoveManager {
|
||||
targetPath = `${targetPath}/${newFolder}`;
|
||||
}
|
||||
|
||||
const apiClient = getModelApiClient();
|
||||
|
||||
try {
|
||||
if (this.bulkFilePaths) {
|
||||
// Bulk move mode
|
||||
await this.moveBulkModels(this.bulkFilePaths, targetPath);
|
||||
const movedFilePaths = await apiClient.moveBulkModels(this.bulkFilePaths, targetPath);
|
||||
|
||||
// Update virtual scroller if in active folder view
|
||||
const pageState = getCurrentPageState();
|
||||
if (pageState.activeFolder !== null && state.virtualScroller) {
|
||||
// Remove moved items from virtual scroller instead of reloading
|
||||
this.bulkFilePaths.forEach(filePath => {
|
||||
state.virtualScroller.removeItemByFilePath(filePath);
|
||||
// Remove only successfully moved items
|
||||
movedFilePaths.forEach(newFilePath => {
|
||||
// Find original filePath by matching filename
|
||||
const filename = newFilePath.substring(newFilePath.lastIndexOf('/') + 1);
|
||||
const originalFilePath = this.bulkFilePaths.find(fp => fp.endsWith('/' + filename));
|
||||
if (originalFilePath) {
|
||||
state.virtualScroller.removeItemByFilePath(originalFilePath);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Update the model cards' filepath in the DOM
|
||||
this.bulkFilePaths.forEach(filePath => {
|
||||
// Extract filename from original path
|
||||
const filename = filePath.substring(filePath.lastIndexOf('/') + 1);
|
||||
// Construct new filepath
|
||||
const newFilePath = `${targetPath}/${filename}`;
|
||||
|
||||
state.virtualScroller.updateSingleItem(filePath, {file_path: newFilePath});
|
||||
movedFilePaths.forEach(newFilePath => {
|
||||
const filename = newFilePath.substring(newFilePath.lastIndexOf('/') + 1);
|
||||
const originalFilePath = this.bulkFilePaths.find(fp => fp.endsWith('/' + filename));
|
||||
if (originalFilePath) {
|
||||
state.virtualScroller.updateSingleItem(originalFilePath, {file_path: newFilePath});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Single move mode
|
||||
await this.moveSingleModel(this.currentFilePath, targetPath);
|
||||
|
||||
// Update virtual scroller if in active folder view
|
||||
const pageState = getCurrentPageState();
|
||||
if (pageState.activeFolder !== null && state.virtualScroller) {
|
||||
// Remove moved item from virtual scroller instead of reloading
|
||||
state.virtualScroller.removeItemByFilePath(this.currentFilePath);
|
||||
} else {
|
||||
// Extract filename from original path
|
||||
const filename = this.currentFilePath.substring(this.currentFilePath.lastIndexOf('/') + 1);
|
||||
// Construct new filepath
|
||||
const newFilePath = `${targetPath}/${filename}`;
|
||||
const newFilePath = await apiClient.moveSingleModel(this.currentFilePath, targetPath);
|
||||
|
||||
state.virtualScroller.updateSingleItem(this.currentFilePath, {file_path: newFilePath});
|
||||
const pageState = getCurrentPageState();
|
||||
if (newFilePath) {
|
||||
if (pageState.activeFolder !== null && state.virtualScroller) {
|
||||
state.virtualScroller.removeItemByFilePath(this.currentFilePath);
|
||||
} else {
|
||||
state.virtualScroller.updateSingleItem(this.currentFilePath, {file_path: newFilePath});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,102 +212,6 @@ class MoveManager {
|
||||
showToast('Failed to move model(s): ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async moveSingleModel(filePath, targetPath) {
|
||||
// show toast if current path is same as target path
|
||||
if (filePath.substring(0, filePath.lastIndexOf('/')) === targetPath) {
|
||||
showToast('Model is already in the selected folder', 'info');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch('/api/move_model', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
file_path: filePath,
|
||||
target_path: targetPath
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
if (result && result.error) {
|
||||
throw new Error(result.error);
|
||||
}
|
||||
throw new Error('Failed to move model');
|
||||
}
|
||||
|
||||
if (result && result.message) {
|
||||
showToast(result.message, 'info');
|
||||
} else {
|
||||
showToast('Model moved successfully', 'success');
|
||||
}
|
||||
}
|
||||
|
||||
async moveBulkModels(filePaths, targetPath) {
|
||||
// Filter out models already in the target path
|
||||
const movedPaths = filePaths.filter(path => {
|
||||
return path.substring(0, path.lastIndexOf('/')) !== targetPath;
|
||||
});
|
||||
|
||||
if (movedPaths.length === 0) {
|
||||
showToast('All selected models are already in the target folder', 'info');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch('/api/move_models_bulk', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
file_paths: movedPaths,
|
||||
target_path: targetPath
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to move models');
|
||||
}
|
||||
|
||||
// Display results with more details
|
||||
if (result.success) {
|
||||
if (result.failure_count > 0) {
|
||||
// Some files failed to move
|
||||
showToast(`Moved ${result.success_count} models, ${result.failure_count} failed`, 'warning');
|
||||
|
||||
// Log details about failures
|
||||
console.log('Move operation results:', result.results);
|
||||
|
||||
// Get list of failed files with reasons
|
||||
const failedFiles = result.results
|
||||
.filter(r => !r.success)
|
||||
.map(r => {
|
||||
const fileName = r.path.substring(r.path.lastIndexOf('/') + 1);
|
||||
return `${fileName}: ${r.message}`;
|
||||
});
|
||||
|
||||
// Show first few failures in a toast
|
||||
if (failedFiles.length > 0) {
|
||||
const failureMessage = failedFiles.length <= 3
|
||||
? failedFiles.join('\n')
|
||||
: failedFiles.slice(0, 3).join('\n') + `\n(and ${failedFiles.length - 3} more)`;
|
||||
|
||||
showToast(`Failed moves:\n${failureMessage}`, 'warning', 6000);
|
||||
}
|
||||
} else {
|
||||
// All files moved successfully
|
||||
showToast(`Successfully moved ${result.success_count} models`, 'success');
|
||||
}
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to move models');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const moveManager = new MoveManager();
|
||||
|
||||
Reference in New Issue
Block a user