import { app } from "../../scripts/app.js" ;
import { api } from "../../scripts/api.js"
import { ComfyDialog , $el } from "../../scripts/ui.js" ;
import { OpenArtShareDialog } from "./comfyui-share-openart.js" ;
export const SUPPORTED _OUTPUT _NODE _TYPES = [
"PreviewImage" ,
"SaveImage" ,
"VHS_VideoCombine" ,
"ADE_AnimateDiffCombine" ,
]
var docStyle = document . createElement ( 'style' ) ;
docStyle . innerHTML = `
. cm - menu - container {
column - gap : 20 px ;
display : flex ;
flex - wrap : wrap ;
justify - content : center ;
}
. cm - menu - column {
display : flex ;
flex - direction : column ;
}
. cm - title {
padding : 10 px 10 px 0 10 p ;
background - color : black ;
text - align : center ;
height : 45 px ;
}
` ;
document . head . appendChild ( docStyle ) ;
export function getPotentialOutputsAndOutputNodes ( nodes ) {
const potential _outputs = [ ] ;
const potential _output _nodes = [ ] ;
// iterate over the array of nodes to find the ones that are marked as SaveImage
// TODO: Add support for AnimateDiffCombine, etc. nodes that save videos/gifs, etc.
for ( let i = 0 ; i < nodes . length ; i ++ ) {
const node = nodes [ i ] ;
if ( ! SUPPORTED _OUTPUT _NODE _TYPES . includes ( node . type ) ) {
continue ;
}
if ( node . type === "SaveImage" ) {
potential _output _nodes . push ( node ) ;
// check if node has an 'images' array property
if ( node . hasOwnProperty ( "images" ) && Array . isArray ( node . images ) ) {
// iterate over the images array and add each image to the potential_outputs array
for ( let j = 0 ; j < node . images . length ; j ++ ) {
potential _outputs . push ( { "type" : "image" , "image" : node . images [ j ] , "title" : node . title } ) ;
}
}
}
else if ( node . type === "PreviewImage" ) {
potential _output _nodes . push ( node ) ;
// check if node has an 'images' array property
if ( node . hasOwnProperty ( "images" ) && Array . isArray ( node . images ) ) {
// iterate over the images array and add each image to the potential_outputs array
for ( let j = 0 ; j < node . images . length ; j ++ ) {
potential _outputs . push ( { "type" : "image" , "image" : node . images [ j ] , "title" : node . title } ) ;
}
}
}
else if ( node . type === "VHS_VideoCombine" ) {
potential _output _nodes . push ( node ) ;
// check if node has a 'widgets' array property, with type 'image'
if ( node . hasOwnProperty ( "widgets" ) && Array . isArray ( node . widgets ) ) {
// iterate over the widgets array and add each image to the potential_outputs array
for ( let j = 0 ; j < node . widgets . length ; j ++ ) {
if ( node . widgets [ j ] . type === "image" ) {
const widgetValue = node . widgets [ j ] . value ;
const parsedURLVals = parseURLPath ( widgetValue ) ;
// ensure that the parsedURLVals have 'filename', 'subfolder', 'type', and 'format' properties
if ( parsedURLVals . hasOwnProperty ( "filename" ) && parsedURLVals . hasOwnProperty ( "subfolder" ) && parsedURLVals . hasOwnProperty ( "type" ) && parsedURLVals . hasOwnProperty ( "format" ) ) {
if ( parsedURLVals . type !== "output" ) {
// TODO
}
potential _outputs . push ( { "type" : "output" , 'title' : node . title , "output" : { "filename" : parsedURLVals . filename , "subfolder" : parsedURLVals . subfolder , "value" : widgetValue , "format" : parsedURLVals . format } } ) ;
}
} else if ( node . widgets [ j ] . type === "preview" ) {
const widgetValue = node . widgets [ j ] . value ;
const parsedURLVals = widgetValue . params ;
if ( ! parsedURLVals . format . startsWith ( 'image' ) ) {
// video isn't supported format
continue ;
}
// ensure that the parsedURLVals have 'filename', 'subfolder', 'type', and 'format' properties
if ( parsedURLVals . hasOwnProperty ( "filename" ) && parsedURLVals . hasOwnProperty ( "subfolder" ) && parsedURLVals . hasOwnProperty ( "type" ) && parsedURLVals . hasOwnProperty ( "format" ) ) {
if ( parsedURLVals . type !== "output" ) {
// TODO
}
potential _outputs . push ( { "type" : "output" , 'title' : node . title , "output" : { "filename" : parsedURLVals . filename , "subfolder" : parsedURLVals . subfolder , "value" : ` /view?filename= ${ parsedURLVals . filename } &subfolder= ${ parsedURLVals . subfolder } &type= ${ parsedURLVals . type } &format= ${ parsedURLVals . format } ` , "format" : parsedURLVals . format } } ) ;
}
}
}
}
}
else if ( node . type === "ADE_AnimateDiffCombine" ) {
potential _output _nodes . push ( node ) ;
// check if node has a 'widgets' array property, with type 'image'
if ( node . hasOwnProperty ( "widgets" ) && Array . isArray ( node . widgets ) ) {
// iterate over the widgets array and add each image to the potential_outputs array
for ( let j = 0 ; j < node . widgets . length ; j ++ ) {
if ( node . widgets [ j ] . type === "image" ) {
const widgetValue = node . widgets [ j ] . value ;
const parsedURLVals = parseURLPath ( widgetValue ) ;
// ensure that the parsedURLVals have 'filename', 'subfolder', 'type', and 'format' properties
if ( parsedURLVals . hasOwnProperty ( "filename" ) && parsedURLVals . hasOwnProperty ( "subfolder" ) && parsedURLVals . hasOwnProperty ( "type" ) && parsedURLVals . hasOwnProperty ( "format" ) ) {
if ( parsedURLVals . type !== "output" ) {
// TODO
continue ;
}
potential _outputs . push ( { "type" : "output" , 'title' : node . title , "output" : { "filename" : parsedURLVals . filename , "subfolder" : parsedURLVals . subfolder , "type" : parsedURLVals . type , "value" : widgetValue , "format" : parsedURLVals . format } } ) ;
}
}
}
}
}
}
return { potential _outputs , potential _output _nodes } ;
}
export function parseURLPath ( urlPath ) {
// Extract the query string from the URL path
var queryString = urlPath . split ( '?' ) [ 1 ] ;
// Use the URLSearchParams API to parse the query string
var params = new URLSearchParams ( queryString ) ;
// Create an object to store the parsed parameters
var parsedParams = { } ;
// Iterate over each parameter and add it to the object
for ( var pair of params . entries ( ) ) {
parsedParams [ pair [ 0 ] ] = pair [ 1 ] ;
}
// Return the object with the parsed parameters
return parsedParams ;
}
export class ShareDialogChooser extends ComfyDialog {
static instance = null ;
constructor ( ) {
super ( ) ;
this . element = $el ( "div.comfy-modal" , {
parent : document . body , style : {
'overflow-y' : "auto" ,
}
} ,
[ $el ( "div.comfy-modal-content" ,
{ } ,
[ ... this . createButtons ( ) ] ) ,
] ) ;
}
createButtons ( ) {
const handleShowOpenArtShareDialog = ( ) => {
if ( ! OpenArtShareDialog . instance ) {
OpenArtShareDialog . instance = new OpenArtShareDialog ( ) ;
}
OpenArtShareDialog . instance . show ( { potential _outputs : this . potential _output _nodes , potential _output _nodes : this . potential _output _nodes } )
this . close ( ) ;
}
const handleShowShareDialog = ( ) => {
if ( ! ShareDialog . instance ) {
ShareDialog . instance = new ShareDialog ( ) ;
}
ShareDialog . instance . show ( { potential _outputs : this . potential _output _nodes , potential _output _nodes : this . potential _output _nodes } )
this . close ( ) ;
}
const buttons = [
{
key : "openart" ,
textContent : "OpenArt AI" ,
website : "https://openart.ai/workflows/" ,
description : "Best place to share your workflow and art." ,
onclick : handleShowOpenArtShareDialog
} ,
{
key : "matrix" ,
textContent : "Matrix Server" ,
website : "https://app.element.io/#/room/%23comfyui_space%3Amatrix.org" ,
description : "Share your art on the official ComfyUI matrix server." ,
onclick : handleShowShareDialog
} ,
{
key : "comfyworkflows" ,
textContent : "ComfyWorkflows" ,
website : "https://comfyworkflows.com" ,
description : "Share ComfyUI art: Download & drop any image into ComfyUI to load its workflow." ,
onclick : handleShowShareDialog
} ,
] ;
function createShareButtonsWithDescriptions ( ) {
// Responsive container
const container = $el ( "div" , {
style : {
display : "flex" ,
'flex-wrap' : 'wrap' ,
'justify-content' : 'space-around' ,
'padding' : '20px' ,
}
} ) ;
buttons . forEach ( b => {
const button = $el ( "button" , {
type : "button" ,
textContent : b . textContent ,
onclick : b . onclick ,
style : {
'width' : '25%' ,
'minWidth' : '200px' ,
'background-color' : b . backgroundColor || '' ,
'border-radius' : '5px' ,
'cursor' : 'pointer' ,
'padding' : '5px 5px' ,
'margin-bottom' : '5px' ,
'transition' : 'background-color 0.3s' ,
}
} ) ;
button . addEventListener ( 'mouseover' , ( ) => {
button . style . backgroundColor = '#007BFF' ; // Change color on hover
} ) ;
button . addEventListener ( 'mouseout' , ( ) => {
button . style . backgroundColor = b . backgroundColor || '' ;
} ) ;
const description = $el ( "p" , {
textContent : b . description ,
style : {
'text-align' : 'center' ,
color : 'white' ,
'font-style' : 'italic' ,
'font-size' : '14px' ,
'margin-bottom' : '10px' ,
} ,
} ) ;
const websiteLink = $el ( "a" , {
textContent : "🌐 Website" ,
href : b . website ,
target : "_blank" ,
style : {
color : 'white' ,
'margin-left' : '10px' ,
'font-size' : '12px' ,
'text-decoration' : 'none' ,
'align-self' : 'center' ,
} ,
} ) ;
// Add highlight to the website link
websiteLink . addEventListener ( 'mouseover' , ( ) => {
websiteLink . style . opacity = '0.7' ;
} ) ;
websiteLink . addEventListener ( 'mouseout' , ( ) => {
websiteLink . style . opacity = '1' ;
} ) ;
const buttonLinkContainer = $el ( "div" , {
style : {
display : 'flex' ,
'align-items' : 'center' ,
'margin-bottom' : '10px' ,
}
} , [ button , websiteLink ] ) ;
const column = $el ( "div" , {
style : {
'flex-basis' : '100%' ,
'margin' : '10px' ,
'padding' : '20px' ,
'border' : '1px solid #ddd' ,
'border-radius' : '5px' ,
'box-shadow' : '0 2px 4px rgba(0, 0, 0, 0.1)' ,
}
} , [ buttonLinkContainer , description ] ) ;
container . appendChild ( column ) ;
} ) ;
return container ;
}
return [
$el ( "tr.td" , { width : "100%" } , [
$el ( "font" , { size : 6 , color : "white" } , [ ` Where would you like to share your workflow? ` ] ) ,
] ) ,
$el ( "br" , { } , [ ] ) ,
$el ( "div.cm-menu-container" , {
id : "comfyui-share-container"
} , [
$el ( "div.cm-menu-column" , [
$el ( "p" , {
size : 3 , color : "white" , style : {
color : 'white'
}
} ) ,
createShareButtonsWithDescriptions ( ) ,
$el ( "br" , { } , [ ] ) ,
] ) ,
] ) ,
$el ( "div.cm-menu-container" , {
id : "comfyui-share-container"
} , [
$el ( "button" , {
type : "button" ,
style : {
margin : "0 25px" ,
width : "100%" ,
} ,
textContent : "Close" ,
onclick : ( ) => {
this . close ( )
}
} ) ,
$el ( "br" , { } , [ ] ) ,
] ) ,
] ;
}
show ( { potential _outputs , potential _output _nodes } ) {
this . element . style . display = "block" ;
this . potential _outputs = potential _outputs ;
this . potential _output _nodes = potential _output _nodes ;
}
}
export class ShareDialog extends ComfyDialog {
static instance = null ;
static matrix _auth = { homeserver : "matrix.org" , username : "" , password : "" } ;
static cw _sharekey = "" ;
constructor ( ) {
super ( ) ;
this . element = $el ( "div.comfy-modal" , {
parent : document . body , style : {
'overflow-y' : "auto" ,
}
} ,
[ $el ( "div.comfy-modal-content" ,
{ } ,
[ ... this . createButtons ( ) ] ) ,
] ) ;
this . selectedOutputIndex = 0 ;
}
createButtons ( ) {
this . radio _buttons = $el ( "div" , {
id : "selectOutputImages" ,
} , [ ] ) ;
this . is _nsfw _checkbox = $el ( "input" , { type : 'checkbox' , id : "is_nsfw" } , [ ] )
const is _nsfw _checkbox _text = $el ( "label" , {
} , [ " Is this NSFW?" ] )
this . is _nsfw _checkbox . style . color = "var(--fg-color)" ;
this . is _nsfw _checkbox . checked = false ;
this . matrix _destination _checkbox = $el ( "input" , { type : 'checkbox' , id : "matrix_destination" } , [ ] )
const matrix _destination _checkbox _text = $el ( "label" , { } , [ " ComfyUI Matrix server" ] )
this . matrix _destination _checkbox . style . color = "var(--fg-color)" ;
this . matrix _destination _checkbox . checked = false ; //true;
this . comfyworkflows _destination _checkbox = $el ( "input" , { type : 'checkbox' , id : "comfyworkflows_destination" } , [ ] )
const comfyworkflows _destination _checkbox _text = $el ( "label" , { } , [ " ComfyWorkflows.com" ] )
this . comfyworkflows _destination _checkbox . style . color = "var(--fg-color)" ;
this . comfyworkflows _destination _checkbox . checked = true ;
this . matrix _homeserver _input = $el ( "input" , { type : 'text' , id : "matrix_homeserver" , placeholder : "matrix.org" , value : ShareDialog . matrix _auth . homeserver || 'matrix.org' } , [ ] ) ;
this . matrix _username _input = $el ( "input" , { type : 'text' , placeholder : "Username" , value : ShareDialog . matrix _auth . username || '' } , [ ] ) ;
this . matrix _password _input = $el ( "input" , { type : 'password' , placeholder : "Password" , value : ShareDialog . matrix _auth . password || '' } , [ ] ) ;
this . cw _sharekey _input = $el ( "input" , { type : 'text' , placeholder : "Share key (found on your profile page)" , value : ShareDialog . cw _sharekey || '' } , [ ] ) ;
this . cw _sharekey _input . style . width = "100%" ;
this . credits _input = $el ( "input" , {
type : "text" ,
placeholder : "This will be used to give credits" ,
required : false ,
} , [ ] ) ;
this . title _input = $el ( "input" , {
type : "text" ,
placeholder : "ex: My awesome art" ,
required : false
} , [ ] ) ;
this . description _input = $el ( "textarea" , {
placeholder : "ex: Trying out a new workflow... " ,
required : false ,
} , [ ] ) ;
this . share _button = $el ( "button" , {
type : "submit" ,
textContent : "Share" ,
style : {
backgroundColor : "blue"
}
} , [ ] ) ;
this . final _message = $el ( "div" , {
style : {
color : "white" ,
textAlign : "center" ,
// marginTop: "10px",
// backgroundColor: "black",
padding : "10px" ,
}
} , [ ] ) ;
this . share _finalmessage _container = $el ( "div.cm-menu-container" , {
id : "comfyui-share-finalmessage-container" ,
style : {
display : "none" ,
}
} , [
$el ( "div.cm-menu-column" , [
this . final _message ,
$el ( "button" , {
type : "button" ,
textContent : "Close" ,
onclick : ( ) => {
// Reset state
this . matrix _destination _checkbox . checked = false ;
this . comfyworkflows _destination _checkbox . checked = true ;
this . share _button . textContent = "Share" ;
this . share _button . style . display = "inline-block" ;
this . final _message . innerHTML = "" ;
this . final _message . style . color = "white" ;
this . credits _input . value = "" ;
this . title _input . value = "" ;
this . description _input . value = "" ;
this . is _nsfw _checkbox . checked = false ;
this . selectedOutputIndex = 0 ;
// hide the final message
this . share _finalmessage _container . style . display = "none" ;
// show the share container
this . share _container . style . display = "flex" ;
this . close ( )
}
} ) ,
] )
] ) ;
this . share _container = $el ( "div.cm-menu-container" , {
id : "comfyui-share-container"
} , [
$el ( "div.cm-menu-column" , [
$el ( "details" , {
style : {
border : "1px solid #999" ,
padding : "5px" ,
borderRadius : "5px" ,
backgroundColor : "#222"
}
} , [
$el ( "summary" , {
style : {
color : "white" ,
cursor : "pointer" ,
}
} , [ ` Matrix account ` ] ) ,
$el ( "div" , {
style : {
display : "flex" ,
flexDirection : "row" ,
}
} , [
$el ( "div" , {
textContent : "Homeserver" ,
style : {
marginRight : "10px" ,
}
} , [ ] ) ,
this . matrix _homeserver _input ,
] ) ,
$el ( "div" , {
style : {
display : "flex" ,
flexDirection : "row" ,
}
} , [
$el ( "div" , {
textContent : "Username" ,
style : {
marginRight : "10px" ,
}
} , [ ] ) ,
this . matrix _username _input ,
] ) ,
$el ( "div" , {
style : {
display : "flex" ,
flexDirection : "row" ,
}
} , [
$el ( "div" , {
textContent : "Password" ,
style : {
marginRight : "10px" ,
}
} , [ ] ) ,
this . matrix _password _input ,
] ) ,
] ) ,
$el ( "details" , {
style : {
border : "1px solid #999" ,
marginTop : "10px" ,
padding : "5px" ,
borderRadius : "5px" ,
backgroundColor : "#222"
}
} , [
$el ( "summary" , {
style : {
color : "white" ,
cursor : "pointer" ,
}
} , [ ` Comfyworkflows.com account ` ] ) ,
$el ( "h4" , {
textContent : "Share key (found on your profile page)" ,
} , [ ] ) ,
$el ( "p" , { size : 3 , color : "white" } , [ "When provided, your art will be saved to your account." ] ) ,
this . cw _sharekey _input ,
] ) ,
$el ( "div" , { } , [
$el ( "p" , {
size : 3 , color : "white" , style : {
color : 'white'
}
} , [ ` Select where to share your art: ` ] ) ,
this . matrix _destination _checkbox ,
matrix _destination _checkbox _text ,
$el ( "br" , { } , [ ] ) ,
this . comfyworkflows _destination _checkbox ,
comfyworkflows _destination _checkbox _text ,
] ) ,
$el ( "h4" , {
textContent : "Credits (optional)" ,
size : 3 ,
color : "white" ,
style : {
color : 'white'
}
} , [ ] ) ,
this . credits _input ,
// $el("br", {}, []),
$el ( "h4" , {
textContent : "Title (optional)" ,
size : 3 ,
color : "white" ,
style : {
color : 'white'
}
} , [ ] ) ,
this . title _input ,
// $el("br", {}, []),
$el ( "h4" , {
textContent : "Description (optional)" ,
size : 3 ,
color : "white" ,
style : {
color : 'white'
}
} , [ ] ) ,
this . description _input ,
$el ( "br" , { } , [ ] ) ,
$el ( "div" , { } , [ this . is _nsfw _checkbox , is _nsfw _checkbox _text ] ) ,
// $el("br", {}, []),
// this.final_message,
// $el("br", {}, []),
] ) ,
$el ( "div.cm-menu-column" , [
this . radio _buttons ,
$el ( "br" , { } , [ ] ) ,
this . share _button ,
$el ( "button" , {
type : "button" ,
textContent : "Close" ,
onclick : ( ) => {
// Reset state
this . matrix _destination _checkbox . checked = false ;
this . comfyworkflows _destination _checkbox . checked = true ;
this . share _button . textContent = "Share" ;
this . share _button . style . display = "inline-block" ;
this . final _message . innerHTML = "" ;
this . final _message . style . color = "white" ;
this . credits _input . value = "" ;
this . title _input . value = "" ;
this . description _input . value = "" ;
this . is _nsfw _checkbox . checked = false ;
this . selectedOutputIndex = 0 ;
// hide the final message
this . share _finalmessage _container . style . display = "none" ;
// show the share container
this . share _container . style . display = "flex" ;
this . close ( )
}
} ) ,
$el ( "br" , { } , [ ] ) ,
] ) ,
] ) ;
// get the user's existing matrix auth and share key
ShareDialog . matrix _auth = { homeserver : "matrix.org" , username : "" , password : "" } ;
try {
api . fetchApi ( ` /manager/get_matrix_auth ` )
. then ( response => response . json ( ) )
. then ( data => {
ShareDialog . matrix _auth = data ;
this . matrix _homeserver _input . value = ShareDialog . matrix _auth . homeserver ;
this . matrix _username _input . value = ShareDialog . matrix _auth . username ;
this . matrix _password _input . value = ShareDialog . matrix _auth . password ;
} )
. catch ( error => {
// console.log(error);
} ) ;
} catch ( error ) {
// console.log(error);
}
// get the user's existing comfyworkflows share key
ShareDialog . cw _sharekey = "" ;
try {
// console.log("Fetching comfyworkflows share key")
api . fetchApi ( ` /manager/get_comfyworkflows_auth ` )
. then ( response => response . json ( ) )
. then ( data => {
ShareDialog . cw _sharekey = data . comfyworkflows _sharekey ;
this . cw _sharekey _input . value = ShareDialog . cw _sharekey ;
} )
. catch ( error => {
// console.log(error);
} ) ;
} catch ( error ) {
// console.log(error);
}
this . share _button . onclick = async ( ) => {
const prompt = await app . graphToPrompt ( ) ;
const nodes = app . graph . _nodes ;
// console.log({ prompt, nodes });
const destinations = [ ] ;
if ( this . matrix _destination _checkbox . checked ) {
destinations . push ( "matrix" ) ;
}
if ( this . comfyworkflows _destination _checkbox . checked ) {
destinations . push ( "comfyworkflows" ) ;
}
// if destinations includes matrix, make an api call to /manager/check_matrix to ensure that the user has configured their matrix settings
if ( destinations . includes ( "matrix" ) ) {
let definedMatrixAuth = ! ! this . matrix _homeserver _input . value && ! ! this . matrix _username _input . value && ! ! this . matrix _password _input . value ;
if ( ! definedMatrixAuth ) {
alert ( "Please set your Matrix account details." ) ;
return ;
}
}
if ( destinations . includes ( "comfyworkflows" ) && ! this . cw _sharekey _input . value && ! confirm ( "You have NOT set your ComfyWorkflows.com share key. Your art will NOT be connected to your account (it will be shared anonymously). Continue?" ) ) {
return ;
}
const { potential _outputs , potential _output _nodes } = getPotentialOutputsAndOutputNodes ( nodes ) ;
// console.log({ potential_outputs, potential_output_nodes })
if ( potential _outputs . length === 0 ) {
if ( potential _output _nodes . length === 0 ) {
// todo: add support for other output node types (animatediff combine, etc.)
const supported _nodes _string = SUPPORTED _OUTPUT _NODE _TYPES . join ( ", " ) ;
alert ( ` No supported output node found ( ${ supported _nodes _string } ). To share this workflow, please add an output node to your graph and re-run your prompt. ` ) ;
} else {
alert ( "To share this, first run a prompt. Once it's done, click 'Share'.\n\nNOTE: Images of the Share target can only be selected in the PreviewImage, SaveImage, and VHS_VideoCombine nodes. In the case of VHS_VideoCombine, only the image/gif and image/webp formats are supported." ) ;
}
this . selectedOutputIndex = 0 ;
this . close ( ) ;
return ;
}
// Change the text of the share button to "Sharing..." to indicate that the share process has started
this . share _button . textContent = "Sharing..." ;
const response = await api . fetchApi ( ` /manager/share ` , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' } ,
body : JSON . stringify ( {
matrix _auth : {
homeserver : this . matrix _homeserver _input . value ,
username : this . matrix _username _input . value ,
password : this . matrix _password _input . value ,
} ,
cw _auth : {
cw _sharekey : this . cw _sharekey _input . value ,
} ,
share _destinations : destinations ,
credits : this . credits _input . value ,
title : this . title _input . value ,
description : this . description _input . value ,
is _nsfw : this . is _nsfw _checkbox . checked ,
prompt ,
potential _outputs ,
selected _output _index : this . selectedOutputIndex ,
// potential_output_nodes
} )
} ) ;
if ( response . status != 200 ) {
try {
const response _json = await response . json ( ) ;
if ( response _json . error ) {
alert ( response _json . error ) ;
this . close ( ) ;
return ;
} else {
alert ( "Failed to share your art. Please try again." ) ;
this . close ( ) ;
return ;
}
} catch ( e ) {
alert ( "Failed to share your art. Please try again." ) ;
this . close ( ) ;
return ;
}
}
const response _json = await response . json ( ) ;
if ( response _json . comfyworkflows . url ) {
this . final _message . innerHTML = "Your art has been shared: <a href='" + response _json . comfyworkflows . url + "' target='_blank'>" + response _json . comfyworkflows . url + "</a>" ;
if ( response _json . matrix . success ) {
this . final _message . innerHTML += "<br>Your art has been shared in the ComfyUI Matrix server's #share channel!" ;
}
} else {
if ( response _json . matrix . success ) {
this . final _message . innerHTML = "Your art has been shared in the ComfyUI Matrix server's #share channel!" ;
}
}
this . final _message . style . color = "green" ;
// hide #comfyui-share-container and show #comfyui-share-finalmessage-container
this . share _container . style . display = "none" ;
this . share _finalmessage _container . style . display = "block" ;
// hide the share button
this . share _button . textContent = "Shared!" ;
this . share _button . style . display = "none" ;
// this.close();
}
const res =
[
$el ( "tr.td" , { width : "100%" } , [
$el ( "font" , { size : 6 , color : "white" } , [ ` Share your art ` ] ) ,
] ) ,
$el ( "br" , { } , [ ] ) ,
this . share _finalmessage _container ,
this . share _container ,
] ;
res [ 0 ] . style . padding = "10px 10px 10px 10px" ;
res [ 0 ] . style . backgroundColor = "black" ; //"linear-gradient(90deg, #00C9FF 0%, #92FE9D 100%)";
res [ 0 ] . style . textAlign = "center" ;
res [ 0 ] . style . height = "45px" ;
return res ;
}
show ( { potential _outputs , potential _output _nodes } ) {
// console.log({ potential_outputs, potential_output_nodes })
this . radio _buttons . innerHTML = "" ; // clear the radio buttons
const new _radio _buttons = $el ( "div" , {
id : "selectOutput-Options" ,
style : {
'overflow-y' : 'scroll' ,
'max-height' : '400px' ,
}
} , potential _outputs . map ( ( output , index ) => {
const radio _button = $el ( "input" , { type : 'radio' , name : "selectOutputImages" , value : index , required : index === 0 } , [ ] )
let radio _button _img ;
if ( output . type === "image" || output . type === "temp" ) {
radio _button _img = $el ( "img" , { src : ` /view?filename= ${ output . image . filename } &subfolder= ${ output . image . subfolder } &type= ${ output . image . type } ` , style : { width : "auto" , height : "100px" } } , [ ] ) ;
} else if ( output . type === "output" ) {
radio _button _img = $el ( "img" , { src : output . output . value , style : { width : "auto" , height : "100px" } } , [ ] ) ;
} else {
// unsupported output type
// this should never happen
// TODO
radio _button _img = $el ( "img" , { src : "" , style : { width : "auto" , height : "100px" } } , [ ] ) ;
}
const radio _button _text = $el ( "label" , {
// style: {
// color: 'white'
// }
} , [ output . title ] )
radio _button . style . color = "var(--fg-color)" ;
radio _button . checked = index === 0 ;
if ( radio _button . checked ) {
this . selectedOutputIndex = index ;
}
radio _button . onchange = ( ) => {
this . selectedOutputIndex = parseInt ( radio _button . value ) ;
} ;
return $el ( "div" , {
style : {
display : "flex" ,
'align-items' : 'center' ,
'justify-content' : 'space-between' ,
'margin-bottom' : '10px' ,
}
} , [ radio _button , radio _button _text , radio _button _img ] ) ;
} ) ) ;
const header = $el ( "h3" , {
textContent : "Select an image to share" ,
size : 3 ,
color : "white" ,
style : {
'text-align' : 'center' ,
color : 'white' ,
backgroundColor : 'black' ,
padding : '10px' ,
'margin-top' : '0px' ,
}
} , [
$el ( "p" , {
textContent : "Scroll to see all outputs" ,
size : 2 ,
color : "white" ,
style : {
'text-align' : 'center' ,
color : 'white' ,
'margin-bottom' : '5px' ,
'font-style' : 'italic' ,
'font-size' : '12px' ,
} ,
} , [ ] )
] ) ;
this . radio _buttons . appendChild ( header ) ;
// this.radio_buttons.appendChild(subheader);
this . radio _buttons . appendChild ( new _radio _buttons ) ;
this . element . style . display = "block" ;
}
}