diff --git a/javascript/plugins/sd-ppp_PS.ccx b/javascript/plugins/sd-ppp_PS.ccx index 4ca0837..04267c4 100644 Binary files a/javascript/plugins/sd-ppp_PS.ccx and b/javascript/plugins/sd-ppp_PS.ccx differ diff --git a/javascript/sdppp-comfy.js b/javascript/sdppp-comfy.js index f32da4d..b0b868f 100644 --- a/javascript/sdppp-comfy.js +++ b/javascript/sdppp-comfy.js @@ -28,14 +28,17 @@ }); socket.on('connect', () => { - socket.emit('reset_changes'); + socket.emit('c_reset_changes'); }); socket.on('disconnect', () => { }); socket.on('connect_error', () => { console.error('sdppp socket connect_error') }); - socket.on('trigger_graph_change', () => { + socket.on('s_run', () => { + document.getElementById('queue-button').click() + }); + socket.on('s_trigger_graph_change', () => { api.dispatchEvent(new CustomEvent("graphChanged")); }); setInterval(() => { @@ -93,9 +96,9 @@ const mode0NodeTypes = currentState.nodes.filter(node => node.mode == 0).map(node => node.type); const containsSDPPPNodes = mode0NodeTypes.some(nodeType => SDPPPNodes.includes(nodeType)); if (!containsSDPPPNodes) return; - socket.emit('check_changes') + socket.emit('c_check_changes') } catch (e) { console.error("[sd-ppp]", "Failed to check changes", e); } } -})(); \ No newline at end of file +})(); diff --git a/javascript/sdppp-sd.js b/javascript/sdppp-sd.js index e9cd0e6..53acdb1 100644 --- a/javascript/sdppp-sd.js +++ b/javascript/sdppp-sd.js @@ -23,6 +23,10 @@ this.$refreshSendLayer = null; this.$getterSaveAndClose = null; this.$senderSaveAndClose = null; + + setTimeout(()=> { + this.initSocket(); + }) } initDOM() { @@ -110,6 +114,13 @@ this.socket.on('disconnect', () => { this.socketInited = false; }); + this.socket.on('s_run', () => { + const tab = document.getElementById('tabs').querySelector('button.selected'); + const activeTabIndex = Array.prototype.indexOf.call(tab.parentElement.children, tab) + if (activeTabIndex == 0) document.getElementById('txt2img_generate').click() + if (activeTabIndex == 1) document.getElementById('img2img_generate').click() + if (activeTabIndex == 2) document.getElementById('extras_generate').click() + }); }); } @@ -294,4 +305,4 @@ insertedSendWidget.set(el, widget); }) }) -})(); \ No newline at end of file +})(); diff --git a/photoshop/dist/index.js b/photoshop/dist/index.js index ead9e81..2dbbf29 100644 --- a/photoshop/dist/index.js +++ b/photoshop/dist/index.js @@ -90,14 +90,16 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../system/ComfyConnection */ "./src/system/ComfyConnection.js"); /* harmony import */ var uxp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! uxp */ "uxp"); /* harmony import */ var uxp__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(uxp__WEBPACK_IMPORTED_MODULE_2__); +function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } class Main extends react__WEBPACK_IMPORTED_MODULE_0__.Component { state = { - comfyURL: '', + backendURL: '', isConnected: false, - isReconnecting: false + isReconnecting: false, + pageInstances: [] }; componentDidMount() { _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].onConnectStateChange(() => { @@ -106,34 +108,45 @@ class Main extends react__WEBPACK_IMPORTED_MODULE_0__.Component { this.setState({ isConnected: instance?.isConnected, isReconnecting: instance?.isReconnecting, - comfyURL: instance ? instance.comfyURL : '' + backendURL: instance ? instance.backendURL : '' }); }); - uxp__WEBPACK_IMPORTED_MODULE_2__.storage.secureStorage.getItem('comfyURL').then(value => { + _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].onPageInstancesChange(data => { + this.setState({ + pageInstances: data.pages || [] + }); + }); + uxp__WEBPACK_IMPORTED_MODULE_2__.storage.secureStorage.getItem('backendURL').then(value => { if (!value) return; this.setState({ - comfyURL: Buffer.from(value).toString() + backendURL: Buffer.from(value).toString() }); - if (this.state.comfyURL) { - console.log('comfyURL:', this.state.comfyURL); + if (this.state.backendURL) { + console.log('backendURL:', this.state.backendURL); this.doConnectOrDisconnect(); } }); } doConnectOrDisconnect() { - console.log(_system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance?.isConnected, _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance?.isReconnecting); - if (_system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance?.isConnected || _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance?.isReconnecting) _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance.disconnect();else _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].createInstance(this.state.comfyURL); + if (_system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance?.isConnected || _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance?.isReconnecting) _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance.disconnect();else _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].createInstance(this.state.backendURL); } render() { - return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("sp-textfield", { + let inputDisable = {}; + if (this.state.isConnected || this.state.isReconnecting) inputDisable = { + disabled: true + }; + console.log(this.state.backendURL); + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("sp-textfield", _extends({ id: "url-bar", - label: "ComfyURL", + label: "backendURL", onInput: ev => { - this.state.comfyURL = ev.currentTarget.value; - }, - value: this.state.comfyURL, + console.log('onInput', ev.currentTarget.value); + this.state.backendURL = ev.currentTarget.value; + } + }, inputDisable, { + value: this.state.backendURL, placeholder: "http://127.0.0.1:8188" - }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { + })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "connect-box" }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { className: "status-bar " + (this.state.isConnected ? 'connected' : this.state.isReconnecting ? 'reconnecting' : 'disconnected') @@ -147,7 +160,20 @@ class Main extends react__WEBPACK_IMPORTED_MODULE_0__.Component { onClick: this.doConnectOrDisconnect.bind(this) }, this.state.isConnected || this.state.isReconnecting ? 'disconnect' : 'connect')), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("sp-divider", { size: "small" - })); + }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("sp-label", null, "webpage-list"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("ul", { + className: "client-list" + }, this.state.pageInstances.map(item => { + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("li", { + key: item, + className: "client-list-item" + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("sp-label", { + class: "client-name" + }, item.slice(0, 6)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("sp-link", { + onClick: () => { + _system_ComfyConnection__WEBPACK_IMPORTED_MODULE_1__["default"].instance?.pageInstanceRun(item); + } + }, "Run")); + }))); } } @@ -196,11 +222,24 @@ class ComfyConnection { } }); } - static createInstance(comfyURL) { + static _pageInstancesCallbacks = []; + static onPageInstancesChange(callback) { + ComfyConnection._pageInstancesCallbacks.push(callback); + } + static _callPageInstancesChange(data) { + ComfyConnection._pageInstancesCallbacks.forEach(cb => { + try { + cb(data); + } catch (e) { + console.error(e); + } + }); + } + static createInstance(backendURL) { if (ComfyConnection.instance) { ComfyConnection.instance.disconnect(); } - ComfyConnection.instance = new ComfyConnection(comfyURL); + ComfyConnection.instance = new ComfyConnection(backendURL); } get isConnected() { return this.socket != null && this.socket.connected === true; @@ -208,12 +247,12 @@ class ComfyConnection { get isReconnecting() { return this.socket != null && this.socket.connected === false && this.socket.active === true; } - comfyURL = ''; + backendURL = ''; serverType = ''; interval = null; - constructor(comfyURL) { + constructor(backendURL) { ComfyConnection.instance = this; - this.comfyURL = comfyURL.replace(/\/*$/, ''); + this.backendURL = backendURL.replace(/\/*$/, ''); this.connect(); } connect() { @@ -231,8 +270,8 @@ class ComfyConnection { } } _createSocket() { - console.log('create socket'); - const socket = this.socket = _library_socket_io_js__WEBPACK_IMPORTED_MODULE_3___default()(this.comfyURL, { + console.log('create socket', this.backendURL); + const socket = this.socket = _library_socket_io_js__WEBPACK_IMPORTED_MODULE_3___default()(this.backendURL, { autoConnect: false, transports: ["websocket"], path: '/sd-ppp/', @@ -258,7 +297,7 @@ class ComfyConnection { }); socket.on('connect', () => { console.log('connect'); - uxp__WEBPACK_IMPORTED_MODULE_1__.storage.secureStorage.setItem('comfyURL', this.comfyURL); + uxp__WEBPACK_IMPORTED_MODULE_1__.storage.secureStorage.setItem('backendURL', this.backendURL); ComfyConnection._callConnectStateChange(); }); socket.on('disconnect', (...args) => { @@ -268,7 +307,7 @@ class ComfyConnection { socket.on('get_image', async (data, callback) => { try { const startTime = Date.now(); - const result = await (0,_events_get_image__WEBPACK_IMPORTED_MODULE_5__["default"])(this.comfyURL, Object.assign(data, { + const result = await (0,_events_get_image__WEBPACK_IMPORTED_MODULE_5__["default"])(this.backendURL, Object.assign(data, { isComfy: this.serverType == "comfy" })); console.log('get_image cost', Date.now() - startTime, 'ms'); @@ -282,7 +321,7 @@ class ComfyConnection { }); socket.on('send_images', async (data, callback) => { try { - const result = await (0,_events_send_images__WEBPACK_IMPORTED_MODULE_4__["default"])(this.comfyURL, Object.assign(data, { + const result = await (0,_events_send_images__WEBPACK_IMPORTED_MODULE_4__["default"])(this.backendURL, Object.assign(data, { isComfy: this.serverType == "comfy" })); callback(result); @@ -307,6 +346,16 @@ class ComfyConnection { socket.on('s_confirm', data => { this.serverType = data.server_type; }); + setInterval(() => { + socket.emit('b_get_pages', data => { + ComfyConnection._callPageInstancesChange(data); + }); + }, 1500); + } + pageInstanceRun(sid) { + this.socket.emit('b_page_run', { + sid + }); } } /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ComfyConnection); diff --git a/photoshop/src/panels/Main.jsx b/photoshop/src/panels/Main.jsx index 385af77..6b369d2 100644 --- a/photoshop/src/panels/Main.jsx +++ b/photoshop/src/panels/Main.jsx @@ -3,9 +3,10 @@ import ComfyConnection from "../system/ComfyConnection"; import { storage } from "uxp"; export default class Main extends React.Component { state = { - comfyURL: '', + backendURL: '', isConnected: false, isReconnecting: false, + pageInstances: [] } componentDidMount() { @@ -15,68 +16,80 @@ export default class Main extends React.Component { this.setState({ isConnected: instance?.isConnected, isReconnecting: instance?.isReconnecting, - comfyURL: instance ? instance.comfyURL : '' + backendURL: instance ? instance.backendURL : '' }) }); - storage.secureStorage.getItem('comfyURL').then((value) => { + ComfyConnection.onPageInstancesChange((data) => { + this.setState({ pageInstances: data.pages || [] }); + }); + storage.secureStorage.getItem('backendURL').then((value) => { if (!value) return - this.setState({ comfyURL: Buffer.from(value).toString() }) - if (this.state.comfyURL) { - console.log('comfyURL:', this.state.comfyURL) + this.setState({ backendURL: Buffer.from(value).toString() }) + if (this.state.backendURL) { + console.log('backendURL:', this.state.backendURL) this.doConnectOrDisconnect() } }) } doConnectOrDisconnect() { - console.log(ComfyConnection.instance?.isConnected, ComfyConnection.instance?.isReconnecting) - if (ComfyConnection.instance?.isConnected || ComfyConnection.instance?.isReconnecting) + if (ComfyConnection.instance?.isConnected || ComfyConnection.instance?.isReconnecting) ComfyConnection.instance.disconnect(); - else - ComfyConnection.createInstance(this.state.comfyURL); + else + ComfyConnection.createInstance(this.state.backendURL); } render() { + let inputDisable = { }; + if (this.state.isConnected || this.state.isReconnecting) inputDisable = { disabled: true }; + console.log(this.state.backendURL) return ( - <> - { this.state.comfyURL = ev.currentTarget.value }} - value={this.state.comfyURL} + <> + { console.log('onInput', ev.currentTarget.value); this.state.backendURL = ev.currentTarget.value }} + {...inputDisable} + value={this.state.backendURL} placeholder="http://127.0.0.1:8188" >
+ ) + )}>
⬤
{( this.state.isConnected ? 'connected' : ( this.state.isReconnecting ? 'reconnecting...' : - 'disconnected' + 'disconnected' ) )}
- {this.state.isConnected || this.state.isReconnecting ? 'disconnect' : 'connect'} -
+ - {/* webpage-list + webpage-list */} + { + this.state.pageInstances.map((item) => { + return ( +
  • + {item.slice(0, 6)} + { ComfyConnection.instance?.pageInstanceRun(item) }}>Run +
  • + ) + }) + } + ) } diff --git a/photoshop/src/system/ComfyConnection.js b/photoshop/src/system/ComfyConnection.js index 9a77b6b..72d5af3 100644 --- a/photoshop/src/system/ComfyConnection.js +++ b/photoshop/src/system/ComfyConnection.js @@ -21,11 +21,23 @@ class ComfyConnection { }); } - static createInstance(comfyURL) { + static _pageInstancesCallbacks = []; + static onPageInstancesChange(callback) { + ComfyConnection._pageInstancesCallbacks.push(callback); + } + static _callPageInstancesChange(data) { + ComfyConnection._pageInstancesCallbacks.forEach(cb => { + try { + cb(data) + } catch (e) { console.error(e) } + }); + } + + static createInstance(backendURL) { if (ComfyConnection.instance) { ComfyConnection.instance.disconnect(); } - ComfyConnection.instance = new ComfyConnection(comfyURL); + ComfyConnection.instance = new ComfyConnection(backendURL); } get isConnected() { @@ -35,12 +47,12 @@ class ComfyConnection { return this.socket != null && this.socket.connected === false && this.socket.active === true; } - comfyURL = ''; + backendURL = ''; serverType = ''; interval = null; - constructor(comfyURL) { + constructor(backendURL) { ComfyConnection.instance = this; - this.comfyURL = comfyURL.replace(/\/*$/, ''); + this.backendURL = backendURL.replace(/\/*$/, ''); this.connect(); } connect() { @@ -49,19 +61,19 @@ class ComfyConnection { } this.socket.connect(); } - + disconnect() { console.log('disconnect' + this.socket); if (this.socket) { this.socket.close() - this.socket = null; + this.socket = null; ComfyConnection._callConnectStateChange(); } } _createSocket() { - console.log('create socket') - const socket = this.socket = socketio(this.comfyURL, { + console.log('create socket', this.backendURL) + const socket = this.socket = socketio(this.backendURL, { autoConnect: false, transports: ["websocket"], path: '/sd-ppp/', @@ -72,7 +84,7 @@ class ComfyConnection { }); this.interval = setInterval(() => { if (!this.isConnected) return; - const allLayers = getAllSubLayer(app.activeDocument); + const allLayers = getAllSubLayer(app.activeDocument); this.socket.emit('b_sync_layers', { layers: allLayers } ) @@ -88,7 +100,7 @@ class ComfyConnection { }); socket.on('connect', () => { console.log('connect') - storage.secureStorage.setItem('comfyURL', this.comfyURL); + storage.secureStorage.setItem('backendURL', this.backendURL); ComfyConnection._callConnectStateChange(); }); socket.on('disconnect', (...args) => { @@ -99,14 +111,14 @@ class ComfyConnection { socket.on('get_image', async (data, callback) => { try { const startTime = Date.now(); - const result = await getImage(this.comfyURL, Object.assign(data, { isComfy: this.serverType == "comfy" })) + const result = await getImage(this.backendURL, Object.assign(data, { isComfy: this.serverType == "comfy" })) console.log('get_image cost', Date.now() - startTime, 'ms'); callback(result) } catch (e) { console.error(e); callback({ error: e.message }) } }) socket.on('send_images', async (data, callback) => { try { - const result = await sendImages(this.comfyURL, Object.assign(data, { isComfy: this.serverType == "comfy" })) + const result = await sendImages(this.backendURL, Object.assign(data, { isComfy: this.serverType == "comfy" })) callback(result) } catch (e) { console.error(e); callback({ error: e.message }) } }) @@ -118,7 +130,16 @@ class ComfyConnection { }) socket.on('s_confirm', (data) => { this.serverType = data.server_type - }) + }) + setInterval(() => { + socket.emit('b_get_pages', (data) => { + ComfyConnection._callPageInstancesChange(data); + }) + }, 1500); + } + + pageInstanceRun(sid) { + this.socket.emit('b_page_run', { sid }); } } diff --git a/sdppp_python/apis.py b/sdppp_python/apis.py index 01e4ddf..a53082c 100644 --- a/sdppp_python/apis.py +++ b/sdppp_python/apis.py @@ -65,6 +65,7 @@ def registerSDHTTPEndpoints(sdppp, app): return {'name': name} def registerSocketEvents(sdppp, sio): + # only emit by web instance @sio.event async def c_get_image(sid, data={}): if not sdppp.has_ps_instance(): @@ -82,6 +83,7 @@ def registerSocketEvents(sdppp, sio): addImageCache(res, sd_elem_id) return {} + # only emit by web instance @sio.event async def c_send_image(sid, data={}): if not sdppp.has_ps_instance(): @@ -101,6 +103,7 @@ def registerSocketEvents(sdppp, sio): image_ids = [load_image(image_url) for image_url in image_urls] await photoshopInstance.send_images(layer_id=layer_id, image_ids=image_ids) + # only emit by web instance @sio.event async def c_get_layers(sid, data = {}): if not sdppp.has_ps_instance(): @@ -124,6 +127,25 @@ def registerSocketEvents(sdppp, sio): return instance.layers = data['layers'] + # only emit by photoshop instance + @sio.event + async def b_get_pages(sid, data = {}): + pages = [] + if sdppp.server_type == "comfy": + pages = list(sdppp.comfyui_instances.keys()) + elif sdppp.server_type == "SD": + pages = list(sdppp.sd_instances.keys()) + + pages.reverse() + return { + 'pages': pages + } + + # only emit by photoshop instance + @sio.event + async def b_page_run(sid, data = {}): + await sdppp.sio.emit('s_run', to=data['sid']) + @sio.event async def check_changes(sid): instance = sdppp.get_ps_instance() @@ -131,11 +153,11 @@ def registerSocketEvents(sdppp, sio): return if not await instance.is_ps_history_changed(): return - await sio.emit('trigger_graph_change', to=sid) + await sio.emit('s_trigger_graph_change', to=sid) @sio.event async def reset_changes(sid): instance = sdppp.get_ps_instance() if instance is None: return - instance.reset_change_tracker() \ No newline at end of file + instance.reset_change_tracker()