mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-24 22:52:12 -03:00
feat: refactor API routes for renaming models and update related functions
This commit is contained in:
@@ -140,7 +140,7 @@ export async function renameCheckpointFile(filePath, newFileName) {
|
||||
// Show loading indicator
|
||||
state.loadingManager.showSimpleLoading('Renaming checkpoint file...');
|
||||
|
||||
const response = await fetch('/api/rename_checkpoint', {
|
||||
const response = await fetch('/api/checkpoints/rename', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -160,7 +160,6 @@ export async function renameCheckpointFile(filePath, newFileName) {
|
||||
console.error('Error renaming checkpoint file:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
// Hide loading indicator
|
||||
state.loadingManager.hide();
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ export async function renameLoraFile(filePath, newFileName) {
|
||||
// Show loading indicator
|
||||
state.loadingManager.showSimpleLoading('Renaming LoRA file...');
|
||||
|
||||
const response = await fetch('/api/rename_lora', {
|
||||
const response = await fetch('/api/loras/rename', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { showToast, getNSFWLevelName, openExampleImagesFolder } from '../../utils/uiHelpers.js';
|
||||
import { NSFW_LEVELS } from '../../utils/constants.js';
|
||||
import { getStorageItem } from '../../utils/storageHelpers.js';
|
||||
import { modalManager } from '../../managers/ModalManager.js';
|
||||
import { state } from '../../state/index.js';
|
||||
|
||||
@@ -44,149 +42,6 @@ export const ModelContextMenuMixin = {
|
||||
});
|
||||
},
|
||||
|
||||
updateCardBlurEffect(card, level) {
|
||||
// Get user settings for blur threshold
|
||||
const blurThreshold = parseInt(getStorageItem('nsfwBlurLevel') || '4');
|
||||
|
||||
// Get card preview container
|
||||
const previewContainer = card.querySelector('.card-preview');
|
||||
if (!previewContainer) return;
|
||||
|
||||
// Get preview media element
|
||||
const previewMedia = previewContainer.querySelector('img') || previewContainer.querySelector('video');
|
||||
if (!previewMedia) return;
|
||||
|
||||
// Check if blur should be applied
|
||||
if (level >= blurThreshold) {
|
||||
// Add blur class to the preview container
|
||||
previewContainer.classList.add('blurred');
|
||||
|
||||
// Get or create the NSFW overlay
|
||||
let nsfwOverlay = previewContainer.querySelector('.nsfw-overlay');
|
||||
if (!nsfwOverlay) {
|
||||
// Create new overlay
|
||||
nsfwOverlay = document.createElement('div');
|
||||
nsfwOverlay.className = 'nsfw-overlay';
|
||||
|
||||
// Create and configure the warning content
|
||||
const warningContent = document.createElement('div');
|
||||
warningContent.className = 'nsfw-warning';
|
||||
|
||||
// Determine NSFW warning text based on level
|
||||
let nsfwText = "Mature Content";
|
||||
if (level >= NSFW_LEVELS.XXX) {
|
||||
nsfwText = "XXX-rated Content";
|
||||
} else if (level >= NSFW_LEVELS.X) {
|
||||
nsfwText = "X-rated Content";
|
||||
} else if (level >= NSFW_LEVELS.R) {
|
||||
nsfwText = "R-rated Content";
|
||||
}
|
||||
|
||||
// Add warning text and show button
|
||||
warningContent.innerHTML = `
|
||||
<p>${nsfwText}</p>
|
||||
<button class="show-content-btn">Show</button>
|
||||
`;
|
||||
|
||||
// Add click event to the show button
|
||||
const showBtn = warningContent.querySelector('.show-content-btn');
|
||||
showBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
previewContainer.classList.remove('blurred');
|
||||
nsfwOverlay.style.display = 'none';
|
||||
|
||||
// Update toggle button icon if it exists
|
||||
const toggleBtn = card.querySelector('.toggle-blur-btn');
|
||||
if (toggleBtn) {
|
||||
toggleBtn.querySelector('i').className = 'fas fa-eye-slash';
|
||||
}
|
||||
});
|
||||
|
||||
nsfwOverlay.appendChild(warningContent);
|
||||
previewContainer.appendChild(nsfwOverlay);
|
||||
} else {
|
||||
// Update existing overlay
|
||||
const warningText = nsfwOverlay.querySelector('p');
|
||||
if (warningText) {
|
||||
let nsfwText = "Mature Content";
|
||||
if (level >= NSFW_LEVELS.XXX) {
|
||||
nsfwText = "XXX-rated Content";
|
||||
} else if (level >= NSFW_LEVELS.X) {
|
||||
nsfwText = "X-rated Content";
|
||||
} else if (level >= NSFW_LEVELS.R) {
|
||||
nsfwText = "R-rated Content";
|
||||
}
|
||||
warningText.textContent = nsfwText;
|
||||
}
|
||||
nsfwOverlay.style.display = 'flex';
|
||||
}
|
||||
|
||||
// Get or create the toggle button in the header
|
||||
const cardHeader = previewContainer.querySelector('.card-header');
|
||||
if (cardHeader) {
|
||||
let toggleBtn = cardHeader.querySelector('.toggle-blur-btn');
|
||||
|
||||
if (!toggleBtn) {
|
||||
toggleBtn = document.createElement('button');
|
||||
toggleBtn.className = 'toggle-blur-btn';
|
||||
toggleBtn.title = 'Toggle blur';
|
||||
toggleBtn.innerHTML = '<i class="fas fa-eye"></i>';
|
||||
|
||||
// Add click event to toggle button
|
||||
toggleBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const isBlurred = previewContainer.classList.toggle('blurred');
|
||||
const icon = toggleBtn.querySelector('i');
|
||||
|
||||
// Update icon and overlay visibility
|
||||
if (isBlurred) {
|
||||
icon.className = 'fas fa-eye';
|
||||
nsfwOverlay.style.display = 'flex';
|
||||
} else {
|
||||
icon.className = 'fas fa-eye-slash';
|
||||
nsfwOverlay.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Add to the beginning of header
|
||||
cardHeader.insertBefore(toggleBtn, cardHeader.firstChild);
|
||||
|
||||
// Update base model label class
|
||||
const baseModelLabel = cardHeader.querySelector('.base-model-label');
|
||||
if (baseModelLabel && !baseModelLabel.classList.contains('with-toggle')) {
|
||||
baseModelLabel.classList.add('with-toggle');
|
||||
}
|
||||
} else {
|
||||
// Update existing toggle button
|
||||
toggleBtn.querySelector('i').className = 'fas fa-eye';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove blur
|
||||
previewContainer.classList.remove('blurred');
|
||||
|
||||
// Hide overlay if it exists
|
||||
const overlay = previewContainer.querySelector('.nsfw-overlay');
|
||||
if (overlay) overlay.style.display = 'none';
|
||||
|
||||
// Remove toggle button when content is set to PG or PG13
|
||||
const cardHeader = previewContainer.querySelector('.card-header');
|
||||
if (cardHeader) {
|
||||
const toggleBtn = cardHeader.querySelector('.toggle-blur-btn');
|
||||
if (toggleBtn) {
|
||||
// Remove the toggle button completely
|
||||
toggleBtn.remove();
|
||||
|
||||
// Update base model label class if it exists
|
||||
const baseModelLabel = cardHeader.querySelector('.base-model-label');
|
||||
if (baseModelLabel && baseModelLabel.classList.contains('with-toggle')) {
|
||||
baseModelLabel.classList.remove('with-toggle');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
showNSFWLevelSelector(x, y, card) {
|
||||
const selector = document.getElementById('nsfwLevelSelector');
|
||||
const currentLevelEl = document.getElementById('currentNSFWLevel');
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { showToast } from '../../utils/uiHelpers.js';
|
||||
import { BASE_MODELS } from '../../utils/constants.js';
|
||||
import { updateModelCard } from '../../utils/cardUpdater.js';
|
||||
import { state } from '../../state/index.js';
|
||||
import { saveModelMetadata, renameCheckpointFile } from '../../api/checkpointApi.js';
|
||||
|
||||
/**
|
||||
@@ -412,30 +412,10 @@ export function setupFileNameEditing(filePath) {
|
||||
if (result.success) {
|
||||
showToast('File name updated successfully', 'success');
|
||||
|
||||
// Get the new file path from the result
|
||||
const pathParts = filePath.split(/[\\/]/);
|
||||
pathParts.pop(); // Remove old filename
|
||||
const newFilePath = [...pathParts, newFileName].join('/');
|
||||
const newFilePath = filePath.replace(originalValue, newFileName);
|
||||
|
||||
// Update the checkpoint card with new file path
|
||||
updateModelCard(filePath, {
|
||||
filepath: newFilePath,
|
||||
file_name: newFileName
|
||||
});
|
||||
|
||||
// Update the file name display in the modal
|
||||
document.querySelector('#file-name').textContent = newFileName;
|
||||
|
||||
// Update the modal's data-filepath attribute
|
||||
const modalContent = document.querySelector('#checkpointModal .modal-content');
|
||||
if (modalContent) {
|
||||
modalContent.dataset.filepath = newFilePath;
|
||||
}
|
||||
|
||||
// Reload the page after a short delay to reflect changes
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1500);
|
||||
state.virtualScroller.updateSingleItem(filePath, { file_name: newFileName, file_path: newFilePath });
|
||||
this.textContent = newFileName;
|
||||
} else {
|
||||
throw new Error(result.error || 'Unknown error');
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { showToast } from '../../utils/uiHelpers.js';
|
||||
import { BASE_MODELS } from '../../utils/constants.js';
|
||||
import { updateModelCard } from '../../utils/cardUpdater.js';
|
||||
import { state } from '../../state/index.js';
|
||||
import { saveModelMetadata, renameLoraFile } from '../../api/loraApi.js';
|
||||
|
||||
/**
|
||||
@@ -420,8 +420,8 @@ export function setupFileNameEditing(filePath) {
|
||||
|
||||
// Get the new file path and update the card
|
||||
const newFilePath = filePath.replace(originalValue, newFileName);
|
||||
// Pass the new file_name in the updates object for proper card update
|
||||
updateModelCard(filePath, { file_name: newFileName, filepath: newFilePath });
|
||||
;
|
||||
state.virtualScroller.updateSingleItem(filePath, { file_name: newFileName, file_path: newFilePath });
|
||||
} else {
|
||||
throw new Error(result.error || 'Unknown error');
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import { showToast } from '../utils/uiHelpers.js';
|
||||
import { state, getCurrentPageState } from '../state/index.js';
|
||||
import { modalManager } from './ModalManager.js';
|
||||
import { getStorageItem } from '../utils/storageHelpers.js';
|
||||
import { updateModelCard } from '../utils/cardUpdater.js';
|
||||
|
||||
class MoveManager {
|
||||
constructor() {
|
||||
@@ -151,8 +150,8 @@ class MoveManager {
|
||||
const filename = filePath.substring(filePath.lastIndexOf('/') + 1);
|
||||
// Construct new filepath
|
||||
const newFilePath = `${targetPath}/${filename}`;
|
||||
// Update the card with new filepath
|
||||
updateModelCard(filePath, {filepath: newFilePath});
|
||||
|
||||
state.virtualScroller.updateSingleItem(filePath, {file_path: newFilePath});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@@ -169,8 +168,8 @@ class MoveManager {
|
||||
const filename = this.currentFilePath.substring(this.currentFilePath.lastIndexOf('/') + 1);
|
||||
// Construct new filepath
|
||||
const newFilePath = `${targetPath}/${filename}`;
|
||||
// Update the card with new filepath
|
||||
updateModelCard(this.currentFilePath, {filepath: newFilePath});
|
||||
|
||||
state.virtualScroller.updateSingleItem(this.currentFilePath, {file_path: newFilePath});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,47 +2,6 @@
|
||||
* Utility functions to update checkpoint cards after modal edits
|
||||
*/
|
||||
|
||||
/**
|
||||
* Update the Lora card after metadata edits in the modal
|
||||
* @param {string} filePath - Path to the Lora file
|
||||
* @param {Object} updates - Object containing the updates (model_name, base_model, notes, usage_tips, etc)
|
||||
*/
|
||||
export function updateModelCard(filePath, updates) {
|
||||
// Find the card with matching filepath
|
||||
const modelCard = document.querySelector(`.lora-card[data-filepath="${filePath}"]`);
|
||||
if (!modelCard) return;
|
||||
|
||||
// Update card dataset and visual elements based on the updates object
|
||||
Object.entries(updates).forEach(([key, value]) => {
|
||||
// Update dataset
|
||||
modelCard.dataset[key] = value;
|
||||
|
||||
// Update visual elements based on the property
|
||||
switch(key) {
|
||||
case 'model_name':
|
||||
// Update the model name in the card title
|
||||
const titleElement = modelCard.querySelector('.card-title');
|
||||
if (titleElement) titleElement.textContent = value;
|
||||
|
||||
// Also update the model name in the footer if it exists
|
||||
const modelNameElement = modelCard.querySelector('.model-name');
|
||||
if (modelNameElement) modelNameElement.textContent = value;
|
||||
break;
|
||||
|
||||
case 'base_model':
|
||||
// Update the base model label in the card header if it exists
|
||||
const baseModelLabel = modelCard.querySelector('.base-model-label');
|
||||
if (baseModelLabel) {
|
||||
baseModelLabel.textContent = value;
|
||||
baseModelLabel.title = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
return modelCard; // Return the updated card element for chaining
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the recipe card after metadata edits in the modal
|
||||
* @param {string} recipeId - ID of the recipe to update
|
||||
|
||||
Reference in New Issue
Block a user