From 8d031120f79cacf07fb7d960135a638a46628de6 Mon Sep 17 00:00:00 2001 From: space-nuko <24979496+space-nuko@users.noreply.github.com> Date: Sat, 20 May 2023 20:46:36 -0500 Subject: [PATCH] Workflow title --- src/lib/components/ComfyApp.ts | 11 +++++- src/lib/components/ComfyWorkflowsView.svelte | 41 +++++++++++++------- src/lib/defaultGraph.ts | 1 + src/lib/stores/layoutStates.ts | 2 +- src/lib/stores/workflowState.ts | 22 +++++++---- src/mobile/routes/home.svelte | 4 +- 6 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/lib/components/ComfyApp.ts b/src/lib/components/ComfyApp.ts index e2a2daf..158af72 100644 --- a/src/lib/components/ComfyApp.ts +++ b/src/lib/components/ComfyApp.ts @@ -80,6 +80,8 @@ export type SerializedAppState = { commitHash?: string, /** Graph state */ workflow: SerializedLGraph, + /** Workflow name */ + workflowName: string, /** UI state */ layout: SerializedLayoutState, /** Position/offset of the canvas at the time of saving */ @@ -197,7 +199,7 @@ export default class ComfyApp { // We failed to restore a workflow so load the default if (!restored) { - await this.initDefaultGraph(); + await this.initDefaultWorkflow(); } workflowState.createNewWorkflow(this.lCanvas); @@ -522,7 +524,12 @@ export default class ComfyApp { selectionState.clear(); } - async initDefaultGraph() { + closeWorkflow(index: number) { + workflowState.closeWorkflow(this.lCanvas, index); + selectionState.clear(); + } + + async initDefaultWorkflow() { let state = null; try { const graphResponse = await fetch("/workflows/defaultWorkflow.json"); diff --git a/src/lib/components/ComfyWorkflowsView.svelte b/src/lib/components/ComfyWorkflowsView.svelte index 8949dea..118d3d8 100644 --- a/src/lib/components/ComfyWorkflowsView.svelte +++ b/src/lib/components/ComfyWorkflowsView.svelte @@ -144,17 +144,16 @@ } async function doLoadDefault() { - var confirmed = confirm("Are you sure you want to clear the current workflow and load the default graph?"); + var confirmed = confirm("Would you like to load the default workflow in a new tab?"); if (confirmed) { - await app.initDefaultGraph(); + await app.initDefaultWorkflow(); } } - function doClear(): void { - var confirmed = confirm("Are you sure you want to clear the current workflow?"); - if (confirmed) { - app.clear(); - } + function closeWorkflow(event: Event, index: number) { + event.preventDefault(); + event.stopImmediatePropagation() + app.closeWorkflow(index); } @@ -190,7 +189,11 @@ {/each} @@ -220,9 +223,6 @@ - @@ -371,14 +371,15 @@ border-left: 1px solid var(--neutral-600); display: flex; - flex-direction: column; + flex-direction: row; justify-content: center; + gap: var(--size-2); &:last-child { border-right: 1px solid var(--neutral-600); } - &:hover { + &:hover:not(:has(.workflow-close-button:hover)) { background: var(--neutral-700); color: var(--neutral-300); } @@ -388,6 +389,20 @@ color: var(--neutral-300); border-top-color: var(--primary-500); } + + > .workflow-close-button { + display:block; + width: 1.5rem; + height: 1.5rem; + border-radius: 50%; + background: var(--neutral-500); + color: var(--neutral-300); + + &:hover { + background: var(--neutral-400); + color: var(--neutral-100); + } + } } } diff --git a/src/lib/defaultGraph.ts b/src/lib/defaultGraph.ts index 9becb14..8892832 100644 --- a/src/lib/defaultGraph.ts +++ b/src/lib/defaultGraph.ts @@ -3,6 +3,7 @@ import type { SerializedAppState } from "./components/ComfyApp" const blankGraph: SerializedAppState = { createdBy: "ComfyBox", version: 1, + workflowName: "New Workflow", workflow: { last_node_id: 0, last_link_id: 0, diff --git a/src/lib/stores/layoutStates.ts b/src/lib/stores/layoutStates.ts index 07358d0..537dae4 100644 --- a/src/lib/stores/layoutStates.ts +++ b/src/lib/stores/layoutStates.ts @@ -1208,7 +1208,7 @@ function create(workflow: ComfyWorkflow): WritableLayoutStateStore { function remove(workflowID: WorkflowInstID) { const state = get(layoutStates) - if (layoutStates[workflowID] == null) + if (state.all[workflowID] == null) throw new Error(`No workflow with ID registered! ${workflowID}`) delete state.all[workflowID]; } diff --git a/src/lib/stores/workflowState.ts b/src/lib/stores/workflowState.ts index 675b1f8..068f65d 100644 --- a/src/lib/stores/workflowState.ts +++ b/src/lib/stores/workflowState.ts @@ -1,5 +1,5 @@ import type { SerializedGraphCanvasState } from '$lib/ComfyGraphCanvas'; -import type { LGraphCanvas, NodeID, SerializedLGraph, UUID } from '@litegraph-ts/core'; +import { clamp, type LGraphCanvas, type NodeID, type SerializedLGraph, type UUID } from '@litegraph-ts/core'; import { get, writable } from 'svelte/store'; import type { Readable, Writable } from 'svelte/store'; import type { SerializedLayoutState, WritableLayoutStateStore } from './layoutStates'; @@ -87,8 +87,10 @@ export class ComfyWorkflow { stop(key: string) { const canvas = this.canvases[key] - if (canvas == null) - throw new Error(`This workflow is not being displayed on canvas ${key}`) + if (canvas == null) { + console.debug("This workflow is not being displayed on canvas ${key}") + return; + } this.graph.detachCanvas(canvas.canvas); this.graph.eventBus.removeListener("afterExecute", canvas.canvasHandler) @@ -163,7 +165,7 @@ type WorkflowStateOps = { getWorkflow: (id: WorkflowInstID) => ComfyWorkflow | null getWorkflowByNodeID: (id: NodeID) => ComfyWorkflow | null getActiveWorkflow: () => ComfyWorkflow | null - createNewWorkflow: (canvas: ComfyGraphCanvas, setActive?: boolean) => ComfyWorkflow, + createNewWorkflow: (canvas: ComfyGraphCanvas, title?: string, setActive?: boolean) => ComfyWorkflow, openWorkflow: (canvas: ComfyGraphCanvas, data: SerializedAppState) => ComfyWorkflow, closeWorkflow: (canvas: ComfyGraphCanvas, index: number) => void, closeAllWorkflows: (canvas: ComfyGraphCanvas) => void, @@ -196,13 +198,14 @@ function getActiveWorkflow(): ComfyWorkflow | null { return state.openedWorkflows[state.activeWorkflowIdx]; } -function createNewWorkflow(canvas: ComfyGraphCanvas, setActive: boolean = false): ComfyWorkflow { - const workflow = new ComfyWorkflow("Workflow X"); +function createNewWorkflow(canvas: ComfyGraphCanvas, title: string = "New Workflow", setActive: boolean = false): ComfyWorkflow { + const workflow = new ComfyWorkflow(title); const layoutState = layoutStates.create(workflow); layoutState.initDefaultLayout(); const state = get(store); state.openedWorkflows.push(workflow); + state.openedWorkflowsByID[workflow.id] = workflow; if (setActive) setActiveWorkflow(canvas, state.openedWorkflows.length - 1) @@ -213,11 +216,12 @@ function createNewWorkflow(canvas: ComfyGraphCanvas, setActive: boolean = false) } function openWorkflow(canvas: ComfyGraphCanvas, data: SerializedAppState): ComfyWorkflow { - const [workflow, layoutState] = ComfyWorkflow.create("Workflow X") + const [workflow, layoutState] = ComfyWorkflow.create(data.workflowName || "Workflow") workflow.deserialize(layoutState, { graph: data.workflow, layout: data.layout }) const state = get(store); state.openedWorkflows.push(workflow); + state.openedWorkflowsByID[workflow.id] = workflow; setActiveWorkflow(canvas, state.openedWorkflows.length - 1) store.set(state) @@ -237,7 +241,9 @@ function closeWorkflow(canvas: ComfyGraphCanvas, index: number) { layoutStates.remove(workflow.id) state.openedWorkflows.splice(index, 1) - setActiveWorkflow(canvas, 0); + delete state.openedWorkflowsByID[workflow.id] + const newIndex = clamp(state.activeWorkflowIdx, 0, state.openedWorkflows.length - 1); + setActiveWorkflow(canvas, newIndex); store.set(state); } diff --git a/src/mobile/routes/home.svelte b/src/mobile/routes/home.svelte index 74da261..71c64d8 100644 --- a/src/mobile/routes/home.svelte +++ b/src/mobile/routes/home.svelte @@ -6,9 +6,9 @@ export let app: ComfyApp | null = null; async function doLoadDefault() { - var confirmed = confirm("Are you sure you want to clear the current workflow and load the default graph?"); + var confirmed = confirm("Would you like to load the default workflow in a new tab?"); if (confirmed) { - await app.initDefaultGraph(); + await app.initDefaultWorkflow(); } }