move to react
This commit is contained in:
@@ -0,0 +1 @@
|
||||
**/node_modules/*
|
||||
+56
-19
@@ -6,34 +6,71 @@ import requests
|
||||
from zipfile import ZipFile
|
||||
import requests
|
||||
|
||||
WEB_DIRECTORY = 'javascript'
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
def transform_css_to_js(css_content):
|
||||
js_content = """
|
||||
var docStyle = document.createElement('style');
|
||||
docStyle.innerHTML = `""" + css_content.replace('`', r'\`').replace('\\', r'\\') + """
|
||||
`;
|
||||
document.head.appendChild(docStyle);
|
||||
"""
|
||||
return js_content
|
||||
|
||||
def transform_files_in_folder(folder_path):
|
||||
for filename in os.listdir(folder_path):
|
||||
if filename.endswith(".css"):
|
||||
css_file_path = os.path.join(folder_path, filename)
|
||||
js_file_path = os.path.join(folder_path, filename[:-4] + ".css.js")
|
||||
|
||||
with open(css_file_path, 'r') as css_file:
|
||||
css_content = css_file.read()
|
||||
|
||||
js_content = transform_css_to_js(css_content)
|
||||
|
||||
with open(js_file_path, 'w') as js_file:
|
||||
js_file.write(js_content)
|
||||
|
||||
|
||||
|
||||
|
||||
github_repo_url = "https://github.com/OpenArt-AI/ComfyUI-Assistant"
|
||||
zip_url = f"{github_repo_url}/archive/main.zip"
|
||||
|
||||
script_directory = os.path.dirname(os.path.realpath(__file__))
|
||||
javascript_folder = os.path.join(script_directory, "javascript")
|
||||
|
||||
|
||||
temp_zip_path = os.path.join(script_directory, "main.zip")
|
||||
temp_extracted_folder = os.path.join(script_directory, "temp_extracted")
|
||||
|
||||
# Download the ZIP file
|
||||
response = requests.get(zip_url)
|
||||
if response.status_code == 200:
|
||||
with open(temp_zip_path, "wb") as temp_zip_file:
|
||||
temp_zip_file.write(response.content)
|
||||
if os.getenv("COMFY_ASSISTANT_ENV") == "DEV":
|
||||
print("Skipping auto-upgrade")
|
||||
else:
|
||||
# Download the ZIP file
|
||||
response = requests.get(zip_url)
|
||||
if response.status_code == 200:
|
||||
with open(temp_zip_path, "wb") as temp_zip_file:
|
||||
temp_zip_file.write(response.content)
|
||||
|
||||
# Extract the contents of the ZIP file to a temporary folder
|
||||
with ZipFile(temp_zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(temp_extracted_folder)
|
||||
# Extract the contents of the ZIP file to a temporary folder
|
||||
with ZipFile(temp_zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(temp_extracted_folder)
|
||||
|
||||
# Replace the current JavaScript folder with the new one
|
||||
new_javascript_folder = os.path.join(temp_extracted_folder, "ComfyUI-Assistant-main", "javascript")
|
||||
# Replace the current JavaScript folder with the new one
|
||||
new_javascript_folder = os.path.join(temp_extracted_folder, "ComfyUI-Assistant-main", "javascript")
|
||||
|
||||
# Copy the contents of the new JavaScript folder to the current folder
|
||||
shutil.rmtree(javascript_folder)
|
||||
shutil.copytree(new_javascript_folder, javascript_folder)
|
||||
# Copy the contents of the new JavaScript folder to the current folder
|
||||
shutil.rmtree(javascript_folder)
|
||||
shutil.copytree(new_javascript_folder, javascript_folder)
|
||||
|
||||
# Cleanup: remove temporary files and folders
|
||||
os.remove(temp_zip_path)
|
||||
shutil.rmtree(temp_extracted_folder)
|
||||
# Cleanup: remove temporary files and folders
|
||||
os.remove(temp_zip_path)
|
||||
shutil.rmtree(temp_extracted_folder)
|
||||
|
||||
transform_files_in_folder(javascript_folder)
|
||||
|
||||
|
||||
|
||||
|
||||
WEB_DIRECTORY = 'javascript'
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
import * as data from './data.js';
|
||||
window.data = data;
|
||||
const ext = {
|
||||
// Unique name for the extension
|
||||
name: "ComfyUI-Assistant",
|
||||
async setup(app) {
|
||||
const menuLoadDefault = document.querySelector("#comfy-load-default-button");
|
||||
const learnBtn = document.createElement("button");
|
||||
learnBtn.textContent = "Learn";
|
||||
|
||||
if(!localStorage.getItem("CLICKED_LEARN")) {
|
||||
learnBtn.classList.toggle("animate-background")
|
||||
learnBtn.addEventListener("click", ()=>{
|
||||
localStorage.setItem("CLICKED_LEARN","true")
|
||||
learnBtn.classList.remove("animate-background")
|
||||
})
|
||||
}
|
||||
learnBtn.addEventListener("click", ()=>{
|
||||
window.onLearnClick()
|
||||
})
|
||||
menuLoadDefault.after(learnBtn);
|
||||
},
|
||||
};
|
||||
|
||||
app.registerExtension(ext);
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia:
|
||||
}
|
||||
|
||||
::backdrop {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia:
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.inset-0 {
|
||||
inset: 0px
|
||||
}
|
||||
|
||||
.left-0 {
|
||||
left: 0px
|
||||
}
|
||||
|
||||
.top-0 {
|
||||
top: 0px
|
||||
}
|
||||
|
||||
.z-50 {
|
||||
z-index: 50
|
||||
}
|
||||
|
||||
.m-4 {
|
||||
margin: 1rem
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex
|
||||
}
|
||||
|
||||
.h-8 {
|
||||
height: 2rem
|
||||
}
|
||||
|
||||
.max-h-96 {
|
||||
max-height: 24rem
|
||||
}
|
||||
|
||||
.w-14 {
|
||||
width: 3.5rem
|
||||
}
|
||||
|
||||
.w-fit {
|
||||
width: -moz-fit-content;
|
||||
width: fit-content
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.w-screen {
|
||||
width: 100vw
|
||||
}
|
||||
|
||||
.max-w-4xl {
|
||||
max-width: 56rem
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
flex-direction: row
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.justify-around {
|
||||
justify-content: space-around
|
||||
}
|
||||
|
||||
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)))
|
||||
}
|
||||
|
||||
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse))
|
||||
}
|
||||
|
||||
.overflow-y-auto {
|
||||
overflow-y: auto
|
||||
}
|
||||
|
||||
.rounded-xl {
|
||||
border-radius: 0.75rem
|
||||
}
|
||||
|
||||
.rounded-t-xl {
|
||||
border-top-left-radius: 0.75rem;
|
||||
border-top-right-radius: 0.75rem
|
||||
}
|
||||
|
||||
.bg-comfy-light {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(53 53 53 / var(--tw-bg-opacity))
|
||||
}
|
||||
|
||||
.bg-gray-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(107 114 128 / var(--tw-bg-opacity))
|
||||
}
|
||||
|
||||
.object-cover {
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover
|
||||
}
|
||||
|
||||
.p-2 {
|
||||
padding: 0.5rem
|
||||
}
|
||||
|
||||
.px-1 {
|
||||
padding-left: 0.25rem;
|
||||
padding-right: 0.25rem
|
||||
}
|
||||
|
||||
.px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem
|
||||
}
|
||||
|
||||
.py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem
|
||||
}
|
||||
|
||||
.text-sm {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem
|
||||
}
|
||||
|
||||
.text-xs {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem
|
||||
}
|
||||
|
||||
.font-semibold {
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.text-gray-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(209 213 219 / var(--tw-text-opacity))
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration-line: underline
|
||||
}
|
||||
|
||||
.filter {
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)
|
||||
}
|
||||
|
||||
@keyframes Gradient {
|
||||
0%{
|
||||
background-position: 0% 50%
|
||||
}
|
||||
|
||||
50%{
|
||||
background-position: 100% 50%
|
||||
}
|
||||
|
||||
100%{
|
||||
background-position: 0% 50%
|
||||
}
|
||||
}
|
||||
|
||||
.animated-background{
|
||||
background: linear-gradient(270deg, #d53369, #daae51);
|
||||
background-size: 200% 200%;
|
||||
animation: Gradient 2s ease infinite;
|
||||
}
|
||||
|
||||
.hover\:bg-gray-500:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(107 114 128 / var(--tw-bg-opacity))
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
|
||||
var docStyle = document.createElement('style');
|
||||
docStyle.innerHTML = `*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia:
|
||||
}
|
||||
|
||||
::backdrop {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia:
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.inset-0 {
|
||||
inset: 0px
|
||||
}
|
||||
|
||||
.left-0 {
|
||||
left: 0px
|
||||
}
|
||||
|
||||
.top-0 {
|
||||
top: 0px
|
||||
}
|
||||
|
||||
.z-50 {
|
||||
z-index: 50
|
||||
}
|
||||
|
||||
.m-4 {
|
||||
margin: 1rem
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex
|
||||
}
|
||||
|
||||
.h-8 {
|
||||
height: 2rem
|
||||
}
|
||||
|
||||
.max-h-96 {
|
||||
max-height: 24rem
|
||||
}
|
||||
|
||||
.w-14 {
|
||||
width: 3.5rem
|
||||
}
|
||||
|
||||
.w-fit {
|
||||
width: -moz-fit-content;
|
||||
width: fit-content
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.w-screen {
|
||||
width: 100vw
|
||||
}
|
||||
|
||||
.max-w-4xl {
|
||||
max-width: 56rem
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
flex-direction: row
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.justify-around {
|
||||
justify-content: space-around
|
||||
}
|
||||
|
||||
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)))
|
||||
}
|
||||
|
||||
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse))
|
||||
}
|
||||
|
||||
.overflow-y-auto {
|
||||
overflow-y: auto
|
||||
}
|
||||
|
||||
.rounded-xl {
|
||||
border-radius: 0.75rem
|
||||
}
|
||||
|
||||
.rounded-t-xl {
|
||||
border-top-left-radius: 0.75rem;
|
||||
border-top-right-radius: 0.75rem
|
||||
}
|
||||
|
||||
.bg-comfy-light {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(53 53 53 / var(--tw-bg-opacity))
|
||||
}
|
||||
|
||||
.bg-gray-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(107 114 128 / var(--tw-bg-opacity))
|
||||
}
|
||||
|
||||
.object-cover {
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover
|
||||
}
|
||||
|
||||
.p-2 {
|
||||
padding: 0.5rem
|
||||
}
|
||||
|
||||
.px-1 {
|
||||
padding-left: 0.25rem;
|
||||
padding-right: 0.25rem
|
||||
}
|
||||
|
||||
.px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem
|
||||
}
|
||||
|
||||
.py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem
|
||||
}
|
||||
|
||||
.text-sm {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem
|
||||
}
|
||||
|
||||
.text-xs {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem
|
||||
}
|
||||
|
||||
.font-semibold {
|
||||
font-weight: 600
|
||||
}
|
||||
|
||||
.text-gray-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(209 213 219 / var(--tw-text-opacity))
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration-line: underline
|
||||
}
|
||||
|
||||
.filter {
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)
|
||||
}
|
||||
|
||||
@keyframes Gradient {
|
||||
0%{
|
||||
background-position: 0% 50%
|
||||
}
|
||||
|
||||
50%{
|
||||
background-position: 100% 50%
|
||||
}
|
||||
|
||||
100%{
|
||||
background-position: 0% 50%
|
||||
}
|
||||
}
|
||||
|
||||
.animated-background{
|
||||
background: linear-gradient(270deg, #d53369, #daae51);
|
||||
background-size: 200% 200%;
|
||||
animation: Gradient 2s ease infinite;
|
||||
}
|
||||
|
||||
.hover\\:bg-gray-500:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(107 114 128 / var(--tw-bg-opacity))
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(docStyle);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,52 +0,0 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
import {LearnModal} from './learn-menu.js'
|
||||
import {latestVersion} from "./data.js";
|
||||
|
||||
|
||||
const localVersion = 1;
|
||||
|
||||
|
||||
var docStyle = document.createElement('style');
|
||||
docStyle.innerHTML = `
|
||||
@keyframes Gradient {
|
||||
0%{background-position: 0% 50%}
|
||||
50%{background-position: 100% 50%}
|
||||
100%{background-position: 0% 50%}
|
||||
}
|
||||
`;
|
||||
|
||||
document.head.appendChild(docStyle);
|
||||
|
||||
let learnModalInstance = null;
|
||||
|
||||
|
||||
|
||||
const ext = {
|
||||
// Unique name for the extension
|
||||
name: "ComfyUI-Assistant",
|
||||
async setup(app) {
|
||||
const menuLoadDefault = document.querySelector("#comfy-load-default-button");
|
||||
const learnBtn = document.createElement("button");
|
||||
learnBtn.textContent = "Learn";
|
||||
|
||||
if(!localStorage.getItem("clickedLearn")) {
|
||||
learnBtn.style.background = "linear-gradient(270deg, #d53369, #daae51)";
|
||||
learnBtn.style.backgroundSize = "200% 200%";
|
||||
learnBtn.style.animation = "Gradient 2s ease infinite";
|
||||
learnBtn.addEventListener("click", ()=>{
|
||||
localStorage.setItem("clickedLearn","true")
|
||||
learnBtn.style=null;
|
||||
})
|
||||
}
|
||||
learnBtn.addEventListener("click", ()=>{
|
||||
if(latestVersion>localVersion){
|
||||
alert("You are using an old version of the plugin, update it to get the latest features")
|
||||
}
|
||||
LearnModal.get().show();
|
||||
})
|
||||
menuLoadDefault.after(learnBtn);
|
||||
},
|
||||
};
|
||||
|
||||
app.registerExtension(ext);
|
||||
|
||||
+27967
File diff suppressed because one or more lines are too long
@@ -1,115 +0,0 @@
|
||||
|
||||
|
||||
const tag = document.createElement('script');
|
||||
|
||||
tag.src = "https://www.youtube.com/iframe_api";
|
||||
const firstScriptTag = document.getElementsByTagName('script')[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
|
||||
let player;
|
||||
const setVideo = (videoId)=> {
|
||||
console.log(videoId)
|
||||
player = new YT.Player('player',{
|
||||
videoId: videoId,
|
||||
events: {
|
||||
'onStateChange': onPlayerStateChange
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var done = false;
|
||||
var lastInterval = null;
|
||||
let keyframesFunctions= {}
|
||||
function onPlayerStateChange(event) {
|
||||
if (event.data == YT.PlayerState.PLAYING) {
|
||||
lastInterval = setInterval(function () {
|
||||
// keyframesFunctions contains seconds and functions like {5:()=>console.log("five seconds!")} I want that this will always call the appropriate function based on the time but still taking to considerations interval hiccups
|
||||
const currentTime = player.getCurrentTime();
|
||||
const timeInSeconds = Math.floor(currentTime);
|
||||
if (keyframesFunctions[timeInSeconds]) {
|
||||
keyframesFunctions[timeInSeconds]();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function startVideo(title,videoId, _keyframesFunctions){
|
||||
keyframesFunctions = _keyframesFunctions
|
||||
const lastContainer = document.getElementById("youtube-container")
|
||||
if(lastContainer){
|
||||
lastContainer.remove()
|
||||
clearInterval(lastInterval)
|
||||
}
|
||||
const ytContainer = document.createElement('div');
|
||||
ytContainer.style.position="absolute"
|
||||
ytContainer.style.top="50px"
|
||||
ytContainer.style.left="50px"
|
||||
ytContainer.style.zIndex="101"
|
||||
ytContainer.setAttribute("id","youtube-container")
|
||||
|
||||
|
||||
const videoContainerWindow = document.createElement('div');
|
||||
videoContainerWindow.style.width="100%"
|
||||
videoContainerWindow.style.height="30px"
|
||||
videoContainerWindow.style.background="#5e5e5e"
|
||||
videoContainerWindow.style.cursor="move";
|
||||
videoContainerWindow.style.display= "flex";
|
||||
videoContainerWindow.style.alignItems= "center";
|
||||
const titleEl = document.createElement('span')
|
||||
titleEl.style.flexGrow= "1";
|
||||
titleEl.style.padding= "4px";
|
||||
titleEl.appendChild(document.createTextNode(title))
|
||||
|
||||
videoContainerWindow.appendChild(titleEl);
|
||||
//Add minimize and exit:
|
||||
const minimizeButton = document.createElement('button');
|
||||
minimizeButton.style.marginRight = "5px";
|
||||
minimizeButton.innerHTML = "-";
|
||||
|
||||
minimizeButton.onclick = () => {
|
||||
document.getElementById("player").hidden=!document.getElementById("player").hidden
|
||||
}
|
||||
|
||||
const exitButton = document.createElement('button');
|
||||
exitButton.innerHTML = "X";
|
||||
exitButton.style.marginRight="5px";
|
||||
|
||||
exitButton.onclick = () => {
|
||||
ytContainer.remove();
|
||||
}
|
||||
|
||||
videoContainerWindow.appendChild(minimizeButton);
|
||||
videoContainerWindow.appendChild(exitButton);
|
||||
|
||||
|
||||
|
||||
let drag = {x: 0, y: 0};
|
||||
let dragging = false;
|
||||
videoContainerWindow.onmousedown = (e) => {
|
||||
drag.x = e.clientX - ytContainer.offsetLeft;
|
||||
drag.y = e.clientY - ytContainer.offsetTop;
|
||||
dragging=true
|
||||
}
|
||||
|
||||
document.onmousemove = (e) => {
|
||||
if (e.buttons === 1 && dragging) {
|
||||
ytContainer.style.left = `${e.clientX - drag.x}px`;
|
||||
ytContainer.style.top = `${e.clientY - drag.y}px`;
|
||||
}
|
||||
}
|
||||
|
||||
document.onmouseup = (e) => {
|
||||
drag = {x: 0, y: 0};
|
||||
dragging=false;
|
||||
}
|
||||
|
||||
|
||||
ytContainer.appendChild(videoContainerWindow)
|
||||
const ytPlayer = document.createElement('div');
|
||||
ytPlayer.setAttribute("id","player")
|
||||
ytContainer.appendChild(ytPlayer)
|
||||
document.body.appendChild(ytContainer);
|
||||
setVideo(videoId)
|
||||
}
|
||||
Generated
+2202
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "ui",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"build:esbuild": "esbuild src/index.jsx --bundle --outfile=../javascript/out.js --loader:.png=dataurl",
|
||||
"build:css": "npx tailwindcss -i ./src/global.css -o ../javascript/global.css --minify",
|
||||
"build": "npm-run-all --parallel build:*",
|
||||
"watch:esbuild": "esbuild src/index.jsx --bundle --watch --outfile=../javascript/out.js --loader:.png=dataurl",
|
||||
"watch:css": "npx tailwindcss -i ./src/global.css -o ../javascript/global.css --watch",
|
||||
"dev": "npm-run-all --parallel watch:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "0.19.11",
|
||||
"tailwindcss": "^3.4.0",
|
||||
"npm-run-all": "^4.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-draggable": "^4.4.6",
|
||||
"react-youtube": "^10.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Dialog } from '@headlessui/react'
|
||||
import logo from './logo.png';
|
||||
import LearnDialog from "./LearnDialog";
|
||||
import YoutubePlayer from "./YoutubePlayer";
|
||||
const ComfyAssistantOverlay = () => {
|
||||
const [isOpen,setIsOpen] = useState(false)
|
||||
const [video,setVideo] = useState(null)
|
||||
window.onLearnClick = () => {
|
||||
setIsOpen(true)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
onClose={() => setIsOpen(false)}
|
||||
className="relative z-50"
|
||||
>
|
||||
{!video && <LearnDialog close={()=>setIsOpen(false)} startVideo={(video) => setVideo(video)}/>}
|
||||
{video && <YoutubePlayer videoId={'BT2Kpm1cU-w'} close={()=> {
|
||||
setIsOpen(false)
|
||||
setVideo(null)
|
||||
}} />}
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default ComfyAssistantOverlay;
|
||||
@@ -0,0 +1,82 @@
|
||||
import React, {useState} from 'react';
|
||||
import {Dialog} from "@headlessui/react";
|
||||
import logo from "./logo.png";
|
||||
import Draggable from "react-draggable";
|
||||
// moduleItem.querySelector('button').addEventListener('click', () => {
|
||||
// LearnModal.get().close()
|
||||
// if(module.initialWorkflow){
|
||||
// app.loadGraphData(JSON.parse(module.initialWorkflow))
|
||||
// }
|
||||
// if(module.type === 'lesson') {
|
||||
// const keyframesFunctions = {}
|
||||
// if(module.keyframesWorkflows){
|
||||
// for (let keyframe in module.keyframesWorkflows) {
|
||||
// const parsedWorkflow = JSON.parse(module.keyframesWorkflows[keyframe])
|
||||
// keyframesFunctions[keyframe] = ()=> app.loadGraphData(parsedWorkflow);
|
||||
// }
|
||||
// }
|
||||
// startVideo(module.title,module.videoId,keyframesFunctions)
|
||||
// }
|
||||
function LearnDialog({close, startVideo}) {
|
||||
const [selectedCategory,setSelectedCategory] = useState(window.data.categories[0])
|
||||
|
||||
return (
|
||||
<Draggable>
|
||||
<div className="fixed inset-0 flex w-screen items-center justify-center p-2">
|
||||
<Dialog.Panel className="w-full max-w-4xl rounded-xl bg-comfy-light px-4 relative">
|
||||
<span className={"font-semibold absolute top-0 left-0 m-4 cursor-pointer"}
|
||||
onClick={close}>X</span>
|
||||
|
||||
<Dialog.Title className={"flex flex-row justify-center"}>Comfy Assistant <span
|
||||
className={"px-2 text-xs"}>by <a
|
||||
href={"https://openart.ai"}><img src={logo} className={"w-14 px-1"}/></a></span>
|
||||
</Dialog.Title>
|
||||
<div className={"flex flex-col"}>
|
||||
<div className="flex flex-row justify-around underline space-x-2 p-2">
|
||||
{window.data.categories.map(cat => <a key={cat} className={"cursor-pointer"}
|
||||
onClick={() => {
|
||||
setSelectedCategory(cat)
|
||||
}}>{cat}</a>)}
|
||||
</div>
|
||||
<div className={"flex flex-col max-h-96 overflow-y-auto space-y-2 p-2 "}>
|
||||
{window.data.modules.filter(module => module.categories.includes(selectedCategory)).map(module =>
|
||||
<div key={module.title}
|
||||
className={"flex items-center flex-row space-x-2 p-2 hover:bg-gray-500 cursor-pointer"}
|
||||
onClick={(e) => {
|
||||
if (module.initialWorkflow) {
|
||||
app.loadGraphData(JSON.parse(module.initialWorkflow))
|
||||
}
|
||||
if (module.type === 'lesson') {
|
||||
const keyframesFunctions = {}
|
||||
if (module.keyframesWorkflows) {
|
||||
for (let keyframe in module.keyframesWorkflows) {
|
||||
const parsedWorkflow = JSON.parse(module.keyframesWorkflows[keyframe])
|
||||
keyframesFunctions[keyframe] = () => app.loadGraphData(parsedWorkflow);
|
||||
}
|
||||
}
|
||||
startVideo({title:module.title, videoId:module.videoId, keyframesFunctions})
|
||||
} else {
|
||||
close()
|
||||
}
|
||||
|
||||
}}
|
||||
>
|
||||
<img width={96} height={96} className={"object-cover"}
|
||||
src={module.thumbnail ? module.thumbnail : `https://img.youtube.com/vi/${module.videoId}/default.jpg`}/>
|
||||
<div className={"flex flex-col"}>
|
||||
<span className={"font-semibold text-2xl py-2"}>{module.title}</span>
|
||||
<span className={"text-sm text-gray-300"}>{module.description}</span>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</Dialog.Panel>
|
||||
</div>
|
||||
</Draggable>
|
||||
);
|
||||
}
|
||||
|
||||
export default LearnDialog;
|
||||
@@ -0,0 +1,51 @@
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import YouTube from 'react-youtube';
|
||||
import {Dialog} from "@headlessui/react";
|
||||
import Draggable from "react-draggable";
|
||||
|
||||
function YoutubePlayer({videoId,close,keyframesFunctions}) {
|
||||
const playerStateRef= useRef(-1)
|
||||
const playerRef= useRef(null)
|
||||
|
||||
const onPlayerStateChange = (event) => {
|
||||
playerRef.current = event.target
|
||||
playerStateRef.current = event.data
|
||||
}
|
||||
useEffect(() => {
|
||||
const lastInterval = setInterval(function () {
|
||||
// keyframesFunctions contains seconds and functions like {5:()=>console.log("five seconds!")} I want that this will always call the appropriate function based on the time but still taking to considerations interval hiccups
|
||||
const currentTime = playerRef.current.getCurrentTime();
|
||||
const timeInSeconds = Math.floor(currentTime);
|
||||
if (keyframesFunctions[timeInSeconds]) {
|
||||
keyframesFunctions[timeInSeconds]();
|
||||
}
|
||||
}, 1000);
|
||||
return () => {
|
||||
clearInterval(lastInterval)
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Draggable>
|
||||
<div className="fixed inset-0 flex w-screen items-center justify-center p-2" >
|
||||
<Dialog.Panel className="w-fit max-w-4xl rounded-xl bg-comfy-light relative">
|
||||
|
||||
<div className={"flex flex-row items-center font-semibold w-full bg-gray-500 top-0 left-0 h-8 rounded-t-xl"}>
|
||||
<span className={"cursor-pointer px-2"} onClick={close}>X</span>
|
||||
</div>
|
||||
<div className={""}>
|
||||
<YouTube videoId={videoId} onPlayerStateChange={onPlayerStateChange}/>
|
||||
</div>
|
||||
|
||||
</Dialog.Panel>
|
||||
</div>
|
||||
</Draggable>
|
||||
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
export default YoutubePlayer;
|
||||
@@ -0,0 +1,16 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@keyframes Gradient {
|
||||
0%{background-position: 0% 50%}
|
||||
50%{background-position: 100% 50%}
|
||||
100%{background-position: 0% 50%}
|
||||
}
|
||||
|
||||
|
||||
.animated-background{
|
||||
background: linear-gradient(270deg, #d53369, #daae51);
|
||||
background-size: 200% 200%;
|
||||
animation: Gradient 2s ease infinite;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
import ComfyAssistantOverlay from "./ComfyAssistantOverlay";
|
||||
|
||||
const rootDomNode = document.createElement('div');
|
||||
document.body.appendChild(rootDomNode);
|
||||
const root = ReactDOM.createRoot(rootDomNode);
|
||||
root.render(<ComfyAssistantOverlay />);
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,17 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{ts,js,jsx,tsx}"],
|
||||
theme: {
|
||||
extend: {
|
||||
colors:{
|
||||
"comfy-light":"#353535",
|
||||
"comfy-dark":"#222222",
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
corePlugins:{
|
||||
preflight:false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user