|
|
import { app } from "../../scripts/app.js"; |
|
|
import { api } from "../../scripts/api.js"; |
|
|
import { ComfyDialog, $el } from "../../scripts/ui.js"; |
|
|
|
|
|
|
|
|
export function rebootAPI() { |
|
|
if (confirm("Are you sure you'd like to reboot the server?")) { |
|
|
try { |
|
|
api.fetchApi("/ttN/reboot"); |
|
|
} |
|
|
catch(exception) { |
|
|
console.log("Failed to reboot: " + exception); |
|
|
} |
|
|
return true; |
|
|
} |
|
|
|
|
|
return false; |
|
|
} |
|
|
|
|
|
export function wait(ms = 16, value) { |
|
|
return new Promise((resolve) => { |
|
|
setTimeout(() => { |
|
|
resolve(value); |
|
|
}, ms); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CONVERTED_TYPE = "converted-widget"; |
|
|
const GET_CONFIG = Symbol(); |
|
|
|
|
|
export function getConfig(widgetName, node) { |
|
|
const { nodeData } = node.constructor; |
|
|
return nodeData?.input?.required[widgetName] ?? nodeData?.input?.optional?.[widgetName]; |
|
|
} |
|
|
|
|
|
export function hideWidget(node, widget, suffix = "") { |
|
|
widget.origType = widget.type; |
|
|
widget.origComputeSize = widget.computeSize; |
|
|
widget.origSerializeValue = widget.serializeValue; |
|
|
widget.computeSize = () => [0, -4]; |
|
|
widget.type = CONVERTED_TYPE + suffix; |
|
|
widget.serializeValue = () => { |
|
|
|
|
|
if (!node.inputs) { |
|
|
return undefined; |
|
|
} |
|
|
let node_input = node.inputs.find((i) => i.widget?.name === widget.name); |
|
|
|
|
|
if (!node_input || !node_input.link) { |
|
|
return undefined; |
|
|
} |
|
|
return widget.origSerializeValue ? widget.origSerializeValue() : widget.value; |
|
|
}; |
|
|
|
|
|
|
|
|
if (widget.linkedWidgets) { |
|
|
for (const w of widget.linkedWidgets) { |
|
|
hideWidget(node, w, ":" + widget.name); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
export function getWidgetType(config) { |
|
|
|
|
|
let type = config[0]; |
|
|
if (type instanceof Array) { |
|
|
type = "COMBO"; |
|
|
} |
|
|
return { type }; |
|
|
} |
|
|
|
|
|
export function convertToInput(node, widget, config) { |
|
|
hideWidget(node, widget); |
|
|
|
|
|
const { type } = getWidgetType(config); |
|
|
|
|
|
|
|
|
const sz = node.size; |
|
|
node.addInput(widget.name, type, { |
|
|
widget: { name: widget.name, [GET_CONFIG]: () => config }, |
|
|
}); |
|
|
|
|
|
for (const widget of node.widgets) { |
|
|
widget.last_y += LiteGraph.NODE_SLOT_HEIGHT; |
|
|
} |
|
|
|
|
|
|
|
|
node.setSize([Math.max(sz[0], node.size[0]), Math.max(sz[1], node.size[1])]); |
|
|
} |
|
|
|
|
|
export function tinyterraReloadNode(node) { |
|
|
|
|
|
const { title: nodeTitle, color: nodeColor, bgcolor: bgColor } = node.properties.origVals || node; |
|
|
const options = { |
|
|
size: [...node.size], |
|
|
color: nodeColor, |
|
|
bgcolor: bgColor, |
|
|
pos: [...node.pos] |
|
|
}; |
|
|
|
|
|
|
|
|
const oldNode = node |
|
|
|
|
|
|
|
|
const inputConnections = [], outputConnections = []; |
|
|
if (node.inputs) { |
|
|
for (const input of node.inputs ?? []) { |
|
|
if (input.link) { |
|
|
const input_name = input.name |
|
|
const input_slot = node.findInputSlot(input_name) |
|
|
const input_node = node.getInputNode(input_slot) |
|
|
const input_link = node.getInputLink(input_slot) |
|
|
|
|
|
inputConnections.push([input_link.origin_slot, input_node, input_name]) |
|
|
} |
|
|
} |
|
|
} |
|
|
if (node.outputs) { |
|
|
for (const output of node.outputs) { |
|
|
if (output.links) { |
|
|
const output_name = output.name |
|
|
|
|
|
for (const linkID of output.links) { |
|
|
const output_link = graph.links[linkID] |
|
|
const output_node = graph._nodes_by_id[output_link.target_id] |
|
|
outputConnections.push([output_name, output_node, output_link.target_slot]) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
app.graph.remove(node) |
|
|
const newNode = app.graph.add(LiteGraph.createNode(node.constructor.type, nodeTitle, options)); |
|
|
if (newNode?.constructor?.hasOwnProperty('ttNnodeVersion')) { |
|
|
newNode.properties.ttNnodeVersion = newNode.constructor.ttNnodeVersion; |
|
|
} |
|
|
|
|
|
|
|
|
function handleLinks() { |
|
|
for (let ow of oldNode.widgets) { |
|
|
if (ow.type === CONVERTED_TYPE) { |
|
|
const config = getConfig(ow.name, oldNode) |
|
|
const WidgetToConvert = newNode.widgets.find((nw) => nw.name === ow.name); |
|
|
if (WidgetToConvert && !newNode?.inputs?.find((i) => i.name === ow.name)) { |
|
|
convertToInput(newNode, WidgetToConvert, config); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for (let input of inputConnections) { |
|
|
const [output_slot, output_node, input_name] = input; |
|
|
output_node.connect(output_slot, newNode.id, input_name) |
|
|
} |
|
|
for (let output of outputConnections) { |
|
|
const [output_name, input_node, input_slot] = output; |
|
|
newNode.connect(output_name, input_node, input_slot) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
let values = oldNode.widgets_values; |
|
|
if (!values) { |
|
|
console.log('NO VALUES') |
|
|
newNode.widgets.forEach((newWidget, index) => { |
|
|
let pass = false |
|
|
while ((index < oldNode.widgets.length) && !pass) { |
|
|
const oldWidget = oldNode.widgets[index]; |
|
|
if (newWidget.type === oldWidget.type) { |
|
|
newWidget.value = oldWidget.value; |
|
|
pass = true |
|
|
} |
|
|
index++; |
|
|
} |
|
|
}); |
|
|
} |
|
|
else { |
|
|
let isValid = false |
|
|
const isIterateForwards = values.length <= newNode.widgets.length; |
|
|
let valueIndex = isIterateForwards ? 0 : values.length - 1; |
|
|
|
|
|
const parseWidgetValue = (value, widget) => { |
|
|
if (['', null].includes(value) && (widget.type === "button" || widget.type === "converted-widget")) { |
|
|
return { value, isValid: true }; |
|
|
} |
|
|
if (typeof value === "boolean" && widget.options?.on && widget.options?.off) { |
|
|
return { value, isValid: true }; |
|
|
} |
|
|
if (widget.options?.values?.includes(value)) { |
|
|
return { value, isValid: true }; |
|
|
} |
|
|
if (widget.inputEl) { |
|
|
if (typeof value === "string" || value === widget.value) { |
|
|
return { value, isValid: true }; |
|
|
} |
|
|
} |
|
|
if (!isNaN(value)) { |
|
|
value = parseFloat(value); |
|
|
if (widget.options?.min <= value && value <= widget.options?.max) { |
|
|
return { value, isValid: true }; |
|
|
} |
|
|
} |
|
|
return { value: widget.value, isValid: false }; |
|
|
}; |
|
|
|
|
|
function updateValue(widgetIndex) { |
|
|
const oldWidget = oldNode.widgets[widgetIndex]; |
|
|
let newWidget = newNode.widgets[widgetIndex]; |
|
|
let newValueIndex = valueIndex |
|
|
|
|
|
if (newWidget.name === oldWidget.name && (newWidget.type === oldWidget.type || oldWidget.type === 'ttNhidden' || newWidget.type === 'ttNhidden')) { |
|
|
|
|
|
while ((isIterateForwards ? newValueIndex < values.length : newValueIndex >= 0) && !isValid) { |
|
|
let { value, isValid } = parseWidgetValue(values[newValueIndex], newWidget); |
|
|
if (isValid && value !== NaN) { |
|
|
newWidget.value = value; |
|
|
break; |
|
|
} |
|
|
newValueIndex += isIterateForwards ? 1 : -1; |
|
|
} |
|
|
|
|
|
if (isIterateForwards) { |
|
|
if (newValueIndex === valueIndex) { |
|
|
valueIndex++; |
|
|
} |
|
|
if (newValueIndex === valueIndex + 1) { |
|
|
valueIndex++; |
|
|
valueIndex++; |
|
|
} |
|
|
} else { |
|
|
if (newValueIndex === valueIndex) { |
|
|
valueIndex--; |
|
|
} |
|
|
if (newValueIndex === valueIndex - 1) { |
|
|
valueIndex--; |
|
|
valueIndex--; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
}; |
|
|
if (isIterateForwards) { |
|
|
for (let widgetIndex = 0; widgetIndex < newNode.widgets.length; widgetIndex++) { |
|
|
updateValue(widgetIndex); |
|
|
} |
|
|
} else { |
|
|
for (let widgetIndex = newNode.widgets.length - 1; widgetIndex >= 0; widgetIndex--) { |
|
|
updateValue(widgetIndex); |
|
|
} |
|
|
} |
|
|
} |
|
|
handleLinks(); |
|
|
|
|
|
newNode.setSize(options.size) |
|
|
newNode.onResize([0,0]); |
|
|
}; |