mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
feat: Enhance path correction functionality for widget nodes with pattern matching and user notifications
This commit is contained in:
@@ -1,6 +1,15 @@
|
|||||||
// ComfyUI extension to track model usage statistics
|
// ComfyUI extension to track model usage statistics
|
||||||
import { app } from "../../scripts/app.js";
|
import { app } from "../../scripts/app.js";
|
||||||
import { api } from "../../scripts/api.js";
|
import { api } from "../../scripts/api.js";
|
||||||
|
import { showToast } from "./utils.js";
|
||||||
|
|
||||||
|
// Define target nodes and their widget configurations
|
||||||
|
const PATH_CORRECTION_TARGETS = [
|
||||||
|
{ comfyClass: "CheckpointLoaderSimple", widgetName: "ckpt_name", modelType: "checkpoints" },
|
||||||
|
{ comfyClass: "UNETLoader", widgetName: "unet_name", modelType: "checkpoints" },
|
||||||
|
{ comfyClass: "LoraLoader", widgetName: "lora_name", modelType: "loras" },
|
||||||
|
{ comfyClass: "easy loraStack", widgetNamePattern: "lora_\\d+_name", modelType: "loras" }
|
||||||
|
];
|
||||||
|
|
||||||
// Register the extension
|
// Register the extension
|
||||||
app.registerExtension({
|
app.registerExtension({
|
||||||
@@ -80,5 +89,100 @@ app.registerExtension({
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error refreshing registry:", error);
|
console.error("Error refreshing registry:", error);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadedGraphNode(node) {
|
||||||
|
// Check if this node type needs path correction
|
||||||
|
const target = PATH_CORRECTION_TARGETS.find(t => t.comfyClass === node.comfyClass);
|
||||||
|
if (!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.correctNodePaths(node, target);
|
||||||
|
},
|
||||||
|
|
||||||
|
async correctNodePaths(node, target) {
|
||||||
|
try {
|
||||||
|
if (target.widgetNamePattern) {
|
||||||
|
// Handle pattern-based widget names (like lora_1_name, lora_2_name, etc.)
|
||||||
|
const pattern = new RegExp(target.widgetNamePattern);
|
||||||
|
const widgetIndexes = [];
|
||||||
|
|
||||||
|
if (node.widgets) {
|
||||||
|
node.widgets.forEach((widget, index) => {
|
||||||
|
if (pattern.test(widget.name)) {
|
||||||
|
widgetIndexes.push(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each matching widget
|
||||||
|
for (const widgetIndex of widgetIndexes) {
|
||||||
|
await this.correctWidgetPath(node, widgetIndex, target.modelType);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle single widget name
|
||||||
|
if (node.widgets) {
|
||||||
|
const widgetIndex = node.widgets.findIndex(w => w.name === target.widgetName);
|
||||||
|
if (widgetIndex !== -1) {
|
||||||
|
await this.correctWidgetPath(node, widgetIndex, target.modelType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error correcting node paths:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async correctWidgetPath(node, widgetIndex, modelType) {
|
||||||
|
if (!node.widgets_values || !node.widgets_values[widgetIndex]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentPath = node.widgets_values[widgetIndex];
|
||||||
|
if (!currentPath || typeof currentPath !== 'string') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract filename from path (after last separator)
|
||||||
|
const fileName = currentPath.split(/[/\\]/).pop();
|
||||||
|
if (!fileName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Search for current relative path
|
||||||
|
const response = await api.fetchApi(`/${modelType}/relative-paths?search=${encodeURIComponent(fileName)}&limit=2`);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!data.success || !data.relative_paths || data.relative_paths.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const foundPaths = data.relative_paths;
|
||||||
|
const firstPath = foundPaths[0];
|
||||||
|
|
||||||
|
// Check if we need to update the path
|
||||||
|
if (firstPath !== currentPath) {
|
||||||
|
// Update the widget value
|
||||||
|
// node.widgets_values[widgetIndex] = firstPath;
|
||||||
|
node.widgets[widgetIndex].value = firstPath;
|
||||||
|
|
||||||
|
if (foundPaths.length === 1) {
|
||||||
|
// Single match found - success
|
||||||
|
showToast(`Updated path for ${fileName}: ${firstPath}`, 'info');
|
||||||
|
} else {
|
||||||
|
// Multiple matches found - warning
|
||||||
|
showToast(`Multiple paths found for ${fileName}, using: ${firstPath}`, 'warning');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark node as modified
|
||||||
|
if (node.setDirtyCanvas) {
|
||||||
|
node.setDirtyCanvas(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error correcting path for ${fileName}:`, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,6 +23,28 @@ export function getComfyUIFrontendVersion() {
|
|||||||
return window['__COMFYUI_FRONTEND_VERSION__'] || "0.0.0";
|
return window['__COMFYUI_FRONTEND_VERSION__'] || "0.0.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a toast notification
|
||||||
|
* @param {string} message - The message to display
|
||||||
|
* @param {string} type - The type of toast (success, error, info, warning)
|
||||||
|
*/
|
||||||
|
export function showToast(message, type = 'info') {
|
||||||
|
if (app && app.extensionManager && app.extensionManager.toast) {
|
||||||
|
app.extensionManager.toast.add({
|
||||||
|
severity: type,
|
||||||
|
summary: type.charAt(0).toUpperCase() + type.slice(1),
|
||||||
|
detail: message,
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log(`${type.toUpperCase()}: ${message}`);
|
||||||
|
// Fallback alert for critical errors only
|
||||||
|
if (type === 'error') {
|
||||||
|
alert(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dynamically import the appropriate widget based on app version
|
// Dynamically import the appropriate widget based on app version
|
||||||
export async function dynamicImportByVersion(latestModulePath, legacyModulePath) {
|
export async function dynamicImportByVersion(latestModulePath, legacyModulePath) {
|
||||||
// Parse app version and compare with 1.12.6 (version when tags widget API changed)
|
// Parse app version and compare with 1.12.6 (version when tags widget API changed)
|
||||||
|
|||||||
Reference in New Issue
Block a user