diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml new file mode 100644 index 0000000..8ba851e --- /dev/null +++ b/.github/workflows/build-and-publish.yml @@ -0,0 +1,64 @@ +name: Build and Publish + +on: + - push + +jobs: + test_default_inputs: + name: Test with default inputs + + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + pnpm: + - 4.11.1 + os: + - ubuntu-latest + - macos-latest + - windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - uses: pnpm/action-setup@v2 + name: Install pnpm + id: pnpm-install + with: + version: 7.26 + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install + + - name: Build + run: | + pnpm build:css + pnpm build + + - uses: actions/upload-artifact@v3 + with: + name: ComfyBox-dist + path: dist/ + if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` diff --git a/.gitignore b/.gitignore index 6635cf5..702a941 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ node_modules !.env.example vite.config.js.timestamp-* vite.config.ts.timestamp-* +/dist diff --git a/litegraph b/litegraph index fd56d0c..115bef4 160000 --- a/litegraph +++ b/litegraph @@ -1 +1 @@ -Subproject commit fd56d0c4e698b7a5bfccb1aa86e15db0f16120df +Subproject commit 115bef46a58616395d7d3b54a1421472ac28e519 diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..53da77d --- /dev/null +++ b/run.bat @@ -0,0 +1,4 @@ +@echo off + +pushd dist +python -m http.server 8000 diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..c673001 --- /dev/null +++ b/run.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +pushd dist/ +python -m http.server 8000 diff --git a/src/lib/components/ComfyApp.svelte b/src/lib/components/ComfyApp.svelte index db027f5..23296bc 100644 --- a/src/lib/components/ComfyApp.svelte +++ b/src/lib/components/ComfyApp.svelte @@ -11,6 +11,7 @@ import { ImageViewer } from "$lib/ImageViewer"; import type { ComfyAPIStatus } from "$lib/api"; import { SvelteToast, toast } from '@zerodevx/svelte-toast' + import defaultGraph from "$lib/defaultGraph" import { LGraph } from "@litegraph-ts/core"; import LightboxModal from "./LightboxModal.svelte"; @@ -95,6 +96,13 @@ } } + async function doLoadDefault(): void { + var confirmed = confirm("Are you sure you want to clear the current workflow and load the default graph?"); + if (confirmed) { + await app.deserialize(defaultGraph) + } + } + function doRecenter(): void { app.lCanvas.recenter(); } @@ -180,6 +188,9 @@ + diff --git a/src/lib/components/ComfyApp.ts b/src/lib/components/ComfyApp.ts index 56667d7..72ac37c 100644 --- a/src/lib/components/ComfyApp.ts +++ b/src/lib/components/ComfyApp.ts @@ -108,7 +108,7 @@ export default class ComfyApp { const json = localStorage.getItem("workflow"); if (json) { const state = JSON.parse(json) as SerializedAppState; - this.deserialize(state) + await this.deserialize(state) restored = true; } } catch (err) { @@ -117,7 +117,7 @@ export default class ComfyApp { // We failed to restore a workflow so load the default if (!restored) { - this.initDefaultGraph(); + await this.initDefaultGraph(); } // Save current workflow automatically @@ -344,7 +344,7 @@ export default class ComfyApp { } } - deserialize(data: SerializedAppState) { + async deserialize(data: SerializedAppState) { if (data.version !== COMFYBOX_SERIAL_VERSION) { throw `Invalid ComfyBox saved data format: ${data.version}` } @@ -363,11 +363,13 @@ export default class ComfyApp { // Restore canvas offset/zoom this.lCanvas.deserialize(data.canvas) + + await this.refreshComboInNodes(); } - initDefaultGraph() { + async initDefaultGraph() { const state = structuredClone(defaultGraph) - this.deserialize(state) + await this.deserialize(state) } /** diff --git a/src/lib/components/ComfyQueue.svelte b/src/lib/components/ComfyQueue.svelte index b844a12..de2af8e 100644 --- a/src/lib/components/ComfyQueue.svelte +++ b/src/lib/components/ComfyQueue.svelte @@ -10,9 +10,79 @@ const title = app.lGraph.getNodeById(nodeId)?.title || String(nodeId); return title + " (" + nodeId + ")" } + + const entries = [ + { + "outputs": { + 44: { + "images": [ + { + "filename": "ComfyUI_00052_.png", + "subfolder": "", + "type": "output" + } + ] + } + } + }, + { + "outputs": { + 44: { + "images": [ + { + "filename": "ComfyUI_00052_.png", + "subfolder": "", + "type": "output" + } + ] + } + } + }, + { + "outputs": { + 44: { + "images": [ + { + "filename": "ComfyUI_00052_.png", + "subfolder": "", + "type": "output" + } + ] + } + } + } + ] + + let _entries: any[] = [] + + $: if (entries) { + _entries = [] + for (const entry of entries) { + for (const outputs of Object.values(entry.outputs)) { + const allImages = outputs.images.map(r => { + // TODO configure backend URL + const url = "http://localhost:8188/view?" + const params = new URLSearchParams(r) + return url + params + }); + + _entries.push({ allImages, name: "Output" }) + } + } + }