File size: 2,422 Bytes
d051564
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { tryToGetWorkflowDataFromEvent } from "rgthree/common/utils_workflow.js";
import { app } from "scripts/app.js";
import type { ComfyNode, ComfyNodeConstructor, ComfyObjectInfo } from "typings/comfy.js";
import { SERVICE as CONFIG_SERVICE } from "./services/config_service.js";

/**
 * Registers the GroupHeaderToggles which places a mute and/or bypass icons in groups headers for
 * quick, single-click ability to mute/bypass.
 */
app.registerExtension({
  name: "rgthree.ImportIndividualNodes",
  async beforeRegisterNodeDef(nodeType: ComfyNodeConstructor, nodeData: ComfyObjectInfo) {
    const onDragOver = nodeType.prototype.onDragOver;
    nodeType.prototype.onDragOver = function (e: DragEvent) {
      let handled = onDragOver?.apply?.(this, [...arguments] as any);
      if (handled != null) {
        return handled;
      }
      return importIndividualNodesInnerOnDragOver(this, e);
    };

    const onDragDrop = nodeType.prototype.onDragDrop;
    nodeType.prototype.onDragDrop = async function (e: DragEvent) {
      const alreadyHandled = await onDragDrop?.apply?.(this, [...arguments] as any);
      if (alreadyHandled) {
        return alreadyHandled;
      }
      return importIndividualNodesInnerOnDragDrop(this, e);
    };
  },
});

export function importIndividualNodesInnerOnDragOver(node: ComfyNode, e: DragEvent): boolean {
  return (
    (node.widgets?.length && !!CONFIG_SERVICE.getFeatureValue("import_individual_nodes.enabled")) ||
    false
  );
}

export async function importIndividualNodesInnerOnDragDrop(node: ComfyNode, e: DragEvent) {
  if (!node.widgets?.length || !CONFIG_SERVICE.getFeatureValue("import_individual_nodes.enabled")) {
    return false;
  }

  let handled = false;
  const { workflow, prompt } = await tryToGetWorkflowDataFromEvent(e);
  if (!handled && workflow) {
    const exact = (workflow.nodes || []).find((n) => n.id === node.id && n.type === node.type);
    if (
      exact &&
      exact.widgets_values?.length &&
      confirm(
        "Found a node match from embedded workflow (same id & type) in this workflow. Would you like to set the widget values?",
      )
    ) {
      node.configure({ widgets_values: [...(exact?.widgets_values || [])] } as any);
      handled = true;
    }
  }
  if (!handled) {
    handled = !confirm(
      "No exact match found in workflow. Would you like to replace the whole workflow?",
    );
  }
  return handled;
}