|
import { app } from "../../scripts/app.js"; |
|
import { $el, ComfyDialog } from "../../scripts/ui.js"; |
|
const env = "prod"; |
|
|
|
let DEFAULT_HOMEPAGE_URL = "https://copus.io"; |
|
|
|
let API_ENDPOINT = "https://api.client.prod.copus.io/copus-client"; |
|
|
|
if (env !== "prod") { |
|
API_ENDPOINT = "https://api.dev.copus.io/copus-client"; |
|
DEFAULT_HOMEPAGE_URL = "https://test.copus.io"; |
|
} |
|
|
|
const style = ` |
|
.copus-share-dialog a { |
|
color: #f8f8f8; |
|
} |
|
.copus-share-dialog a:hover { |
|
color: #007bff; |
|
} |
|
.output_label { |
|
border: 5px solid transparent; |
|
} |
|
.output_label:hover { |
|
border: 5px solid #59E8C6; |
|
} |
|
.output_label.checked { |
|
border: 5px solid #59E8C6; |
|
} |
|
`; |
|
|
|
|
|
const sectionStyle = { |
|
marginBottom: 0, |
|
padding: 0, |
|
borderRadius: "8px", |
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.05)", |
|
display: "flex", |
|
flexDirection: "column", |
|
justifyContent: "center", |
|
position: "relative", |
|
}; |
|
|
|
export class CopusShareDialog extends ComfyDialog { |
|
static instance = null; |
|
|
|
constructor() { |
|
super(); |
|
$el("style", { |
|
textContent: style, |
|
parent: document.head, |
|
}); |
|
this.element = $el( |
|
"div.comfy-modal.copus-share-dialog", |
|
{ |
|
parent: document.body, |
|
style: { |
|
"overflow-y": "auto", |
|
}, |
|
}, |
|
[$el("div.comfy-modal-content", {}, [...this.createButtons()])] |
|
); |
|
this.selectedOutputIndex = 0; |
|
this.selectedNodeId = null; |
|
this.uploadedImages = []; |
|
this.allFilesImages = []; |
|
this.selectedFile = null; |
|
this.allFiles = []; |
|
this.titleNum = 0; |
|
} |
|
|
|
createButtons() { |
|
const inputStyle = { |
|
display: "block", |
|
minWidth: "500px", |
|
width: "100%", |
|
padding: "10px", |
|
margin: "10px 0", |
|
borderRadius: "4px", |
|
border: "1px solid #ddd", |
|
boxSizing: "border-box", |
|
}; |
|
|
|
const textAreaStyle = { |
|
display: "block", |
|
minWidth: "500px", |
|
width: "100%", |
|
padding: "10px", |
|
margin: "10px 0", |
|
borderRadius: "4px", |
|
border: "1px solid #ddd", |
|
boxSizing: "border-box", |
|
minHeight: "100px", |
|
background: "#222", |
|
resize: "vertical", |
|
color: "#f2f2f2", |
|
fontFamily: "Arial", |
|
fontWeight: "400", |
|
fontSize: "15px", |
|
}; |
|
|
|
const hyperLinkStyle = { |
|
display: "block", |
|
marginBottom: "15px", |
|
fontWeight: "bold", |
|
fontSize: "14px", |
|
}; |
|
|
|
const labelStyle = { |
|
color: "#f8f8f8", |
|
display: "block", |
|
margin: "10px 0 0 0", |
|
fontWeight: "bold", |
|
textDecoration: "none", |
|
}; |
|
|
|
const buttonStyle = { |
|
padding: "10px 80px", |
|
margin: "10px 5px", |
|
borderRadius: "4px", |
|
border: "none", |
|
cursor: "pointer", |
|
color: "#fff", |
|
backgroundColor: "#007bff", |
|
}; |
|
|
|
|
|
this.uploadImagesInput = $el("input", { |
|
type: "file", |
|
multiple: false, |
|
style: inputStyle, |
|
accept: "image/*", |
|
}); |
|
|
|
this.uploadImagesInput.addEventListener("change", async (e) => { |
|
const file = e.target.files[0]; |
|
if (!file) { |
|
this.previewImage.src = ""; |
|
this.previewImage.style.display = "none"; |
|
return; |
|
} |
|
const reader = new FileReader(); |
|
reader.onload = async (e) => { |
|
const imgData = e.target.result; |
|
this.previewImage.src = imgData; |
|
this.previewImage.style.display = "block"; |
|
this.selectedFile = null; |
|
|
|
this.radioButtons.forEach((ele) => { |
|
ele.checked = false; |
|
ele.parentElement.classList.remove("checked"); |
|
}); |
|
|
|
|
|
|
|
this.outputsSection.style.opacity = 0.35; |
|
this.uploadImagesInput.style.opacity = 1; |
|
}; |
|
reader.readAsDataURL(file); |
|
}); |
|
|
|
|
|
this.previewImage = $el("img", { |
|
src: "", |
|
style: { |
|
width: "100%", |
|
maxHeight: "100px", |
|
objectFit: "contain", |
|
display: "none", |
|
marginTop: "10px", |
|
}, |
|
}); |
|
|
|
this.keyInput = $el("input", { |
|
type: "password", |
|
placeholder: "Copy & paste your API key", |
|
style: inputStyle, |
|
}); |
|
this.TitleInput = $el("input", { |
|
type: "text", |
|
placeholder: "Title (Required)", |
|
style: inputStyle, |
|
maxLength: "70", |
|
oninput: () => { |
|
const titleNum = this.TitleInput.value.length; |
|
titleNumDom.textContent = `${titleNum}/70`; |
|
}, |
|
}); |
|
this.SubTitleInput = $el("input", { |
|
type: "text", |
|
placeholder: "Subtitle (Optional)", |
|
style: inputStyle, |
|
maxLength: "70", |
|
oninput: () => { |
|
const titleNum = this.SubTitleInput.value.length; |
|
subTitleNumDom.textContent = `${titleNum}/70`; |
|
}, |
|
}); |
|
this.descriptionInput = $el("textarea", { |
|
placeholder: "Content (Optional)", |
|
style: { |
|
...textAreaStyle, |
|
minHeight: "100px", |
|
}, |
|
}); |
|
|
|
|
|
const headerSection = $el("h3", { |
|
textContent: "Share your workflow to Copus", |
|
size: 3, |
|
color: "white", |
|
style: { |
|
"text-align": "center", |
|
color: "white", |
|
margin: "0 0 10px 0", |
|
}, |
|
}); |
|
this.getAPIKeyLink = $el( |
|
"a", |
|
{ |
|
style: { |
|
...hyperLinkStyle, |
|
color: "#59E8C6", |
|
}, |
|
href: `${DEFAULT_HOMEPAGE_URL}?fromPage=comfyUI`, |
|
target: "_blank", |
|
}, |
|
["👉 Get your API key here"] |
|
); |
|
const linkSection = $el( |
|
"div", |
|
{ |
|
style: { |
|
marginTop: "10px", |
|
display: "flex", |
|
flexDirection: "column", |
|
}, |
|
}, |
|
[ |
|
|
|
this.getAPIKeyLink, |
|
] |
|
); |
|
|
|
|
|
const accountSection = $el("div", { style: sectionStyle }, [ |
|
$el("label", { style: labelStyle }, ["1️⃣ Copus API Key"]), |
|
this.keyInput, |
|
]); |
|
|
|
|
|
const outputUploadSection = $el("div", { style: sectionStyle }, [ |
|
$el( |
|
"label", |
|
{ |
|
style: { |
|
...labelStyle, |
|
margin: "10px 0 0 0", |
|
}, |
|
}, |
|
["2️⃣ Image/Thumbnail (Required)"] |
|
), |
|
this.previewImage, |
|
this.uploadImagesInput, |
|
]); |
|
|
|
|
|
this.outputsSection = $el( |
|
"div", |
|
{ |
|
id: "selectOutputs", |
|
}, |
|
[] |
|
); |
|
|
|
const titleNumDom = $el( |
|
"label", |
|
{ |
|
style: { |
|
fontSize: "12px", |
|
position: "absolute", |
|
right: "10px", |
|
bottom: "-10px", |
|
color: "#999", |
|
}, |
|
}, |
|
["0/70"] |
|
); |
|
const subTitleNumDom = $el( |
|
"label", |
|
{ |
|
style: { |
|
fontSize: "12px", |
|
position: "absolute", |
|
right: "10px", |
|
bottom: "-10px", |
|
color: "#999", |
|
}, |
|
}, |
|
["0/70"] |
|
); |
|
const descriptionNumDom = $el( |
|
"label", |
|
{ |
|
style: { |
|
fontSize: "12px", |
|
position: "absolute", |
|
right: "10px", |
|
bottom: "-10px", |
|
color: "#999", |
|
}, |
|
}, |
|
["0/70"] |
|
); |
|
|
|
const additionalInputsSection = $el( |
|
"div", |
|
{ style: { ...sectionStyle, } }, |
|
[ |
|
$el("label", { style: labelStyle }, ["3️⃣ Title "]), |
|
this.TitleInput, |
|
titleNumDom, |
|
] |
|
); |
|
const SubtitleSection = $el("div", { style: sectionStyle }, [ |
|
$el("label", { style: labelStyle }, ["4️⃣ Subtitle "]), |
|
this.SubTitleInput, |
|
subTitleNumDom, |
|
]); |
|
const DescriptionSection = $el("div", { style: sectionStyle }, [ |
|
$el("label", { style: labelStyle }, ["5️⃣ Description "]), |
|
this.descriptionInput, |
|
|
|
]); |
|
|
|
this.radioButtons = []; |
|
|
|
this.radioButtonsCheck = $el("input", { |
|
type: "radio", |
|
name: "output_type", |
|
value: "0", |
|
id: "blockchain1", |
|
checked: true, |
|
}); |
|
this.radioButtonsCheckOff = $el("input", { |
|
type: "radio", |
|
name: "output_type", |
|
value: "1", |
|
id: "blockchain", |
|
}); |
|
|
|
const blockChainSection = $el("div", { style: sectionStyle }, [ |
|
$el("label", { style: labelStyle }, ["6️⃣ Store on blockchain "]), |
|
$el( |
|
"label", |
|
{ |
|
style: { |
|
marginTop: "10px", |
|
display: "flex", |
|
alignItems: "center", |
|
cursor: "pointer", |
|
}, |
|
}, |
|
[ |
|
this.radioButtonsCheck, |
|
$el("span", { style: { marginLeft: "5px" } }, ["ON"]), |
|
] |
|
), |
|
$el( |
|
"label", |
|
{ style: { display: "flex", alignItems: "center", cursor: "pointer" } }, |
|
[ |
|
this.radioButtonsCheckOff, |
|
$el("span", { style: { marginLeft: "5px" } }, ["OFF"]), |
|
] |
|
), |
|
$el( |
|
"p", |
|
{ style: { fontSize: "16px", color: "#fff", margin: "10px 0 0 0" } }, |
|
["Secure ownership with a permanent & decentralized storage"] |
|
), |
|
]); |
|
|
|
this.message = $el( |
|
"div", |
|
{ |
|
style: { |
|
color: "#ff3d00", |
|
textAlign: "center", |
|
padding: "10px", |
|
fontSize: "20px", |
|
}, |
|
}, |
|
[] |
|
); |
|
|
|
this.shareButton = $el("button", { |
|
type: "submit", |
|
textContent: "Share", |
|
style: buttonStyle, |
|
onclick: () => { |
|
this.handleShareButtonClick(); |
|
}, |
|
}); |
|
|
|
|
|
const buttonsSection = $el( |
|
"div", |
|
{ |
|
style: { |
|
textAlign: "right", |
|
marginTop: "20px", |
|
display: "flex", |
|
justifyContent: "space-between", |
|
}, |
|
}, |
|
[ |
|
$el("button", { |
|
type: "button", |
|
textContent: "Close", |
|
style: { |
|
...buttonStyle, |
|
backgroundColor: undefined, |
|
}, |
|
onclick: () => { |
|
this.close(); |
|
}, |
|
}), |
|
this.shareButton, |
|
] |
|
); |
|
|
|
|
|
const layout = [ |
|
headerSection, |
|
linkSection, |
|
accountSection, |
|
outputUploadSection, |
|
this.outputsSection, |
|
additionalInputsSection, |
|
SubtitleSection, |
|
DescriptionSection, |
|
|
|
blockChainSection, |
|
this.message, |
|
buttonsSection, |
|
]; |
|
|
|
return layout; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async fetchApi(path, options, statusText) { |
|
if (statusText) { |
|
this.message.textContent = statusText; |
|
} |
|
const fullPath = new URL(API_ENDPOINT + path); |
|
const response = await fetch(fullPath, options); |
|
if (!response.ok) { |
|
throw new Error(response.statusText); |
|
} |
|
if (statusText) { |
|
this.message.textContent = ""; |
|
} |
|
const data = await response.json(); |
|
return { |
|
ok: response.ok, |
|
statusText: response.statusText, |
|
status: response.status, |
|
data, |
|
}; |
|
} |
|
|
|
|
|
|
|
async uploadThumbnail(uploadFile, type) { |
|
const form = new FormData(); |
|
form.append("file", uploadFile); |
|
form.append("apiToken", this.keyInput.value); |
|
try { |
|
const res = await this.fetchApi( |
|
`/client/common/opus/uploadImage`, |
|
{ |
|
method: "POST", |
|
body: form, |
|
}, |
|
"Uploading thumbnail..." |
|
); |
|
if (res.status && res.data.status && res.data) { |
|
const { data } = res.data; |
|
if (type) { |
|
this.allFilesImages.push({ |
|
url: data, |
|
}); |
|
} |
|
this.uploadedImages.push({ |
|
url: data, |
|
}); |
|
} else { |
|
throw new Error("make sure your API key is correct and try again later"); |
|
} |
|
} catch (e) { |
|
if (e?.response?.status === 413) { |
|
throw new Error("File size is too large (max 20MB)"); |
|
} else { |
|
throw new Error("Error uploading thumbnail: " + e.message); |
|
} |
|
} |
|
} |
|
|
|
async handleShareButtonClick() { |
|
this.message.textContent = ""; |
|
try { |
|
this.shareButton.disabled = true; |
|
this.shareButton.textContent = "Sharing..."; |
|
await this.share(); |
|
} catch (e) { |
|
alert(e.message); |
|
} |
|
this.shareButton.disabled = false; |
|
this.shareButton.textContent = "Share"; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async share() { |
|
const prompt = await app.graphToPrompt(); |
|
const workflowJSON = prompt["workflow"]; |
|
const form_values = { |
|
title: this.TitleInput.value, |
|
subTitle: this.SubTitleInput.value, |
|
content: this.descriptionInput.value, |
|
storeOnChain: this.radioButtonsCheck.checked ? true : false, |
|
}; |
|
|
|
if (!this.keyInput.value) { |
|
throw new Error("API key is required"); |
|
} |
|
|
|
if (!this.uploadImagesInput.files[0] && !this.selectedFile) { |
|
throw new Error("Thumbnail is required"); |
|
} |
|
|
|
if (!form_values.title) { |
|
throw new Error("Title is required"); |
|
} |
|
|
|
if (!this.uploadedImages.length) { |
|
if (this.selectedFile) { |
|
await this.uploadThumbnail(this.selectedFile); |
|
} else { |
|
for (const file of this.uploadImagesInput.files) { |
|
try { |
|
await this.uploadThumbnail(file); |
|
} catch (e) { |
|
this.uploadedImages = []; |
|
throw new Error(e.message); |
|
} |
|
} |
|
|
|
if (this.uploadImagesInput.files.length === 0) { |
|
throw new Error("No thumbnail uploaded"); |
|
} |
|
} |
|
} |
|
if (this.allFiles.length > 0) { |
|
for (const file of this.allFiles) { |
|
try { |
|
await this.uploadThumbnail(file, true); |
|
} catch (e) { |
|
this.allFilesImages = []; |
|
throw new Error(e.message); |
|
} |
|
} |
|
} |
|
try { |
|
const res = await this.fetchApi( |
|
"/client/common/opus/shareFromComfyUI", |
|
{ |
|
method: "POST", |
|
headers: { "Content-Type": "application/json" }, |
|
body: JSON.stringify({ |
|
workflowJson: workflowJSON, |
|
apiToken: this.keyInput.value, |
|
coverUrl: this.uploadedImages[0].url, |
|
imageUrls: this.allFilesImages.map((image) => image.url), |
|
...form_values, |
|
}), |
|
}, |
|
"Uploading workflow..." |
|
); |
|
|
|
if (res.status && res.data.status && res.data) { |
|
localStorage.setItem("copus_token",this.keyInput.value); |
|
const { data } = res.data; |
|
if (data) { |
|
const url = `${DEFAULT_HOMEPAGE_URL}/work/${data}`; |
|
this.message.innerHTML = `Workflow has been shared successfully. <a href="${url}" target="_blank">Click here to view it.</a>`; |
|
this.previewImage.src = ""; |
|
this.previewImage.style.display = "none"; |
|
this.uploadedImages = []; |
|
this.allFilesImages = []; |
|
this.allFiles = []; |
|
this.TitleInput.value = ""; |
|
this.SubTitleInput.value = ""; |
|
this.descriptionInput.value = ""; |
|
this.selectedFile = null; |
|
} |
|
} |
|
} catch (e) { |
|
throw new Error("Error sharing workflow: " + e.message); |
|
} |
|
} |
|
|
|
async fetchImageBlob(url) { |
|
const response = await fetch(url); |
|
const blob = await response.blob(); |
|
return blob; |
|
} |
|
|
|
async show({ potential_outputs, potential_output_nodes } = {}) { |
|
|
|
|
|
|
|
const potential_output_to_order = {}; |
|
potential_output_nodes.forEach((node, index) => { |
|
if (node.id in potential_output_to_order) { |
|
potential_output_to_order[node.id][1].push(potential_outputs[index]); |
|
} else { |
|
potential_output_to_order[node.id] = [node, [potential_outputs[index]]]; |
|
} |
|
}); |
|
|
|
const sorted_potential_output_to_order = Object.fromEntries( |
|
Object.entries(potential_output_to_order).sort( |
|
(a, b) => a[0].id - b[0].id |
|
) |
|
); |
|
const sorted_potential_outputs = []; |
|
const sorted_potential_output_nodes = []; |
|
for (const [key, value] of Object.entries( |
|
sorted_potential_output_to_order |
|
)) { |
|
sorted_potential_output_nodes.push(value[0]); |
|
sorted_potential_outputs.push(...value[1]); |
|
} |
|
potential_output_nodes = sorted_potential_output_nodes; |
|
potential_outputs = sorted_potential_outputs; |
|
const apiToken = localStorage.getItem("copus_token"); |
|
this.message.innerHTML = ""; |
|
this.message.textContent = ""; |
|
this.element.style.display = "block"; |
|
this.previewImage.src = ""; |
|
this.previewImage.style.display = "none"; |
|
this.keyInput.value = apiToken!=null?apiToken:""; |
|
this.uploadedImages = []; |
|
this.allFilesImages = []; |
|
this.allFiles = []; |
|
|
|
|
|
|
|
if (this.selectedNodeId) { |
|
const index = potential_output_nodes.findIndex( |
|
(node) => node.id === this.selectedNodeId |
|
); |
|
if (index >= 0) { |
|
this.selectedOutputIndex = index; |
|
} |
|
} |
|
|
|
this.radioButtons = []; |
|
const new_radio_buttons = $el( |
|
"div", |
|
{ |
|
id: "selectOutput-Options", |
|
style: { |
|
"overflow-y": "scroll", |
|
"max-height": "200px", |
|
display: "grid", |
|
"grid-template-columns": "repeat(auto-fit, minmax(100px, 1fr))", |
|
"grid-template-rows": "auto", |
|
"grid-column-gap": "10px", |
|
"grid-row-gap": "10px", |
|
"margin-bottom": "10px", |
|
padding: "10px", |
|
"border-radius": "8px", |
|
"box-shadow": "0 2px 4px rgba(0, 0, 0, 0.05)", |
|
"background-color": "var(--bg-color)", |
|
}, |
|
}, |
|
potential_outputs.map((output, index) => { |
|
const { node_id } = output; |
|
const radio_button = $el( |
|
"input", |
|
{ |
|
type: "radio", |
|
name: "selectOutputImages", |
|
value: index, |
|
required: index === 0, |
|
}, |
|
[] |
|
); |
|
let radio_button_img; |
|
let filename; |
|
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: "100px", |
|
height: "100px", |
|
objectFit: "cover", |
|
borderRadius: "5px", |
|
}, |
|
}, |
|
[] |
|
); |
|
filename = output.image.filename; |
|
} else if (output.type === "output") { |
|
radio_button_img = $el( |
|
"img", |
|
{ |
|
src: output.output.value, |
|
style: { |
|
width: "auto", |
|
height: "100px", |
|
objectFit: "cover", |
|
borderRadius: "5px", |
|
}, |
|
}, |
|
[] |
|
); |
|
filename = output.filename; |
|
} else { |
|
|
|
|
|
radio_button_img = $el( |
|
"img", |
|
{ |
|
src: "", |
|
style: { width: "auto", height: "100px" }, |
|
}, |
|
[] |
|
); |
|
} |
|
const radio_button_text = $el( |
|
"span", |
|
{ |
|
style: { |
|
color: "gray", |
|
display: "block", |
|
fontSize: "12px", |
|
overflowX: "hidden", |
|
textOverflow: "ellipsis", |
|
textWrap: "nowrap", |
|
maxWidth: "100px", |
|
}, |
|
}, |
|
[output.title] |
|
); |
|
const node_id_chip = $el( |
|
"span", |
|
{ |
|
style: { |
|
color: "#FBFBFD", |
|
display: "block", |
|
backgroundColor: "rgba(0, 0, 0, 0.5)", |
|
fontSize: "12px", |
|
overflowX: "hidden", |
|
padding: "2px 3px", |
|
textOverflow: "ellipsis", |
|
textWrap: "nowrap", |
|
maxWidth: "100px", |
|
position: "absolute", |
|
top: "3px", |
|
left: "3px", |
|
borderRadius: "3px", |
|
}, |
|
}, |
|
[`Node: ${node_id}`] |
|
); |
|
radio_button.style.color = "var(--fg-color)"; |
|
radio_button.checked = this.selectedOutputIndex === index; |
|
|
|
radio_button.onchange = async () => { |
|
this.selectedOutputIndex = parseInt(radio_button.value); |
|
|
|
|
|
this.radioButtons.forEach((ele) => { |
|
ele.parentElement.classList.remove("checked"); |
|
}); |
|
radio_button.parentElement.classList.add("checked"); |
|
|
|
this.fetchImageBlob(radio_button_img.src).then((blob) => { |
|
const file = new File([blob], filename, { |
|
type: blob.type, |
|
}); |
|
this.previewImage.src = radio_button_img.src; |
|
this.previewImage.style.display = "block"; |
|
this.selectedFile = file; |
|
}); |
|
|
|
|
|
|
|
this.outputsSection.style.opacity = 1; |
|
this.uploadImagesInput.style.opacity = 0.35; |
|
}; |
|
|
|
if (radio_button.checked) { |
|
this.fetchImageBlob(radio_button_img.src).then((blob) => { |
|
const file = new File([blob], filename, { |
|
type: blob.type, |
|
}); |
|
this.previewImage.src = radio_button_img.src; |
|
this.previewImage.style.display = "block"; |
|
this.selectedFile = file; |
|
}); |
|
|
|
|
|
this.outputsSection.style.opacity = 1; |
|
this.uploadImagesInput.style.opacity = 0.35; |
|
} |
|
this.radioButtons.push(radio_button); |
|
let src = ""; |
|
if (output.type === "image" || output.type === "temp") { |
|
filename = output.image.filename; |
|
src = `/view?filename=${output.image.filename}&subfolder=${output.image.subfolder}&type=${output.image.type}`; |
|
} else if (output.type === "output") { |
|
src = output.output.value; |
|
filename = output.filename; |
|
} |
|
if (src) { |
|
this.fetchImageBlob(src).then((blob) => { |
|
const file = new File([blob], filename, { |
|
type: blob.type, |
|
}); |
|
this.allFiles.push(file); |
|
}); |
|
} |
|
return $el( |
|
`label.output_label${radio_button.checked ? ".checked" : ""}`, |
|
{ |
|
style: { |
|
display: "flex", |
|
flexDirection: "column", |
|
alignItems: "center", |
|
justifyContent: "center", |
|
marginBottom: "10px", |
|
cursor: "pointer", |
|
position: "relative", |
|
}, |
|
}, |
|
[radio_button_img, radio_button_text, radio_button, node_id_chip] |
|
); |
|
}) |
|
); |
|
|
|
const header = $el( |
|
"p", |
|
{ |
|
textContent: |
|
this.radioButtons.length === 0 |
|
? "Queue Prompt to see the outputs" |
|
: "Or choose one from the outputs (scroll to see all)", |
|
size: 2, |
|
color: "white", |
|
style: { |
|
color: "white", |
|
margin: "0 0 5px 0", |
|
fontSize: "12px", |
|
}, |
|
}, |
|
[] |
|
); |
|
this.outputsSection.innerHTML = ""; |
|
this.outputsSection.appendChild(header); |
|
this.outputsSection.appendChild(new_radio_buttons); |
|
} |
|
} |
|
|