Files

254 lines
7.9 KiB
JavaScript

import { api } from '/scripts/api.js'
import * as shared from './comfy_shared.js'
import { app } from '/scripts/app.js'
export const findWidgetByName = (node, name) => {
return node.widgets ? node.widgets.find((w) => w.name === name) : null;
}
export const doesInputWithNameExist = (node, name) => {
return node.inputs ? node.inputs.some((input) => input.name === name) : false;
}
export const findWidgetsByType = (node, type) => {
var widgets = [];
node.widgets.map((widget) => {
if (widget.type === type) {
widgets.push(widget);
}
});
return widgets;
}
export const getNodeByLink = (linkId, type) => app.graph.getNodeById(app.graph.links[linkId][type == "input" ? "origin_id" : "target_id"]);
// node.title is visual title
export function isGetter(node) {
return node.type === "GetNode" || node.type?.includes?.("Getter");
}
export function isSetter(node) {
return node.type === 'SetNode' || node.type?.includes?.("Setter");
}
export const isSetNode = (node) => node.type === "SetNode";
export const isGetNode = (node) => node.type === "GetNode";
function findSetterNode(key) {
return app.graph._nodes.find((node) => isSetter(node) && findWidgetByName(node, "key").value === key);
}
function findGetterNode(key) {
return app.graph._nodes.find((node) => isGetter(node) && findWidgetByName(node, "key").value === key);
}
function findSetNode(key) {
return app.graph._nodes.find((node) => isSetNode(node) && node.widgets_values === key);
}
function findGetNode(key) {
return app.graph._nodes.find((node) => isGetNode(node) && node.widgets_values === key);
}
export function enableOnlyRelatedNodes(targetNode) {
let whitelist = {};
function travelBackward(node) {
whitelist[node.id] = node;
if (!node.inputs) return;
if (isGetter(node)) {
const key = findWidgetByName(node, "key").value;
const setterNode = findSetterNode(key);
if (!setterNode) {
shared.errorLogger('No Setter node find for key:', key);
} else {
shared.log("Connecting Getter & Setter", node?.widgets_values);
travelBackward(setterNode);
}
} else if (isGetNode(node)) {
const key = findWidgetByName(node, "Constant").value;
const setNode = findSetNode(key);
if (!setNode) {
shared.errorLogger('No SetNode find for Constant:', key);
} else {
shared.log("Connecting GetNode & SetNode", node?.widgets_values);
travelBackward(setNode);
}
} else {
for (const input of node.inputs) {
if (!input.link) continue
travelBackward(getNodeByLink(input.link, "input"));
}
}
}
function travelForward(node) {
whitelist[node.id] = node;
travelBackward(node);
if (!node.outputs) return;
for (const output of node.outputs) {
if (!output.links) continue;
for (const link of output.links) {
travelForward(getNodeByLink(link, "output"));
}
}
}
travelForward(targetNode);
let notAlreadyMutedBlacklist = app.graph._nodes.filter(node => node.mode !== 2 && !whitelist[node.id]);
for (const node of notAlreadyMutedBlacklist) node.mode = 2;
return notAlreadyMutedBlacklist;
}
export function waitForPromptId() {
const originalFetch = window.fetch;
return new Promise(resolve => {
window.fetch = async (...args) => {
let [url, config] = args;
const response = await originalFetch(url, config);
if (url === "/prompt") {
response.clone().json().then(data => resolve(data.prompt_id));
window.fetch = originalFetch;
}
return response;
};
})
}
//https://github.com/melMass/comfy_mtb/blob/main/web/mtb_widgets.js#L309
//Thanks for cool text box.
export const DEBUG_STRING = (name, val) => {
const fontSize = 16
const w = {
name,
type: 'debug_text',
draw: function (ctx, node, widgetWidth, widgetY, height) {
// const [cw, ch] = this.computeSize(widgetWidth)
shared.offsetDOMWidget(this, ctx, node, widgetWidth, widgetY, height)
},
computeSize: function (width) {
const value = this.inputEl.innerHTML
if (!value) {
return [32, 32]
}
if (!width) {
log(`No width ${this.parent.size}`)
}
const oldFont = app.ctx.font
app.ctx.font = `${fontSize}px monospace`
const words = value.split(' ')
const lines = []
let currentLine = ''
for (const word of words) {
const testLine =
currentLine.length === 0 ? word : `${currentLine} ${word}`
const testWidth = app.ctx.measureText(testLine).width
if (testWidth > width) {
lines.push(currentLine)
currentLine = word
} else {
currentLine = testLine
}
}
app.ctx.font = oldFont
if (lines.length === 0) lines.push(currentLine)
const textHeight = (lines.length + 1) * fontSize
const maxLineWidth = lines.reduce(
(maxWidth, line) =>
Math.max(maxWidth, app.ctx.measureText(line).width),
0
)
const widgetWidth = Math.max(width || this.width || 32, maxLineWidth)
const widgetHeight = textHeight * 1.5
return [widgetWidth, widgetHeight]
},
onRemoved: function () {
if (this.inputEl) {
this.inputEl.remove()
}
},
}
Object.defineProperty(w, 'value', {
get() {
return this.inputEl.innerHTML
},
set(value) {
this.inputEl.innerHTML = value
this.parent?.setSize?.(this.parent?.computeSize())
},
})
w.inputEl = document.createElement('p')
w.inputEl.style.textAlign = 'center'
w.inputEl.style.fontSize = `${fontSize}px`
w.inputEl.style.color = 'var(--input-text)'
w.inputEl.style.lineHeight = 0
w.inputEl.style.fontFamily = 'monospace'
w.value = val
document.body.appendChild(w.inputEl)
return w
}
export function setColorAndBgColor(type) {
const colorMap = {
"MODEL": LGraphCanvas.node_colors.blue,
"LATENT": LGraphCanvas.node_colors.purple,
"VAE": LGraphCanvas.node_colors.red,
"CONDITIONING": LGraphCanvas.node_colors.brown,
"IMAGE": LGraphCanvas.node_colors.pale_blue,
"CLIP": LGraphCanvas.node_colors.yellow,
"FLOAT": LGraphCanvas.node_colors.green,
"MASK": LGraphCanvas.node_colors.cyan,
"INT": { color: "#1b4669", bgcolor: "#29699c"},
"*": { color: "#453e2c", bgcolor: "#756d58"},
};
const nameColorMap = {
"ksampler": { color: "820300", bgcolor: "B80000"},
"controlnet": { color: "FF9800", bgcolor: "5F8670"},
"ipadapter": { color: "3E3232", bgcolor: "503C3C"},
"checkpoint": { color: "2D3250", bgcolor: "424769"},
"lora": {color: "C499F3" , bgcolor: "7360DF"},
}
const colors = colorMap[type];
if (colors) {
this.color = colors.color;
this.bgcolor = colors.bgcolor;
} else {
// Handle the default case if needed
const name = this.type.toLowerCase?.();
if (!name) {
return;
}
for (let [key, value] of Object.entries(nameColorMap)) {
if (name.includes(key)) {
this.color = value.color;
this.bgcolor = value.bgcolor
console.log(name, key);
return;
}
}
}
}