bizydraft 0.1.29__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bizydraft might be problematic. Click here for more details.

@@ -1,27 +1,50 @@
1
1
  import { app } from "../../scripts/app.js";
2
- import { fileToOss } from "./uploadFile.js";
3
- import { getCookie, hideWidget } from './tool.js';
2
+ import { getCookie, computeIsLoadNode, computeExt, hideWidget } from './tool.js';
3
+
4
4
 
5
5
  app.registerExtension({
6
6
  name: "bizyair.image.to.oss",
7
7
  async beforeRegisterNodeDef(nodeType, nodeData) {
8
- if (nodeData.name === 'LoadImage') {
9
- let workflowParams = null
10
- document.addEventListener('workflowLoaded', (event) => {
11
- workflowParams = event.detail;
8
+ let workflowParams = null
9
+ document.addEventListener('workflowLoaded', (event) => {
10
+ workflowParams = event.detail;
11
+ })
12
+ document.addEventListener('drop', (e) => {
13
+ e.preventDefault();
14
+ const files = e.dataTransfer.files;
15
+
16
+ Array.from(files).forEach((file) => {
17
+ if (file.type === 'application/json' || file.name.endsWith('.json')) {
18
+ const reader = new FileReader();
19
+ reader.onload = function(event) {
20
+ try {
21
+ const jsonContent = JSON.parse(event.target.result);
22
+ if (jsonContent && jsonContent.nodes) {
23
+ window.currentWorkflowData = jsonContent;
24
+ }
25
+ } catch (error) {
26
+ console.error('解析JSON文件失败:', error);
27
+ }
28
+ };
29
+ reader.readAsText(file);
30
+ }
12
31
  });
32
+ })
33
+ if (computeIsLoadNode(nodeData.name)) {
13
34
  nodeType.prototype.onNodeCreated = async function() {
14
- const image_widget = this.widgets.find(w => w.name === 'image');
15
- console.log(image_widget)
16
- // const apiHost = 'http://localhost:3000/api'
17
35
  const apiHost = 'https://bizyair.cn/api'
18
- const node = this;
36
+ const image_widget = this.widgets.find(w => {
37
+ return w.name === 'image'
38
+ || w.name === 'file'
39
+ || w.name === 'audio'
40
+ || w.name === 'model_file'
41
+ });
42
+ let image_name_widget = this.widgets.find(w => w.name === 'image_name');
19
43
  let image_list = []
20
44
  const getData = async () => {
21
45
  const res = await fetch(`${apiHost}/special/community/commit_input_resource?${
22
46
  new URLSearchParams({
23
- url: '',
24
- ext: '',
47
+ ext: computeExt(nodeData.name),
25
48
  current: 1,
26
49
  page_size: 100
27
50
 
@@ -38,96 +61,113 @@ app.registerExtension({
38
61
  image_list = list.filter(item => item.name).map(item => {
39
62
  return {
40
63
  url: item.url,
64
+ id: item.id,
41
65
  name: item.name
42
66
  }
43
- // return item.url
44
67
  })
45
- const image_widget = this.widgets.find(w => w.name === 'image');
46
-
47
-
48
- let image_path_widget = this.widgets.find(w => w.name === 'image_path');
49
- if (!image_path_widget) {
50
- image_path_widget = this.addWidget("text", "image_path", "", function(){}, {
51
- serialize: true
68
+ if (!image_name_widget) {
69
+ image_name_widget = this.addWidget("combo", "image_name", "", function(e){
70
+ const item = image_list.find(item => item.name === e)
71
+ const image_url = decodeURIComponent(item.url);
72
+ image_widget.value = image_url;
73
+ if (image_widget.callback) {
74
+ image_widget.callback(e);
75
+ }
76
+ }, {
77
+ serialize: true,
78
+ values: image_list.map(item => item.name)
52
79
  });
53
- image_path_widget.type = "hidden";
54
- // image_path_widget.style = "hidden";
55
- image_path_widget.computeSize = () => [0, 0]; // 隐藏显示
56
80
  }
57
- hideWidget(this, 'image_path')
81
+ const val = image_list.find(item => item.url === image_widget.value)?.name || image_widget.value
82
+ image_name_widget.label = image_widget.label
83
+ image_name_widget.value = val
58
84
 
59
- image_widget.options.values = image_list.map(item => item.name);
60
- // console.log(image_widget.value)
61
- // image_widget.value = image_list[0].url;
62
- // image_widget.value = image_list[0];
63
- if (image_list[0] && image_list[0].url) {
64
- image_widget.value = image_list[0].name
65
- const defaultImageUrl = decodeURIComponent(image_list[0].url);
66
- image_path_widget.value = defaultImageUrl;
67
-
68
- previewImage(node, defaultImageUrl)
85
+ const currentIndex = this.widgets.indexOf(image_name_widget);
86
+ if (currentIndex > 1) {
87
+ this.widgets.splice(currentIndex, 1);
88
+ this.widgets.splice(1, 0, image_name_widget);
69
89
  }
70
- image_widget.callback = function(e) {
71
- const image_url = decodeURIComponent(image_list.find(item => item.name === e).url);
72
- image_path_widget.value = image_url;
73
- previewImage(node, image_url)
90
+ hideWidget(this, image_widget.name)
91
+ image_widget.options.values = image_list.map(item => item.name);
92
+
93
+ const callback = image_widget.callback
94
+ image_widget.callback = async function(e) {
95
+ console.log(e)
96
+ if (typeof e == 'string') {
97
+ const item = e.includes('http') ?
98
+ image_list.find(item => item.url === e) :
99
+ image_list.find(item => item.name === e)
100
+
101
+ const image_url = item ? decodeURIComponent(item.url) : e;
102
+
103
+ image_name_widget.value = item ? item.name : e;
104
+ image_widget.value = image_url;
105
+ console.log('=================image_url=================')
106
+ console.log(image_url)
107
+ console.log(item)
108
+ console.log(await app.graphToPrompt())
109
+ callback([image_url])
110
+ console.log(await app.graphToPrompt())
111
+ } else {
112
+ const item = e[0].split('/')
113
+ image_name_widget.options.values.pop()
114
+ image_name_widget.options.values.push(item[item.length - 1])
115
+ image_name_widget.value = item[item.length - 1]
116
+ image_list.push({
117
+ name: item[item.length - 1],
118
+ url: e[0]
119
+ })
120
+ callback(e)
121
+ }
74
122
  }
75
123
  return true
76
124
  }
77
-
78
125
  await getData()
79
126
 
80
127
 
128
+ function applyWorkflowImageSettings(workflowParams, image_list, image_widget, image_name_widget) {
129
+ if (workflowParams && workflowParams.nodes) {
130
+ const imageNode = workflowParams.nodes.find(item => computeIsLoadNode(item.type))
131
+ if (imageNode && imageNode.widgets_values) {
132
+ const item = imageNode.widgets_values[0].split('/')
133
+ image_list.push({
134
+ name: item[item.length - 1],
135
+ url: imageNode.widgets_values[0]
136
+ })
137
+ image_widget.value = imageNode.widgets_values[0]
81
138
 
82
- if (workflowParams && workflowParams.json.nodes) {
83
- const imageNode = workflowParams.json.nodes.find(item => item.type === 'LoadImage')
84
- if (imageNode && imageNode.widgets_values && imageNode.widgets_values[2]) {
85
- const temp = {
86
- name: imageNode.widgets_values[0],
87
- url: imageNode.widgets_values[2]
139
+ image_widget.options.values = image_list.map(item => item.url)
140
+ image_name_widget.options.values = image_list.map(item => item.name)
141
+ image_widget.callback(imageNode.widgets_values[0])
88
142
  }
89
- image_list.push(temp)
90
- image_widget.value = temp.name
91
- image_widget.options.values = image_list.map(item => item.name)
92
- previewImage(node, temp.url)
93
-
94
- requestAnimationFrame(() => {
95
- previewImage(node, temp.url)
96
- })
97
143
  }
98
144
  }
99
- const upload_widget = this.widgets.find(w => w.name === 'upload');
100
- upload_widget.callback = async function() {
101
- const input = document.createElement('input');
102
- input.type = 'file';
103
- input.accept = 'image/*';
104
- input.onchange = async (e) => {
105
- const file = e.target.files[0];
106
- await fileToOss(file);
107
-
108
- getData()
109
- }
110
- input.click();
145
+
146
+ // 如果有存储的工作流数据,应用图像设置
147
+ if (window.currentWorkflowData) {
148
+ applyWorkflowImageSettings(window.currentWorkflowData, image_list, image_widget, image_name_widget);
149
+ // 清除存储的数据,避免重复处理
150
+ delete window.currentWorkflowData;
151
+ } else {
152
+ // 原有的调用
153
+ applyWorkflowImageSettings(workflowParams, image_list, image_widget, image_name_widget);
111
154
  }
155
+
156
+
112
157
  }
113
158
  }
114
159
  }
115
160
  })
116
161
 
117
- function previewImage(node, image_url) {
118
- const img = new Image();
119
- img.onload = function() {
120
- node.imgs = [img];
121
- if (node.graph && node.graph.setDirtyCanvas) {
122
- node.graph.setDirtyCanvas(true);
123
- } else {
124
- console.warn('[BizyAir] 无法访问graph对象进行重绘');
125
- }
126
-
127
- console.log('[BizyAir] 图片预览加载成功');
128
- };
129
- img.onerror = function(err) {
130
- console.error('[BizyAir] 图片加载失败:', image_url, err);
131
- };
132
- img.src = image_url;
133
- }
162
+ // app.api.addEventListener('graphChanged', (e) => {
163
+ // console.log('Graph 发生变化,当前 workflow JSON:', e.detail)
164
+ // window.parent.postMessage({
165
+ // type: 'functionResult',
166
+ // method: 'workflowChanged',
167
+ // result: e.detail
168
+ // }, '*');
169
+
170
+ // document.dispatchEvent(new CustomEvent('workflowLoaded', {
171
+ // detail: e.detail
172
+ // }));
173
+ // })
@@ -0,0 +1,152 @@
1
+ import { app } from "../../scripts/app.js";
2
+ import '../BizyAir/bizyair_frontend.js'
3
+ import { hideWidget } from './tool.js'
4
+ const possibleWidgetNames=[
5
+ "clip_name",
6
+ "clip_name1",
7
+ "clip_name2",
8
+ "ckpt_name",
9
+ "lora_name",
10
+ "control_net_name",
11
+ "ipadapter_file",
12
+ "unet_name",
13
+ "vae_name",
14
+ "model_name",
15
+ "instantid_file",
16
+ "pulid_file",
17
+ "style_model_name",
18
+ ]
19
+
20
+ // 根据节点名称匹配模型类型
21
+ function getModelTypeFromNodeName(nodeName) {
22
+ if (/bizyair/i.test(nodeName)) {
23
+ return null;
24
+ }
25
+
26
+ const regex = /^(\w+).*Loader.*/i;
27
+ const match = nodeName.match(regex);
28
+ if (match) {
29
+ return match[1];
30
+ }
31
+ return null;
32
+ }
33
+
34
+ function createSetWidgetCallback(modelType, selectedBaseModels = []) {
35
+ return function setWidgetCallback() {
36
+ const targetWidget = this.widgets.find(widget => possibleWidgetNames.includes(widget.name));
37
+ if (targetWidget) {
38
+ targetWidget.value = targetWidget.value || "to choose"
39
+ targetWidget.mouse = function(e, pos, canvas) {
40
+ try {
41
+ if (e.type === "pointerdown" || e.type === "mousedown" || e.type === "click" || e.type === "pointerup") {
42
+ e.preventDefault();
43
+ e.stopPropagation();
44
+ e.widgetClick = true;
45
+
46
+ const currentNode = this.node;
47
+
48
+ if (!currentNode || !currentNode.widgets) {
49
+ console.warn("Node or widgets not available");
50
+ return false;
51
+ }
52
+
53
+ if (typeof bizyAirLib !== 'undefined' && typeof bizyAirLib.showModelSelect === 'function') {
54
+ bizyAirLib.showModelSelect({
55
+ modelType: [modelType],
56
+ selectedBaseModels,
57
+ onApply: (version, model) => {
58
+ if (!currentNode || !currentNode.widgets) return;
59
+
60
+ const currentLora = currentNode.widgets.find(widget => possibleWidgetNames.includes(widget.name));
61
+ const currentModel = currentNode.widgets.find(w => w.name === "model_version_id");
62
+
63
+ if (model && currentModel && version) {
64
+ currentLora.value = model;
65
+ currentModel.value = version.id;
66
+ currentNode.setDirtyCanvas(true);
67
+ }
68
+ }
69
+ });
70
+ } else {
71
+ console.error("bizyAirLib not available");
72
+ }
73
+ return false;
74
+ }
75
+ } catch (error) {
76
+ console.error("Error handling mouse event:", error);
77
+ }
78
+ };
79
+
80
+ // targetWidget.node = this;
81
+ targetWidget.options = targetWidget.options || {};
82
+ targetWidget.options.values = () => [];
83
+ targetWidget.options.editable = false;
84
+ targetWidget.clickable = true;
85
+ targetWidget.processMouse = true;
86
+ }
87
+ }
88
+ }
89
+
90
+ function setupNodeMouseBehavior(node, modelType) {
91
+ hideWidget(node, "model_version_id");
92
+
93
+ // 只设置必要的状态信息,不修改onMouseDown(已在上面的扩展中处理)
94
+ if (!node._bizyairState) {
95
+ node._bizyairState = {
96
+ lastClickTime: 0,
97
+ DEBOUNCE_DELAY: 300,
98
+ modelType: modelType
99
+ };
100
+ }
101
+ }
102
+
103
+ app.registerExtension({
104
+ name: "bizyair.hook.load.model",
105
+ async beforeRegisterNodeDef(nodeType, nodeData, app) {
106
+
107
+ localStorage.removeItem('workflow')
108
+ sessionStorage.clear()
109
+ const interval = setInterval(() => {
110
+ if (window.switchLanguage) {
111
+ window.switchLanguage('zh')
112
+ clearInterval(interval)
113
+ }
114
+ }, 100)
115
+
116
+ const modelType = getModelTypeFromNodeName(nodeData.name);
117
+ if (modelType) {
118
+ const onNodeCreated = nodeType.prototype.onNodeCreated;
119
+ nodeType.prototype.onNodeCreated = function() {
120
+ try {
121
+ let model_version_id = this.widgets.find(w => w.name === "model_version_id");
122
+ if (!model_version_id) {
123
+ model_version_id = this.addWidget("hidden", "model_version_id", "", function(e){
124
+ console.log(e)
125
+ }, {
126
+ serialize: true,
127
+ values: []
128
+ });
129
+ }
130
+ console.log(model_version_id)
131
+ const result = onNodeCreated?.apply(this, arguments);
132
+ let selectedBaseModels = [];
133
+ // if (modelType === 'Checkpoint') {
134
+ // selectedBaseModels = ['SDXL', 'Pony', 'SD 3.5', 'Illustrious']
135
+ // }
136
+ createSetWidgetCallback(modelType, selectedBaseModels).call(this);
137
+ return result;
138
+ } catch (error) {
139
+ console.error("Error in node creation:", error);
140
+ }
141
+ };
142
+ }
143
+ },
144
+
145
+ async nodeCreated(node) {
146
+ const modelType = getModelTypeFromNodeName(node?.comfyClass);
147
+
148
+ if (modelType) {
149
+ setupNodeMouseBehavior(node, modelType);
150
+ }
151
+ }
152
+ })
@@ -1,5 +1,4 @@
1
1
  // 主入口文件,导入所有模块
2
2
  import "./hookLoadImage.js";
3
- import "./hookSaveImage.js";
4
3
  import "./postEvent.js";
5
4
  import "./handleStyle.js";
@@ -0,0 +1,153 @@
1
+ import { app } from "../../scripts/app.js";
2
+
3
+ // 全局变量引用(从aiAppHandler.js中引用)
4
+ let freezeOverlay = null;
5
+ let globalEventBlocked = false;
6
+ let keyboardListener = null;
7
+ let contextMenuListener = null;
8
+
9
+ // 设置全局变量引用
10
+ export function setGlobalReferences(overlay, eventBlocked, kListener, cListener) {
11
+ freezeOverlay = overlay;
12
+ globalEventBlocked = eventBlocked;
13
+ keyboardListener = kListener;
14
+ contextMenuListener = cListener;
15
+ }
16
+
17
+ // 只聚焦节点,不高亮
18
+ export function focusNodeOnly(nodeId) {
19
+ console.log('[nodeFocusHandler] focusNodeOnly called with nodeId:', nodeId);
20
+
21
+ if (!app || !app.graph) {
22
+ console.error('[nodeFocusHandler] app or app.graph not available');
23
+ return false;
24
+ }
25
+
26
+ const node = app.graph.getNodeById(parseInt(nodeId, 10));
27
+ if (!node) {
28
+ console.error('[nodeFocusHandler] 找不到节点:', nodeId);
29
+ return false;
30
+ }
31
+
32
+ console.log('[nodeFocusHandler] 找到节点:', node);
33
+
34
+ // 临时禁用冻结模式
35
+ const wasFreezed = !!freezeOverlay;
36
+ let originalOverlayDisplay = null;
37
+
38
+ if (wasFreezed && freezeOverlay) {
39
+ originalOverlayDisplay = freezeOverlay.style.display;
40
+ freezeOverlay.style.display = 'none';
41
+
42
+ // 临时解除事件阻止
43
+ if (globalEventBlocked) {
44
+ document.removeEventListener('keydown', keyboardListener, true);
45
+ document.removeEventListener('contextmenu', contextMenuListener, true);
46
+ }
47
+ }
48
+
49
+ // 只设置节点的 selected 属性,不改变颜色
50
+ for (const n of app.graph._nodes) {
51
+ n.selected = n.id === node.id;
52
+ }
53
+
54
+ // 设置 selected_nodes
55
+ if (app.canvas) {
56
+ app.canvas.selected_nodes = [node];
57
+ }
58
+
59
+ // 聚焦到节点 - 使用与selectNodeAndFocus相同的方法
60
+ if (app.canvas && typeof app.canvas.centerOnNode === 'function') {
61
+ console.log('[nodeFocusHandler] 使用 centerOnNode 方法聚焦节点');
62
+ app.canvas.centerOnNode(node);
63
+ }
64
+
65
+ // 刷新画布
66
+ if (app.canvas) {
67
+ app.canvas.setDirty(true, true);
68
+ if (typeof app.canvas.draw === 'function') {
69
+ app.canvas.draw(true, true);
70
+ }
71
+ }
72
+
73
+ // 恢复冻结模式
74
+ setTimeout(() => {
75
+ if (wasFreezed && freezeOverlay) {
76
+ freezeOverlay.style.display = originalOverlayDisplay;
77
+
78
+ // 恢复事件阻止
79
+ if (globalEventBlocked) {
80
+ document.addEventListener('keydown', keyboardListener, true);
81
+ document.addEventListener('contextmenu', contextMenuListener, true);
82
+ }
83
+ }
84
+
85
+ // 再次刷新画布
86
+ if (app.canvas) {
87
+ app.canvas.setDirty(true, true);
88
+ if (typeof app.canvas.draw === 'function') {
89
+ app.canvas.draw(true, true);
90
+ }
91
+ }
92
+ }, 100);
93
+
94
+ console.log('[nodeFocusHandler] focusNodeOnly 完成');
95
+ return true;
96
+ }
97
+
98
+ // 处理画布节点点击事件
99
+ export function handleCanvasNodeClick(e) {
100
+ if (!app || !app.graph) return;
101
+
102
+ // 获取点击的节点
103
+ const nodeUnderMouse = getNodeUnderMouse(e);
104
+ if (!nodeUnderMouse) return;
105
+
106
+ console.log('[nodeFocusHandler] 画布点击节点:', nodeUnderMouse.id, nodeUnderMouse.title);
107
+
108
+ // 发送消息到前端,通知节点被点击
109
+ window.parent.postMessage({
110
+ type: 'CANVAS_NODE_CLICKED',
111
+ nodeId: nodeUnderMouse.id,
112
+ nodeTitle: nodeUnderMouse.title,
113
+ nodeType: nodeUnderMouse.type
114
+ }, '*');
115
+ }
116
+
117
+ // 获取鼠标下方的节点
118
+ function getNodeUnderMouse(e) {
119
+ if (!app || !app.graph) return null;
120
+
121
+ // 获取画布位置
122
+ const canvas = document.querySelector('canvas');
123
+ if (!canvas) return null;
124
+
125
+ // 转换为图形坐标
126
+ const pos = app.canvas.convertEventToCanvasOffset(e);
127
+
128
+ // 检查点击位置是否在某个节点上
129
+ const node = app.graph.getNodeOnPos(pos[0], pos[1]);
130
+ return node;
131
+ }
132
+
133
+ // 设置画布点击事件监听
134
+ export function setupCanvasClickHandler() {
135
+ // 移除现有的事件监听器
136
+ removeCanvasClickHandler();
137
+
138
+ // 添加画布点击事件监听
139
+ const canvas = document.querySelector('canvas');
140
+ if (canvas) {
141
+ canvas.addEventListener('click', handleCanvasNodeClick);
142
+ console.log('[nodeFocusHandler] 画布点击事件监听器已设置');
143
+ }
144
+ }
145
+
146
+ // 移除画布点击事件监听
147
+ export function removeCanvasClickHandler() {
148
+ const canvas = document.querySelector('canvas');
149
+ if (canvas) {
150
+ canvas.removeEventListener('click', handleCanvasNodeClick);
151
+ console.log('[nodeFocusHandler] 画布点击事件监听器已移除');
152
+ }
153
+ }