mirror of
https://git.datalinker.icu/ltdrdata/ComfyUI-Manager
synced 2025-12-09 22:24:23 +08:00
feat: add ShareDialogChooser and OpenArtShareDialog basic UI
This commit is contained in:
parent
defe95c0e8
commit
f07fddcdad
@ -1,7 +1,7 @@
|
|||||||
import { app } from "../../scripts/app.js";
|
import { app } from "../../scripts/app.js";
|
||||||
import { api } from "../../scripts/api.js"
|
import { api } from "../../scripts/api.js"
|
||||||
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
||||||
import { ShareDialog, SUPPORTED_OUTPUT_NODE_TYPES, getPotentialOutputsAndOutputNodes } from "./comfyui-share.js";
|
import { ShareDialog, SUPPORTED_OUTPUT_NODE_TYPES, getPotentialOutputsAndOutputNodes, ShareDialogChooser } from "./comfyui-share-common.js";
|
||||||
import { CustomNodesInstaller } from "./custom-nodes-downloader.js";
|
import { CustomNodesInstaller } from "./custom-nodes-downloader.js";
|
||||||
import { AlternativesInstaller } from "./a1111-alter-downloader.js";
|
import { AlternativesInstaller } from "./a1111-alter-downloader.js";
|
||||||
import { SnapshotManager } from "./snapshot.js";
|
import { SnapshotManager } from "./snapshot.js";
|
||||||
@ -586,9 +586,13 @@ app.registerExtension({
|
|||||||
const shareButton = document.createElement("button");
|
const shareButton = document.createElement("button");
|
||||||
shareButton.textContent = "Share";
|
shareButton.textContent = "Share";
|
||||||
shareButton.onclick = () => {
|
shareButton.onclick = () => {
|
||||||
if (!ShareDialog.instance) {
|
|
||||||
ShareDialog.instance = new ShareDialog();
|
if(!ShareDialogChooser.instance) {
|
||||||
|
ShareDialogChooser.instance = new ShareDialogChooser();
|
||||||
}
|
}
|
||||||
|
// TODO: DEV ONLY, remove this line
|
||||||
|
ShareDialogChooser.instance.show({ potential_outputs : [], potential_output_nodes: [] });
|
||||||
|
return
|
||||||
|
|
||||||
app.graphToPrompt().then(prompt => {
|
app.graphToPrompt().then(prompt => {
|
||||||
// console.log({ prompt })
|
// console.log({ prompt })
|
||||||
@ -608,7 +612,7 @@ app.registerExtension({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareDialog.instance.show({ potential_outputs, potential_output_nodes });
|
ShareDialogChooser.instance.show({ potential_outputs, potential_output_nodes });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// make the background color a gradient of blue to green
|
// make the background color a gradient of blue to green
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { app } from "../../scripts/app.js";
|
import { app } from "../../scripts/app.js";
|
||||||
import { api } from "../../scripts/api.js"
|
import { api } from "../../scripts/api.js"
|
||||||
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
||||||
|
import { OpenArtShareDialog } from "./comfyui-share-openart.js";
|
||||||
|
|
||||||
export const SUPPORTED_OUTPUT_NODE_TYPES = [
|
export const SUPPORTED_OUTPUT_NODE_TYPES = [
|
||||||
"PreviewImage",
|
"PreviewImage",
|
||||||
@ -149,7 +150,198 @@ export function parseURLPath(urlPath) {
|
|||||||
// Return the object with the parsed parameters
|
// Return the object with the parsed parameters
|
||||||
return parsedParams;
|
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 {
|
export class ShareDialog extends ComfyDialog {
|
||||||
static instance = null;
|
static instance = null;
|
||||||
static matrix_auth = { homeserver: "matrix.org", username: "", password: "" };
|
static matrix_auth = { homeserver: "matrix.org", username: "", password: "" };
|
||||||
|
|||||||
124
js/comfyui-share-openart.js
Normal file
124
js/comfyui-share-openart.js
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import { app } from "../../scripts/app.js";
|
||||||
|
import { api } from "../../scripts/api.js"
|
||||||
|
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
||||||
|
|
||||||
|
const LOCAL_STORAGE_KEY = "openart_comfy_workflow_key";
|
||||||
|
|
||||||
|
export class OpenArtShareDialog 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()]),
|
||||||
|
]);
|
||||||
|
this.selectedOutputIndex = 0;
|
||||||
|
}
|
||||||
|
readKeyFromLocalStorage() {
|
||||||
|
return localStorage.getItem(LOCAL_STORAGE_KEY) || '';
|
||||||
|
}
|
||||||
|
saveKeyToLocalStorage(value) {
|
||||||
|
localStorage.setItem(LOCAL_STORAGE_KEY, value);
|
||||||
|
}
|
||||||
|
createButtons() {
|
||||||
|
const sectionStyle = {
|
||||||
|
marginBottom: '20px',
|
||||||
|
padding: '15px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.05)'
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputStyle = {
|
||||||
|
display: 'block',
|
||||||
|
minWidth: '500px',
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
margin: '10px 0',
|
||||||
|
borderRadius: '4px',
|
||||||
|
border: '1px solid #ddd',
|
||||||
|
boxSizing: 'border-box'
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerLabelStyle = {
|
||||||
|
color: "#f8f8f8",
|
||||||
|
display: 'block',
|
||||||
|
marginBottom: '15px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textDecoration: 'none',
|
||||||
|
fontSize: '20px',
|
||||||
|
};
|
||||||
|
|
||||||
|
const labelStyle = {
|
||||||
|
color: "#f8f8f8",
|
||||||
|
display: 'block',
|
||||||
|
marginBottom: '5px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textDecoration: 'none',
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttonStyle = {
|
||||||
|
padding: '10px 80px',
|
||||||
|
margin: '10px 5px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
border: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: '#fff',
|
||||||
|
backgroundColor: '#007bff'
|
||||||
|
};
|
||||||
|
|
||||||
|
this.keyInput = $el("input", { type: 'text', placeholder: "Share Your key", style: inputStyle })
|
||||||
|
// Account Section
|
||||||
|
const AccountSection = $el("div", { style: sectionStyle }, [
|
||||||
|
$el("a", { style: headerLabelStyle, href: "https://openart.ai/workflows" }, ["Check out 1000+ workflows others have uploaded."]),
|
||||||
|
$el("a", { style: headerLabelStyle, href: "https://openart.ai/workflows" }, ["You can get OpenArt key at https://openart.ai/"]),
|
||||||
|
$el("label", { style: labelStyle }, ["OpenArt API Key"]),
|
||||||
|
this.keyInput,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Additional Inputs Section
|
||||||
|
const additionalInputsSection = $el("div", { style: sectionStyle }, [
|
||||||
|
$el("label", { style: labelStyle }, ["Details"]),
|
||||||
|
$el("input", { type: "text", placeholder: "Title (required)", style: inputStyle }),
|
||||||
|
$el("textarea", { placeholder: "Description (optional)", style: {
|
||||||
|
...inputStyle,
|
||||||
|
minHeight: '100px',
|
||||||
|
} }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Share and Close Buttons
|
||||||
|
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(); } }),
|
||||||
|
$el("button", { type: "submit", textContent: "Share", style: buttonStyle, onclick: () => { this.share(); } }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Final Message Section
|
||||||
|
const finalMessage = $el("div", { style: { color: "white", textAlign: "center", padding: "10px" } }, []);
|
||||||
|
// Composing the full layout
|
||||||
|
const layout = [
|
||||||
|
AccountSection,
|
||||||
|
additionalInputsSection,
|
||||||
|
buttonsSection,
|
||||||
|
finalMessage,
|
||||||
|
];
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
async share() {
|
||||||
|
this.saveKeyToLocalStorage(this.keyInput.value);
|
||||||
|
}
|
||||||
|
show({ potential_outputs, potential_output_nodes }) {
|
||||||
|
this.element.style.display = "block";
|
||||||
|
// read key from local storage and set it to the input
|
||||||
|
const key = this.readKeyFromLocalStorage();
|
||||||
|
this.keyInput.value = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user