Workflow saving/loading

This commit is contained in:
space-nuko
2023-05-06 21:39:21 -05:00
parent 2a2d04803b
commit da65d1b439
6 changed files with 78 additions and 18 deletions

View File

@@ -21,6 +21,7 @@
import queueState from "$lib/stores/queueState"; import queueState from "$lib/stores/queueState";
import ComfyUnlockUIButton from "./ComfyUnlockUIButton.svelte"; import ComfyUnlockUIButton from "./ComfyUnlockUIButton.svelte";
import ComfyGraphView from "./ComfyGraphView.svelte"; import ComfyGraphView from "./ComfyGraphView.svelte";
import { download } from "$lib/utils";
export let app: ComfyApp = undefined; export let app: ComfyApp = undefined;
let imageViewer: ImageViewer; let imageViewer: ImageViewer;
@@ -32,6 +33,7 @@
let resizeTimeout: NodeJS.Timeout | null; let resizeTimeout: NodeJS.Timeout | null;
let hasShownUIHelpToast: boolean = false; let hasShownUIHelpToast: boolean = false;
let uiTheme: string = ""; let uiTheme: string = "";
let fileInput: HTMLInputElement = undefined;
let debugLayout: boolean = false; let debugLayout: boolean = false;
@@ -100,6 +102,43 @@
if (!app?.lGraph) if (!app?.lGraph)
return; return;
const promptFilename = false; // TODO
let filename = "workflow.json";
if (promptFilename) {
filename = prompt("Save workflow as:", filename);
if (!filename) return;
if (!filename.toLowerCase().endsWith(".json")) {
filename += ".json";
}
}
else {
const date = new Date();
const formattedDate = date.toISOString().replace(/:/g, '-').replace(/\.\d{3}/g, '').replace('T', '_').replace("Z", "");
filename = `workflow-${formattedDate}.json`
}
const indent = 2
const json = JSON.stringify(app.serialize(), null, indent)
download(filename, json, "application/json")
}
function doLoad(): void {
if (!app?.lGraph || !fileInput)
return;
fileInput.click();
}
function loadWorkflow(): void {
app.handleFile(fileInput.files[0]);
}
function doSaveLocal(): void {
if (!app?.lGraph)
return;
app.saveStateToLocalStorage(); app.saveStateToLocalStorage();
toast.push("Saved to local storage.") toast.push("Saved to local storage.")
// //
@@ -109,13 +148,6 @@
// download(`workflow-${formattedDate}.json`, JSON.stringify(app.serialize()), "application/json") // download(`workflow-${formattedDate}.json`, JSON.stringify(app.serialize()), "application/json")
} }
function doReset(): void {
var confirmed = confirm("Are you sure you want to clear the current workflow?");
if (confirmed) {
app.reset();
}
}
async function doLoadDefault(): void { async function doLoadDefault(): void {
var confirmed = confirm("Are you sure you want to clear the current workflow and load the default graph?"); var confirmed = confirm("Are you sure you want to clear the current workflow and load the default graph?");
if (confirmed) { if (confirmed) {
@@ -123,6 +155,13 @@
} }
} }
function doClear(): void {
var confirmed = confirm("Are you sure you want to clear the current workflow?");
if (confirmed) {
app.clear();
}
}
$: if ($uiState.uiUnlocked && !hasShownUIHelpToast) { $: if ($uiState.uiUnlocked && !hasShownUIHelpToast) {
hasShownUIHelpToast = true; hasShownUIHelpToast = true;
toast.push("Right-click to open context menu.") toast.push("Right-click to open context menu.")
@@ -222,8 +261,14 @@
<Button variant="secondary" on:click={doSave}> <Button variant="secondary" on:click={doSave}>
Save Save
</Button> </Button>
<Button variant="secondary" on:click={doReset}> <Button variant="secondary" on:click={doSaveLocal}>
Reset Save Local
</Button>
<Button variant="secondary" on:click={doLoad}>
Load
</Button>
<Button variant="secondary" on:click={doClear}>
Clear
</Button> </Button>
<Button variant="secondary" on:click={doLoadDefault}> <Button variant="secondary" on:click={doLoadDefault}>
Load Default Load Default
@@ -255,6 +300,7 @@
</div> </div>
</div> </div>
<LightboxModal /> <LightboxModal />
<input bind:this={fileInput} id="comfy-file-input" type="file" accept=".json" on:change={loadWorkflow} />
</div> </div>
<SvelteToast options={toastOptions} /> <SvelteToast options={toastOptions} />
@@ -358,4 +404,8 @@
span.left { span.left {
right: 0px; right: 0px;
} }
#comfy-file-input {
display: none;
}
</style> </style>

View File

@@ -404,7 +404,7 @@ export default class ComfyApp {
} }
} }
reset() { clear() {
this.clean(); this.clean();
const blankGraph: SerializedLGraph = { const blankGraph: SerializedLGraph = {
@@ -634,16 +634,21 @@ export default class ComfyApp {
if (file.type === "image/png") { if (file.type === "image/png") {
const pngInfo = await getPngMetadata(file); const pngInfo = await getPngMetadata(file);
if (pngInfo) { if (pngInfo) {
if (pngInfo.workflow) { if (pngInfo.comfyBoxConfig) {
this.loadGraphData(JSON.parse(pngInfo.workflow)); this.deserialize(JSON.parse(pngInfo.comfyBoxConfig));
} else if (pngInfo.parameters) { } else if (pngInfo.parameters) {
importA1111(this.lGraph, pngInfo.parameters, this.api); throw "TODO import A111 import!"
// importA1111(this.lGraph, pngInfo.parameters, this.api);
}
else {
console.error("No metadata found in image file.", pngInfo)
toast.push("No metadata found in image file.")
} }
} }
} else if (file.type === "application/json" || file.name.endsWith(".json")) { } else if (file.type === "application/json" || file.name.endsWith(".json")) {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = () => { reader.onload = () => {
this.loadGraphData(JSON.parse(reader.result as string)); this.deserialize(JSON.parse(reader.result as string));
}; };
reader.readAsText(file); reader.readAsText(file);
} }

View File

@@ -33,7 +33,8 @@ export default class ComfyValueControl extends ComfyGraphNode {
{ name: "step", type: "number" } { name: "step", type: "number" }
], ],
outputs: [ outputs: [
{ name: "value", type: "*" } { name: "value", type: "*" },
{ name: "changed", type: BuiltInSlotType.EVENT }
], ],
} }
@@ -93,6 +94,7 @@ export default class ComfyValueControl extends ComfyGraphNode {
v = clamp(v, min, max) v = clamp(v, min, max)
this.setProperty("value", v) this.setProperty("value", v)
this.triggerSlot(1, v)
this.setOutputData(0, v) this.setOutputData(0, v)
console.debug("ValueControl", v, this.properties) console.debug("ValueControl", v, this.properties)

View File

@@ -101,7 +101,7 @@ export abstract class ComfyWidgetNode<T = any> extends ComfyGraphNode {
if (this.changedIndex !== null && this.outputs.length >= this.changedIndex) { if (this.changedIndex !== null && this.outputs.length >= this.changedIndex) {
const changedOutput = this.outputs[this.changedIndex] const changedOutput = this.outputs[this.changedIndex]
if (changedOutput.type === BuiltInSlotType.EVENT) if (changedOutput.type === BuiltInSlotType.EVENT)
this.triggerSlot(this.changedIndex, "changed") this.triggerSlot(this.changedIndex, get(this.value))
} }
} }

View File

@@ -790,7 +790,10 @@ function initDefaultLayout() {
currentSelection: [], currentSelection: [],
currentSelectionNodes: [], currentSelectionNodes: [],
isMenuOpen: false, isMenuOpen: false,
isConfiguring: false isConfiguring: false,
attrs: {
defaultSubgraph: ""
}
}) })
const root = addContainer(null, { direction: "horizontal", title: "" }); const root = addContainer(null, { direction: "horizontal", title: "" });