195 lines
7.8 KiB
JavaScript
195 lines
7.8 KiB
JavaScript
// Shared utility functions for LoRA renaming
|
|
|
|
/**
|
|
* Shows a temporary non-blocking message
|
|
* @param {string} message - The message to display
|
|
* @param {string} type - 'success', 'warning', or 'error'
|
|
*/
|
|
function showTemporaryMessage(message, type = 'success') {
|
|
const messageElement = document.createElement('div');
|
|
messageElement.style.cssText = `
|
|
position: fixed !important;
|
|
top: 20px !important;
|
|
right: 20px !important;
|
|
background-color: ${
|
|
type === 'success' ? '#2a5a2a' :
|
|
type === 'warning' ? '#5a5a2a' :
|
|
'#5a2a2a'
|
|
} !important;
|
|
color: #ddd !important;
|
|
padding: 12px 16px !important;
|
|
border-radius: 6px !important;
|
|
border: 1px solid ${
|
|
type === 'success' ? '#4a7a4a' :
|
|
type === 'warning' ? '#7a7a4a' :
|
|
'#7a4a4a'
|
|
} !important;
|
|
font-family: Arial, sans-serif !important;
|
|
font-size: 13px !important;
|
|
z-index: 10002 !important;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.3) !important;
|
|
opacity: 0 !important;
|
|
transition: opacity 0.3s ease-in-out !important;
|
|
max-width: 350px !important;
|
|
word-wrap: break-word !important;
|
|
`;
|
|
|
|
messageElement.textContent = message;
|
|
document.body.appendChild(messageElement);
|
|
|
|
// Fade in
|
|
setTimeout(() => {
|
|
messageElement.style.opacity = '1';
|
|
}, 10);
|
|
|
|
// Remove after 3 seconds
|
|
setTimeout(() => {
|
|
messageElement.style.opacity = '0';
|
|
setTimeout(() => {
|
|
if (messageElement.parentNode) {
|
|
messageElement.parentNode.removeChild(messageElement);
|
|
}
|
|
}, 300);
|
|
}, 3000);
|
|
}
|
|
|
|
/**
|
|
* Renames a LoRA file and its associated files
|
|
* @param {string} loraName - The current LoRA file path
|
|
* @param {string} variant - 'high' for main LoRA, 'low' for low variant
|
|
* @param {Function} [refreshCallback] - Optional callback to refresh the UI after renaming
|
|
* @param {Function} [widgetCallback] - Optional widget callback for UI updates
|
|
* @param {Object} [node] - Optional node for canvas updates
|
|
* @param {Object} [widget] - Optional widget for value updates
|
|
*/
|
|
export async function renameLoRAFiles(loraName, variant = 'high', refreshCallback = null, widgetCallback = null, node = null, widget = null) {
|
|
if (!loraName) {
|
|
console.error('No LoRA name found for renaming');
|
|
return;
|
|
}
|
|
|
|
// Extract filename without extension
|
|
const fileName = loraName.includes('/') || loraName.includes('\\')
|
|
? loraName.split(/[\/\\]/).pop()
|
|
: loraName;
|
|
|
|
const baseName = fileName.replace(/\.safetensors$/, '');
|
|
|
|
// Show a simple prompt for the new name
|
|
const newName = prompt(`Enter new name for LoRA:`, baseName);
|
|
|
|
if (!newName || newName.trim() === '') {
|
|
return; // User cancelled or entered empty name
|
|
}
|
|
|
|
const finalNewName = newName.trim().replace(/[^a-zA-Z0-9_-]/g, '_'); // Sanitize name
|
|
|
|
if (finalNewName === baseName) {
|
|
return; // No change
|
|
}
|
|
|
|
try {
|
|
const response = await fetch('/wanvideo_wrapper/rename_lora', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
old_name: loraName,
|
|
new_name: finalNewName,
|
|
variant: variant
|
|
})
|
|
});
|
|
|
|
// Check if response is ok before trying to parse JSON
|
|
if (!response.ok) {
|
|
const errorText = await response.text();
|
|
console.error('Server returned error:', response.status, errorText);
|
|
throw new Error(`Server error ${response.status}: ${errorText}`);
|
|
}
|
|
|
|
// Try to parse JSON with better error handling
|
|
let data;
|
|
let responseText;
|
|
try {
|
|
responseText = await response.text();
|
|
console.log('Raw response:', responseText); // Debug log
|
|
data = JSON.parse(responseText);
|
|
} catch (parseError) {
|
|
console.error('JSON parse error:', parseError);
|
|
console.error('Raw response text:', responseText);
|
|
throw new Error(`Invalid JSON response from server: ${responseText ? responseText.substring(0, 200) : 'Empty response'}`);
|
|
}
|
|
|
|
if (data.success) {
|
|
// Handle widget updates if widget and node are provided
|
|
if (widget && node) {
|
|
// Update the widget value(s) based on which variant was renamed
|
|
if (variant === 'low') {
|
|
widget.value.low_variant_name = data.new_low_path;
|
|
if (widget.value.is_low && widget.value.low_variant_name) {
|
|
widget.value.lora_name = data.new_low_path;
|
|
}
|
|
} else {
|
|
widget.value.lora_name = data.new_high_path;
|
|
// Also update low variant if it exists and is based on the high one
|
|
if (widget.value.is_low && widget.value.low_variant_name &&
|
|
widget.value.low_variant_name.includes(baseName)) {
|
|
widget.value.low_variant_name = data.new_low_path || data.new_high_path;
|
|
}
|
|
}
|
|
|
|
// Update the displayed name
|
|
if (widgetCallback) {
|
|
widgetCallback(widget.value, null, null, null);
|
|
}
|
|
|
|
// Mark canvas as dirty to trigger redraw
|
|
node.setDirtyCanvas(true, true);
|
|
}
|
|
|
|
// Handle refresh callback (for picker dialog)
|
|
if (refreshCallback) {
|
|
// Show success message in console and call refresh
|
|
console.log('LoRA renamed successfully:', data.message);
|
|
|
|
// Show a temporary success message instead of blocking alert
|
|
showTemporaryMessage(`✅ LoRA renamed to: ${finalNewName}.safetensors`, 'success');
|
|
|
|
try {
|
|
await refreshCallback();
|
|
console.log('Refresh callback executed successfully');
|
|
} catch (refreshError) {
|
|
console.warn('Refresh callback failed:', refreshError);
|
|
showTemporaryMessage('⚠️ List may need manual refresh to see updated name', 'warning');
|
|
}
|
|
} else if (!widget) {
|
|
// Show success message for non-widget, non-picker contexts
|
|
console.log('LoRA renamed successfully:', data.message);
|
|
showTemporaryMessage(`✅ LoRA renamed to: ${finalNewName}.safetensors`, 'success');
|
|
|
|
// If we have access to the dialog, refresh preview availability for blue dots
|
|
const dialog = document.querySelector('.lora-picker-dialog');
|
|
if (dialog && dialog.dialogInstance && dialog.dialogInstance.loadPreviewAvailability) {
|
|
try {
|
|
console.log('Refreshing preview availability after rename...');
|
|
await dialog.dialogInstance.loadPreviewAvailability();
|
|
// Re-render list to update blue dots
|
|
if (dialog.dialogInstance.renderList) {
|
|
dialog.dialogInstance.renderList();
|
|
}
|
|
console.log('Preview availability refreshed after rename');
|
|
} catch (previewError) {
|
|
console.warn('Failed to refresh preview availability after rename:', previewError);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
alert('Failed to rename LoRA: ' + (data.error || 'Unknown error'));
|
|
console.error('Failed to rename LoRA:', data.error);
|
|
}
|
|
} catch (error) {
|
|
alert('Error renaming LoRA: ' + error.message);
|
|
console.error('Error renaming LoRA:', error);
|
|
}
|
|
} |