Disable interaction, read only checkboxes
This commit is contained in:
@@ -5,17 +5,22 @@
|
||||
import { Button } from "@gradio/button";
|
||||
import ComfyUIPane from "./ComfyUIPane.svelte";
|
||||
import ComfyApp, { type SerializedAppState } from "./ComfyApp";
|
||||
import { Checkbox } from "@gradio/form"
|
||||
import widgetState from "$lib/stores/widgetState";
|
||||
import { ImageViewer } from "$lib/ImageViewer";
|
||||
import { download } from "$lib/utils"
|
||||
|
||||
import { LGraph, LGraphNode } from "@litegraph-ts/core";
|
||||
import LightboxModal from "./LightboxModal.svelte";
|
||||
import { Block } from "@gradio/atoms";
|
||||
|
||||
let app: ComfyApp = undefined;
|
||||
let imageViewer: ImageViewer;
|
||||
let uiPane: ComfyUIPane = undefined;
|
||||
let mainElem: HTMLDivElement;
|
||||
let containerElem: HTMLDivElement;
|
||||
let nodesLocked: boolean = false;
|
||||
let graphLocked: boolean = false;
|
||||
let resizeTimeout: typeof Timer = -1;
|
||||
|
||||
function refreshView(event?: Event) {
|
||||
@@ -29,6 +34,9 @@
|
||||
app.queuePrompt(0, 1, state);
|
||||
}
|
||||
|
||||
$: if (app) app.lCanvas.allow_dragnodes = !nodesLocked;
|
||||
$: if (app) app.lCanvas.allow_interaction = !graphLocked;
|
||||
|
||||
let graphSize = null;
|
||||
|
||||
function toggleGraph() {
|
||||
@@ -55,7 +63,8 @@
|
||||
|
||||
let graphResizeTimer: typeof Timer = -1;
|
||||
|
||||
function serializeAppState(graph: LGraph): SerializedAppState {
|
||||
function serializeAppState(): SerializedAppState {
|
||||
const graph = app.lGraph;
|
||||
const frontendState = get(widgetState);
|
||||
|
||||
const serializedGraph = graph.serialize()
|
||||
@@ -79,6 +88,7 @@
|
||||
}
|
||||
|
||||
return {
|
||||
createdBy: "ComfyBox",
|
||||
version: 1,
|
||||
workflow: serializedGraph,
|
||||
panes: serializedPaneOrder
|
||||
@@ -86,7 +96,7 @@
|
||||
}
|
||||
|
||||
function doAutosave(graph: LGraph): void {
|
||||
const savedWorkflow = serializeAppState(graph);
|
||||
const savedWorkflow = serializeAppState();
|
||||
localStorage.setItem("workflow", JSON.stringify(savedWorkflow))
|
||||
}
|
||||
|
||||
@@ -94,6 +104,16 @@
|
||||
uiPane.restore(workflow.panes);
|
||||
}
|
||||
|
||||
function doSave(): void {
|
||||
if (!app?.lGraph)
|
||||
return;
|
||||
|
||||
const date = new Date();
|
||||
const formattedDate = date.toISOString().replace(/:/g, '-').replace(/\.\d{3}/g, '').replace('T', '_').replace("Z", "");
|
||||
|
||||
download(`workflow-${formattedDate}.json`, JSON.stringify(serializeAppState()), "application/json")
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
app = new ComfyApp();
|
||||
|
||||
@@ -155,9 +175,11 @@
|
||||
<Button variant="secondary" on:click={toggleSidebar}>
|
||||
Toggle Sidebar
|
||||
</Button>
|
||||
<Button variant="secondary" on:click={() => { if (app?.lGraph) doAutosave(app.lGraph) }}>
|
||||
<Button variant="secondary" on:click={doSave}>
|
||||
Save
|
||||
</Button>
|
||||
<Checkbox label="Lock Nodes" bind:value={nodesLocked}/>
|
||||
<Checkbox label="Disable Interaction" bind:value={graphLocked}/>
|
||||
</div>
|
||||
<LightboxModal />
|
||||
</div>
|
||||
@@ -187,6 +209,9 @@
|
||||
}
|
||||
|
||||
#bottombar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--layout-gap);
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export type SerializedPanes = {
|
||||
}
|
||||
|
||||
export type SerializedAppState = {
|
||||
createdBy: "ComfyBox",
|
||||
version: number,
|
||||
panes: SerializedPanes,
|
||||
workflow: SerializedLGraph
|
||||
|
||||
13
src/lib/utils.ts
Normal file
13
src/lib/utils.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export function download(filename: string, text: string, type: string = "text/plain") {
|
||||
const blob = new Blob([text], { type: type });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = filename
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
setTimeout(function() {
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
}, 0);
|
||||
}
|
||||
@@ -1,23 +1,31 @@
|
||||
<script lang="ts">
|
||||
import type { WidgetUIState } from "$lib/stores/widgetState";
|
||||
import { BlockTitle } from "@gradio/atoms";
|
||||
import { Dropdown } from "@gradio/form";
|
||||
import Select from 'svelte-select';
|
||||
export let item: WidgetUIState | null = null;
|
||||
|
||||
let option: any = null;
|
||||
|
||||
$: if(item && !option) option = item.value;
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
{#if item}
|
||||
<Dropdown
|
||||
bind:value={item.value}
|
||||
choices={item.widget.options.values}
|
||||
multiselect={false}
|
||||
max_choices={1}
|
||||
label={item.widget.name}
|
||||
show_label={true}
|
||||
disabled={item.widget.options.values.length === 0}
|
||||
on:change
|
||||
on:select
|
||||
on:blur
|
||||
/>
|
||||
<label>
|
||||
<BlockTitle show_label={true}>{item.widget.name}</BlockTitle>
|
||||
<Select
|
||||
bind:value={option}
|
||||
bind:justValue={item.value}
|
||||
bind:items={item.widget.options.values}
|
||||
disabled={item.widget.options.values.length === 0}
|
||||
clearable={false}
|
||||
on:change
|
||||
on:select
|
||||
on:filter
|
||||
on:blur
|
||||
/>
|
||||
</label>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -26,4 +34,8 @@
|
||||
padding: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:global(.svelte-select-list) {
|
||||
z-index: var(--layer-5) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user