History fixes
This commit is contained in:
@@ -1113,7 +1113,7 @@ export default class ComfyApp {
|
|||||||
queueState.afterQueued(workflow.id, response.promptID, response.number, p.output, extraData)
|
queueState.afterQueued(workflow.id, response.promptID, response.number, p.output, extraData)
|
||||||
workflowState.afterQueued(workflow.id, response.promptID)
|
workflowState.afterQueued(workflow.id, response.promptID)
|
||||||
if (journeyNode != null) {
|
if (journeyNode != null) {
|
||||||
journeyNode.promptID = response.promptID;
|
targetWorkflow.journey.afterQueued(journeyNode, response.promptID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
import selectionState from '$lib/stores/selectionState';
|
import selectionState from '$lib/stores/selectionState';
|
||||||
import { Checkbox } from '@gradio/form';
|
import { Checkbox } from '@gradio/form';
|
||||||
import modalState from '$lib/stores/modalState';
|
import modalState from '$lib/stores/modalState';
|
||||||
import queueState from '$lib/stores/queueState';
|
import queueState, { type QueueEntry } from '$lib/stores/queueState';
|
||||||
import PromptDisplay from "$lib/components/PromptDisplay.svelte"
|
import PromptDisplay from "$lib/components/PromptDisplay.svelte"
|
||||||
import { getQueueEntryImages } from '$lib/stores/uiQueueState';
|
import { getQueueEntryImages } from '$lib/stores/uiQueueState';
|
||||||
import { SvelteComponent } from 'svelte';
|
import { SvelteComponent } from 'svelte';
|
||||||
@@ -91,23 +91,25 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const promptID = journeyNode.promptID;
|
// pick first resolved prompt
|
||||||
if (promptID != null) {
|
const queueEntry: QueueEntry | null =
|
||||||
const queueEntry = queueState.getQueueEntry(journeyNode.promptID)
|
Array.from(journeyNode.promptIDs)
|
||||||
if (queueEntry?.prompt != null) {
|
.map(id => queueState.getQueueEntry(id))
|
||||||
modalState.pushModal({
|
.find(qe => qe?.prompt != null);
|
||||||
title: "Prompt Details",
|
|
||||||
svelteComponent: PromptDisplay,
|
if (queueEntry) {
|
||||||
svelteProps: {
|
modalState.pushModal({
|
||||||
prompt: queueEntry.prompt,
|
title: "Prompt Details",
|
||||||
workflow: queueEntry.extraData?.extra_pnginfo?.comfyBoxWorkflow,
|
svelteComponent: PromptDisplay,
|
||||||
images: getQueueEntryImages(queueEntry),
|
svelteProps: {
|
||||||
closeModal: () => modalState.closeAllModals(),
|
prompt: queueEntry.prompt,
|
||||||
expandAll: false,
|
workflow: queueEntry.extraData?.extra_pnginfo?.comfyBoxWorkflow,
|
||||||
app
|
images: getQueueEntryImages(queueEntry),
|
||||||
},
|
closeModal: () => modalState.closeAllModals(),
|
||||||
})
|
expandAll: false,
|
||||||
}
|
app
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
notify("This journey entry has no prompts yet.", { type: "warning" })
|
notify("This journey entry has no prompts yet.", { type: "warning" })
|
||||||
|
|||||||
@@ -50,23 +50,31 @@
|
|||||||
return a[1].name > b[1].name ? 1 : -1
|
return a[1].name > b[1].name ? 1 : -1
|
||||||
})
|
})
|
||||||
|
|
||||||
for (const [nodeID, source] of sorted) {
|
const MAX_ENTRIES = 5
|
||||||
|
const entries = sorted.slice(0, MAX_ENTRIES)
|
||||||
|
const leftover = sorted.length - MAX_ENTRIES
|
||||||
|
|
||||||
|
for (const [nodeID, source] of entries) {
|
||||||
let line = ""
|
let line = ""
|
||||||
switch (source.nodeType) {
|
switch (source.nodeType) {
|
||||||
case "ui/text":
|
case "ui/text":
|
||||||
line = `${source.name} (changed)`
|
line = `${source.name}: (changed)`
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
const prevValue = prev[nodeID];
|
const prevValue = prev[nodeID];
|
||||||
let prevValueStr = "???"
|
let prevValueStr = "???"
|
||||||
if (prevValue)
|
if (prevValue)
|
||||||
prevValueStr = prevValue.finalValue
|
prevValueStr = prevValue.finalValue
|
||||||
line = `${source.name}: ${prevValueStr} -> ${source.finalValue}`
|
line = `${source.name}: ${prevValueStr} → ${source.finalValue}`
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lines.push(line)
|
lines.push(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (leftover > 0) {
|
||||||
|
lines.push(`(+ ${leftover} more)`)
|
||||||
|
}
|
||||||
|
|
||||||
return lines.join("\n")
|
return lines.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,8 +136,6 @@
|
|||||||
const patchText = makePatchText(patchNode.patch, prev);
|
const patchText = makePatchText(patchNode.patch, prev);
|
||||||
const patchNodeHeight = countNewLines(patchText) * 11 + 22;
|
const patchNodeHeight = countNewLines(patchText) * 11 + 22;
|
||||||
|
|
||||||
console.debug("[JourneyRenderer] Patch text", prev, patchText);
|
|
||||||
|
|
||||||
nodes.push({
|
nodes.push({
|
||||||
data: {
|
data: {
|
||||||
id: midNodeID,
|
id: midNodeID,
|
||||||
@@ -224,8 +230,8 @@
|
|||||||
|
|
||||||
const journeyNode = $journey.nodesByID[nodeID]
|
const journeyNode = $journey.nodesByID[nodeID]
|
||||||
if (journeyNode) {
|
if (journeyNode) {
|
||||||
if (journeyNode.promptID != null) {
|
if (journeyNode.promptIDs) {
|
||||||
const queueEntry = queueState.getQueueEntry(journeyNode.promptID)
|
const queueEntry = Array.from(journeyNode.promptIDs).map(id => queueState.getQueueEntry(id)).find(Boolean);
|
||||||
if (queueEntry) {
|
if (queueEntry) {
|
||||||
const outputs = getQueueEntryImages(queueEntry);
|
const outputs = getQueueEntryImages(queueEntry);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import Gallery from "$lib/components/gradio/gallery/Gallery.svelte";
|
import Gallery from "$lib/components/gradio/gallery/Gallery.svelte";
|
||||||
import { ImageViewer } from "$lib/ImageViewer";
|
import { ImageViewer } from "$lib/ImageViewer";
|
||||||
import type { Styles } from "@gradio/utils";
|
import type { Styles } from "@gradio/utils";
|
||||||
import { comfyFileToComfyBoxMetadata, comfyURLToComfyFile, countNewLines } from "$lib/utils";
|
import { comfyFileToComfyBoxMetadata, comfyURLToComfyFile, countNewLines, isMultiline } from "$lib/utils";
|
||||||
import ReceiveOutputTargets from "./modal/ReceiveOutputTargets.svelte";
|
import ReceiveOutputTargets from "./modal/ReceiveOutputTargets.svelte";
|
||||||
import RestoreParamsTable from "./modal/RestoreParamsTable.svelte";
|
import RestoreParamsTable from "./modal/RestoreParamsTable.svelte";
|
||||||
import workflowState, { type ComfyBoxWorkflow, type WorkflowReceiveOutputTargets } from "$lib/stores/workflowState";
|
import workflowState, { type ComfyBoxWorkflow, type WorkflowReceiveOutputTargets } from "$lib/stores/workflowState";
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
// TODO other sources than serialized workflow
|
// TODO other sources than serialized workflow
|
||||||
if (workflow != null) {
|
if (workflow != null) {
|
||||||
const workflowParams = getWorkflowRestoreParamsUsingLayout(workflow.workflow, workflow.layout)
|
const workflowParams = getWorkflowRestoreParamsUsingLayout(workflow.workflow, workflow.layout)
|
||||||
|
console.error("GETPARMS", workflowParams)
|
||||||
restoreParams = concatRestoreParams(restoreParams, workflowParams);
|
restoreParams = concatRestoreParams(restoreParams, workflowParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,10 +101,6 @@
|
|||||||
&& typeof input[1] === "number"
|
&& typeof input[1] === "number"
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMultiline(input: any): boolean {
|
|
||||||
return typeof input === "string" && (input.length > splitLength || countNewLines(input) > 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatInput(input: any): string {
|
function formatInput(input: any): string {
|
||||||
if (typeof input === "string")
|
if (typeof input === "string")
|
||||||
return input
|
return input
|
||||||
|
|||||||
@@ -68,8 +68,9 @@ const styles: Stylesheet[] = [
|
|||||||
"text-valign": "center",
|
"text-valign": "center",
|
||||||
"text-wrap": "wrap",
|
"text-wrap": "wrap",
|
||||||
"text-max-width": "140",
|
"text-max-width": "140",
|
||||||
"background-color": "#333",
|
"line-height": "1.5",
|
||||||
"border-color": "#black",
|
"background-color": "#374151",
|
||||||
|
"border-color": "#1f2937",
|
||||||
"border-width": "1",
|
"border-width": "1",
|
||||||
"color": "white",
|
"color": "white",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ComfyReceiveOutputNode } from "$lib/nodes/actions";
|
import type { ComfyReceiveOutputNode } from "$lib/nodes/actions";
|
||||||
import type { ComfyWidgetNode } from "$lib/nodes/widgets";
|
import type { ComfyWidgetNode } from "$lib/nodes/widgets";
|
||||||
import type { RestoreParamTargets } from "$lib/restoreParameters";
|
import type { RestoreParamSource, RestoreParamTargets } from "$lib/restoreParameters";
|
||||||
import { isComfyWidgetNode } from "$lib/stores/layoutStates";
|
import { isComfyWidgetNode, type WidgetLayout } from "$lib/stores/layoutStates";
|
||||||
import type { ComfyBoxWorkflow, WorkflowReceiveOutputTargets } from "$lib/stores/workflowState";
|
import type { ComfyBoxWorkflow, WorkflowReceiveOutputTargets } from "$lib/stores/workflowState";
|
||||||
import workflowState from "$lib/stores/workflowState";
|
import workflowState from "$lib/stores/workflowState";
|
||||||
import { Block, BlockTitle } from "@gradio/atoms";
|
import { Block, BlockTitle } from "@gradio/atoms";
|
||||||
import { Button } from "@gradio/button";
|
import { Button } from "@gradio/button";
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from "svelte";
|
||||||
|
import deepEqual from "deep-equal";
|
||||||
|
import { capitalize, countNewLines, isMultiline } from "$lib/utils";
|
||||||
|
import { TextBox } from "@gradio/form";
|
||||||
|
|
||||||
type UIRestoreParam = {
|
type UIRestoreParam = {
|
||||||
node: ComfyWidgetNode,
|
node: ComfyWidgetNode,
|
||||||
@@ -32,14 +35,21 @@
|
|||||||
if (node == null || !isComfyWidgetNode(node))
|
if (node == null || !isComfyWidgetNode(node))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const nodeValue = node.getValue();
|
||||||
|
const foundSources = sources.filter(s => !deepEqual(nodeValue, s.finalValue));
|
||||||
|
if (foundSources.length === 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
const widget = node.dragItem;
|
const widget = node.dragItem;
|
||||||
if (widget == null) {
|
if (widget == null) {
|
||||||
console.error("[RestoreParamsTable] Node missing layoutState widget!!!", node)
|
console.error("[RestoreParamsTable] Node missing layoutState widget!!!", node)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push({ node, widget, sources })
|
result.push({ node, widget, sources: foundSources })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.warn("RESTORE PARAMS", restoreParams, "->", result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +58,7 @@
|
|||||||
|
|
||||||
function doRestore(e: MouseEvent) {
|
function doRestore(e: MouseEvent) {
|
||||||
dispatch("restore", {})
|
dispatch("restore", {})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="scroll-container">
|
<div class="scroll-container">
|
||||||
@@ -57,7 +67,7 @@
|
|||||||
{:else if Object.keys(uiRestoreParams).length === 0}
|
{:else if Object.keys(uiRestoreParams).length === 0}
|
||||||
<div>
|
<div>
|
||||||
<p>No parameters to restore found in this workflow.</p>
|
<p>No parameters to restore found in this workflow.</p>
|
||||||
<p>(TODO: Only parameters compatible with the currently active workflow can be restored right now)</p>
|
<p>(Either prompt is unchanged from active workflow, or the workflow the parameters were saved from was different)</p>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<Block>
|
<Block>
|
||||||
@@ -69,11 +79,22 @@
|
|||||||
</Block>
|
</Block>
|
||||||
{#each uiRestoreParams as { node, widget, sources }}
|
{#each uiRestoreParams as { node, widget, sources }}
|
||||||
<Block>
|
<Block>
|
||||||
<BlockTitle>{widget.attrs.title || node.title}</BlockTitle>
|
<div class="target-name">➤ {widget.attrs.title || node.title}</div>
|
||||||
{#each sources as source}
|
{#each sources as source}
|
||||||
|
{@const value = String(source.finalValue)}
|
||||||
<div class="target">
|
<div class="target">
|
||||||
<div class="target-name-and-desc">
|
<div class="target-name-and-desc">
|
||||||
<div class="target-name">➤ {source.type}</div>
|
<Block>
|
||||||
|
<BlockTitle>{capitalize(source.type)}</BlockTitle>
|
||||||
|
<div>
|
||||||
|
{#if isMultiline(value, 20)}
|
||||||
|
{@const lines = Math.max(countNewLines(value), value.length / 20)}
|
||||||
|
<TextBox show_label={false} label={''} {value} {lines} max_lines={lines} />
|
||||||
|
{:else}
|
||||||
|
<TextBox show_label={false} label={''} {value} lines={1} max_lines={1} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Block>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -95,20 +116,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.target-name {
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.target {
|
.target {
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
.target-name-and-desc {
|
.target-name-and-desc {
|
||||||
margin: auto auto auto 0;
|
:global(.block) {
|
||||||
left: 0px;
|
background: var(--panel-background-fill);
|
||||||
|
}
|
||||||
|
|
||||||
.target-desc {
|
.target-desc {
|
||||||
opacity: 65%;
|
opacity: 65%;
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
@include json-view;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { INodeInputSlot, NodeID, SerializedLGraph } from "@litegraph-ts/core";
|
import type { INodeInputSlot, NodeID, SerializedLGraph, SerializedLGraphNode } from "@litegraph-ts/core";
|
||||||
import type { SerializedPrompt } from "./components/ComfyApp";
|
import type { SerializedPrompt } from "./components/ComfyApp";
|
||||||
import type { ComfyWidgetNode } from "./nodes/widgets";
|
import type { ComfyWidgetNode } from "./nodes/widgets";
|
||||||
import type { SerializedComfyWidgetNode } from "./nodes/widgets/ComfyWidgetNode";
|
import type { SerializedComfyWidgetNode } from "./nodes/widgets/ComfyWidgetNode";
|
||||||
@@ -242,15 +242,29 @@ export function getWorkflowRestoreParams(serGraph: SerializedLGraph, workflow?:
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function* iterateSerializedNodesRecursive(serGraph: SerializedLGraph): Iterable<SerializedLGraphNode> {
|
||||||
|
for (const serNode of serGraph.nodes) {
|
||||||
|
yield serNode;
|
||||||
|
|
||||||
|
if (serNode.type === "graph/subgraph") {
|
||||||
|
for (const childNode of iterateSerializedNodesRecursive((serNode as any).subgraph)) {
|
||||||
|
yield childNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getWorkflowRestoreParamsUsingLayout(serGraph: SerializedLGraph, layout?: SerializedLayoutState, noExclude: boolean = false): RestoreParamWorkflowNodeTargets {
|
export function getWorkflowRestoreParamsUsingLayout(serGraph: SerializedLGraph, layout?: SerializedLayoutState, noExclude: boolean = false): RestoreParamWorkflowNodeTargets {
|
||||||
const result = {}
|
const result = {}
|
||||||
|
|
||||||
for (const serNode of serGraph.nodes) {
|
for (const serNode of iterateSerializedNodesRecursive(serGraph)) {
|
||||||
if (!isSerializedComfyWidgetNode(serNode))
|
if (!isSerializedComfyWidgetNode(serNode)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!noExclude && serNode.properties.excludeFromJourney)
|
if (!noExclude && serNode.properties.excludeFromJourney) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let name = null;
|
let name = null;
|
||||||
const serWidget = Array.from(Object.values(layout?.allItems || {})).find(di => di.dragItem.type === "widget" && di.dragItem.nodeId === serNode.id)
|
const serWidget = Array.from(Object.values(layout?.allItems || {})).find(di => di.dragItem.type === "widget" && di.dragItem.nodeId === serNode.id)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export interface JourneyNode {
|
|||||||
id: JourneyNodeID,
|
id: JourneyNodeID,
|
||||||
type: JourneyNodeType,
|
type: JourneyNodeType,
|
||||||
children: JourneyPatchNode[],
|
children: JourneyPatchNode[],
|
||||||
promptID?: PromptID,
|
promptIDs: Set<PromptID>,
|
||||||
images?: string[]
|
images?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +101,7 @@ export function calculateWorkflowParamsPatch(parent: JourneyNode, newParams: Res
|
|||||||
export type JourneyState = {
|
export type JourneyState = {
|
||||||
root: JourneyRootNode | null,
|
root: JourneyRootNode | null,
|
||||||
nodesByID: Record<JourneyNodeID, JourneyNode>,
|
nodesByID: Record<JourneyNodeID, JourneyNode>,
|
||||||
|
nodesByPromptID: Record<PromptID, JourneyNode>,
|
||||||
activeNodeID: JourneyNodeID | null,
|
activeNodeID: JourneyNodeID | null,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -117,6 +118,7 @@ type JourneyStateOps = {
|
|||||||
iterateBreadthFirst: (id?: JourneyNodeID | null) => Iterable<JourneyNode>,
|
iterateBreadthFirst: (id?: JourneyNodeID | null) => Iterable<JourneyNode>,
|
||||||
iterateLinearPath: (id: JourneyNodeID) => Iterable<JourneyNode>,
|
iterateLinearPath: (id: JourneyNodeID) => Iterable<JourneyNode>,
|
||||||
pushPatchOntoActive: (workflow: ComfyBoxWorkflow, activeNode?: JourneyNode, showNotification?: boolean) => JourneyNode | null
|
pushPatchOntoActive: (workflow: ComfyBoxWorkflow, activeNode?: JourneyNode, showNotification?: boolean) => JourneyNode | null
|
||||||
|
afterQueued: (journeyNode: JourneyNode, promptID: PromptID) => void,
|
||||||
onExecuted: (promptID: PromptID, nodeID: ComfyNodeID, output: SerializedPromptOutput, queueEntry: QueueEntry) => void
|
onExecuted: (promptID: PromptID, nodeID: ComfyNodeID, output: SerializedPromptOutput, queueEntry: QueueEntry) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +129,7 @@ function create() {
|
|||||||
{
|
{
|
||||||
root: null,
|
root: null,
|
||||||
nodesByID: {},
|
nodesByID: {},
|
||||||
|
nodesByPromptID: {},
|
||||||
activeNodeID: null,
|
activeNodeID: null,
|
||||||
version: 0
|
version: 0
|
||||||
})
|
})
|
||||||
@@ -135,6 +138,7 @@ function create() {
|
|||||||
store.set({
|
store.set({
|
||||||
root: null,
|
root: null,
|
||||||
nodesByID: {},
|
nodesByID: {},
|
||||||
|
nodesByPromptID: {},
|
||||||
activeNodeID: null,
|
activeNodeID: null,
|
||||||
version: 0
|
version: 0
|
||||||
})
|
})
|
||||||
@@ -173,6 +177,7 @@ function create() {
|
|||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
type: "root",
|
type: "root",
|
||||||
children: [],
|
children: [],
|
||||||
|
promptIDs: new Set(),
|
||||||
base: { ...params }
|
base: { ...params }
|
||||||
}
|
}
|
||||||
s.root = _node
|
s.root = _node
|
||||||
@@ -183,6 +188,7 @@ function create() {
|
|||||||
type: "patch",
|
type: "patch",
|
||||||
parent: parentNode,
|
parent: parentNode,
|
||||||
children: [],
|
children: [],
|
||||||
|
promptIDs: new Set(),
|
||||||
patch: params,
|
patch: params,
|
||||||
}
|
}
|
||||||
parentNode.children.push(_node);
|
parentNode.children.push(_node);
|
||||||
@@ -311,8 +317,16 @@ function create() {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function afterQueued(journeyNode: JourneyNode, promptID: PromptID) {
|
||||||
|
journeyNode.promptIDs.add(promptID);
|
||||||
|
store.update(s => {
|
||||||
|
s.nodesByPromptID[promptID] = journeyNode;
|
||||||
|
return s;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function onExecuted(promptID: PromptID, nodeID: ComfyNodeID, output: SerializedPromptOutput, queueEntry: QueueEntry) {
|
function onExecuted(promptID: PromptID, nodeID: ComfyNodeID, output: SerializedPromptOutput, queueEntry: QueueEntry) {
|
||||||
const journeyNode = Array.from(iterateBreadthFirst()).find(j => j.promptID === promptID);
|
const journeyNode = get(store).nodesByPromptID[promptID];
|
||||||
if (journeyNode == null)
|
if (journeyNode == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -333,7 +347,8 @@ function create() {
|
|||||||
selectNode,
|
selectNode,
|
||||||
iterateBreadthFirst,
|
iterateBreadthFirst,
|
||||||
iterateLinearPath,
|
iterateLinearPath,
|
||||||
onExecuted
|
afterQueued,
|
||||||
|
onExecuted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type QueueStateOps = {
|
|||||||
export type QueueEntry = {
|
export type QueueEntry = {
|
||||||
/*** Data preserved on page refresh ***/
|
/*** Data preserved on page refresh ***/
|
||||||
|
|
||||||
/** Priority of the prompt. -1 means to queue at the front. */
|
/** Priority of the prompt. Lower/negative numbers get higher priority. */
|
||||||
number: number,
|
number: number,
|
||||||
queuedAt?: Date,
|
queuedAt?: Date,
|
||||||
finishedAt?: Date,
|
finishedAt?: Date,
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ function updateFromQueue(queuePending: QueueEntry[], queueRunning: QueueEntry[])
|
|||||||
// newest entries appear at the top
|
// newest entries appear at the top
|
||||||
s.queuedEntries = queuePending.map((e) => convertPendingEntry(e, "pending")).reverse();
|
s.queuedEntries = queuePending.map((e) => convertPendingEntry(e, "pending")).reverse();
|
||||||
s.runningEntries = queueRunning.map((e) => convertPendingEntry(e, "running")).reverse();
|
s.runningEntries = queueRunning.map((e) => convertPendingEntry(e, "running")).reverse();
|
||||||
|
|
||||||
|
s.queuedEntries.sort((a, b) => a.entry.number - b.entry.number)
|
||||||
|
s.runningEntries.sort((a, b) => a.entry.number - b.entry.number)
|
||||||
|
|
||||||
s.queueUIEntries = s.queuedEntries.concat(s.runningEntries);
|
s.queueUIEntries = s.queuedEntries.concat(s.runningEntries);
|
||||||
console.warn("[ComfyQueue] BUILDQUEUE", s.queuedEntries.length, s.runningEntries.length)
|
console.warn("[ComfyQueue] BUILDQUEUE", s.queuedEntries.length, s.runningEntries.length)
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
@@ -745,3 +745,7 @@ const MOBILE_USER_AGENTS = ["iPhone", "iPad", "Android", "BlackBerry", "WebOs"].
|
|||||||
export function isMobileBrowser(userAgent: string): boolean {
|
export function isMobileBrowser(userAgent: string): boolean {
|
||||||
return MOBILE_USER_AGENTS.some(a => userAgent.match(a))
|
return MOBILE_USER_AGENTS.some(a => userAgent.match(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isMultiline(input: any, splitLength: number = 50): boolean {
|
||||||
|
return typeof input === "string" && (input.length > splitLength || countNewLines(input) > 1);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user