diff --git a/flow/constants.py b/flow/constants.py index 0b9be6a..ba96140 100644 --- a/flow/constants.py +++ b/flow/constants.py @@ -3,7 +3,7 @@ from pathlib import Path import re APP_NAME = "Flow" -APP_VERSION = "0.4.6" +APP_VERSION = "0.4.7" FLOWMSG = f"\033[38;5;129mFlow - {APP_VERSION}\033[0m" APP_CONFIGS = [] diff --git a/flow/route_manager.py b/flow/route_manager.py index 6a8c867..506465f 100644 --- a/flow/route_manager.py +++ b/flow/route_manager.py @@ -1,5 +1,3 @@ -# flow/route_manager.py - from aiohttp import web from pathlib import Path diff --git a/pyproject.toml b/pyproject.toml index 05261c6..d9f4e70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-disty-flow" description = "Flow is a custom node designed to provide a more user-friendly interface for ComfyUI by acting as an alternative user interface for running workflows. It is not a replacement for workflow creation.\nFlow is currently in the early stages of development, so expect bugs and ongoing feature enhancements. With your support and feedback, Flow will settle into a steady stream." -version = "0.4.6" +version = "0.4.7" license = {file = "LICENSE"} [project.urls] diff --git a/web/core/css/main.css b/web/core/css/main.css index 0b65ae5..d816650 100644 --- a/web/core/css/main.css +++ b/web/core/css/main.css @@ -2279,4 +2279,181 @@ html:not(.css-loading) body { padding: 10px; border: 1px dashed var(--color-border); background-color: var(--color-background-secondary); - } */ \ No newline at end of file + } */ + +.toggle-component-wrapper { + display: flex; + align-items: center; + /* margin: 0.5em; */ + width: 100%; + background-color: var(--color-background-secondary); + margin-bottom: 0.5em; + /* padding: 6px 0; */ + height: 100%; +} + +.toggle-label-container { + display: flex; + align-items: center; + margin-left: 4px; + flex: 1; + min-width: 100px; + /* background: red; */ + font-weight: bold; + + +} + +.toggle-label-container img.toggle-icon { + width: 1em; + height: 1em; + /* margin-right: 0.5em; */ + +} + +.toggle-label-container .toggle-label { + /* font-size: 1em; */ + white-space: nowrap; + +} + +.toggle-component { + position: relative; + /* flex-shrink: 0; */ + /* padding: 0; */ + + /* background: blue; */ + display: flex; + height: 100%; + padding: 6px 0; + padding-left: 10px ; + + + +} +.toggle-component:hover { + cursor: pointer; + background-color: var(--color-background); +} +.toggle, .toggle:before, .slot__label, .curtain { + transition-property: background-color, transform, visibility; + transition-duration: 0.25s; + transition-timing-function: ease-in, cubic-bezier(0.6,0.2,0.4,1.5), linear; + +} +.toggle:before, .slot, .slot__label { + display: block; + +} +.toggle:before, .curtain { + position: absolute; + +} + +.toggle:checked, .curtain { + +} + +.toggle:focus { + outline: transparent; + +} + +.toggle { + width: 0.9em; + height: 1em; + border-radius: 50%; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-tap-highlight-color: transparent; + vertical-align: middle; + /* margin-right: 0.15em; */ + /* Start as a hollow circle to simulate no "O" when off */ + background: transparent; + border: 0.25em solid var(--color-primary-text); + position: relative; + cursor: pointer; + user-select: none; + vertical-align: middle; + +} + +.toggle:before { + content: none; +} + +.toggle:checked { + /* background: #2b7f3a; */ + /* border-color: #2b7f3a; */ + /* background: transparent; */ + border-color: var(--color-button-secondary-text); + +} + +.slot { + display: inline-block; + vertical-align: middle; + font-size: 17px; + /* letter-spacing: 0.2em; */ + line-height: 1em; + overflow: hidden; + height: 1em; + /* text-indent: -0.8em; */ + /* -webkit-text-stroke: 0.03em #fff; */ + user-select: none; + font-weight: bold; + padding-right: 6px; + color: var(--color-primary-text); +} + +.slot__label { + transform-origin: 50% 0; + /* color: red; */ + /* background: green; */ + letter-spacing: 0.2em; + line-height: 0.8em; + overflow: hidden; + height: 1em; + text-indent: -0.8em; + + +} + +.slot__label:nth-child(2) { + transform-origin: 50% 100%; +} + +.toggle:checked ~ .slot .slot__label { + transform: translateY(-50%) scaleY(0); + color: var(--color-button-secondary-text); + +} + +.toggle:checked ~ .slot .slot__label:nth-child(2) { + transform: translateY(-100%) scaleY(1); +} +.curtain { + transform: scaleX(0); + transform-origin: 0 50%; + z-index: -1; + width: 100%; + height: 100%; + top: 0; + left: 0; +} + + +.toggle:checked ~ .curtain { + transform: scaleX(1); +} + +@media (max-width: 600px) { + .toggle-component-wrapper { + max-width: 100%; + } + .toggle-label-container { + flex: none; + min-width: 80px; + } +} diff --git a/web/core/js/common/components/ToggleComponent.js b/web/core/js/common/components/ToggleComponent.js index d21c0ed..386350b 100644 --- a/web/core/js/common/components/ToggleComponent.js +++ b/web/core/js/common/components/ToggleComponent.js @@ -15,36 +15,46 @@ class ToggleComponent { ...config }; this.workflow = workflow; - this.value = this.config.defaultValue; + this.value = typeof this.config.defaultValue === "boolean" + ? (this.config.defaultValue ? 1 : 0) + : (this.config.defaultValue === "true" ? 1 : 0); + + console.log("ToggleComponent", this.value, this.config.id, this.config.defaultValue); this.buildUI(); this.initializeUI(); } buildUI() { + const toggleId = `${this.config.id}Toggle`; + const html = `
${this.config.labelPosition === 'left' ? this.getLabelHTML() : ''}
-
${this.config.labelPosition === 'right' ? this.getLabelHTML() : ''}
`; this.container.innerHTML = html; - this.inputElement = document.getElementById(`${this.config.id}Toggle`); - this.labelElement = this.container.querySelector('.toggle-label'); + this.inputElement = this.container.querySelector(`#${toggleId}`); + this.labelElement = this.container.querySelector('.toggle-label-container'); this.attachEventListeners(); } @@ -65,7 +75,7 @@ class ToggleComponent { } updateValue(newValue) { - this.value = newValue; + this.value = newValue ? 1 : 0; this.updateDisplay(); this.updateExternalConfig(); } @@ -99,7 +109,6 @@ class ToggleComponent { target[pathParts[pathParts.length - 1]] = this.value; } - attachEventListeners() { if (this.inputElement) { this.inputElement.addEventListener('change', (event) => { diff --git a/web/core/js/common/scripts/templates.js b/web/core/js/common/scripts/templates.js index 845e97a..43bba64 100644 --- a/web/core/js/common/scripts/templates.js +++ b/web/core/js/common/scripts/templates.js @@ -924,5 +924,32 @@ const componentTemplates = { } } }, + Toggle_ON : { + type: 'component', + nodeClass: null, + component: { + type: 'Toggle', + params: { + label: 'Prompt', + defaultValue: true, + nodePath: '{nodeId}.inputs.boolean', + } + } + }, + + Toggle_OFF : { + type: 'component', + nodeClass: null, + component: { + type: 'toggle', + params: { + label: 'Toggle', + defaultValue: false, + nodePath: '{nodeId}.inputs.boolean', + } + } + }, + }; + export { componentTemplates }; diff --git a/web/core/js/common/scripts/ui_utils.js b/web/core/js/common/scripts/ui_utils.js index 6342c6e..ce01a25 100644 --- a/web/core/js/common/scripts/ui_utils.js +++ b/web/core/js/common/scripts/ui_utils.js @@ -53,7 +53,7 @@ const addWidgetMenuRight = (menuRight) => { const flowButton = createWidget({ className: 'comfyui-button comfyui-menu-mobile-collapse primary', text: '', - tooltip: 'Start Flow', + tooltip: 'Launch Flow', includeIcon: true, svgMarkup: getFlowIcon(), });