Default notifications for workflows

This commit is contained in:
space-nuko
2023-05-26 17:06:23 -05:00
parent 60bd989915
commit b3584dd2ad
9 changed files with 5772 additions and 5383 deletions

View File

@@ -3331,17 +3331,17 @@
"title": "UI.Text", "title": "UI.Text",
"properties": { "properties": {
"tags": [], "tags": [],
"defaultValue": "masterpiece, 1girl, (yuri:1.2), city street, cityscape, open shirt, breasts, large breasts, nipples, shiny skin, full body, happy, red hair, red eyes, looking at another, eye contact, red skirt", "defaultValue": "masterpiece, 1girl, city street, cityscape, large shiny skin, full body, happy, red hair, red eyes, looking at another, eye contact, red skirt",
"multiline": true, "multiline": true,
"lines": 5, "lines": 5,
"maxLines": 5 "maxLines": 5
}, },
"widgets_values": [ "widgets_values": [
"masterpiece, 1girl, (yuri:1.2), city street, cityscape, open shirt, breasts, large breasts, nipples, shiny skin, full body, happy, red hair, red eyes, looking at another, eye contact, red skirt" "masterpiece, 1girl, city street, cityscape, large shiny skin, full body, happy, red hair, red eyes, looking at another, eye contact, red skirt"
], ],
"color": "#223", "color": "#223",
"bgColor": "#335", "bgColor": "#335",
"comfyValue": "masterpiece, 1girl, (yuri:1.2), city street, cityscape, open shirt, breasts, large breasts, nipples, shiny skin, full body, happy, red hair, red eyes, looking at another, eye contact, red skirt", "comfyValue": "masterpiece, 1girl, city street, cityscape, large shiny skin, full body, happy, red hair, red eyes, looking at another, eye contact, red skirt",
"shownOutputProperties": {}, "shownOutputProperties": {},
"saveUserState": true "saveUserState": true
}, },
@@ -3396,17 +3396,17 @@
"title": "UI.Text", "title": "UI.Text",
"properties": { "properties": {
"tags": [], "tags": [],
"defaultValue": "masterpiece, 1girl, (yuri:1.2), open shirt, breasts, medium breasts, nipples, city street, cityscape, full body, happy, blue hair, blue eyes, looking at another, eye contact, blue skirt", "defaultValue": "masterpiece, 1girl, city street, cityscape, full body, happy, blue hair, blue eyes, looking at another, eye contact, blue skirt",
"multiline": true, "multiline": true,
"lines": 5, "lines": 5,
"maxLines": 5 "maxLines": 5
}, },
"widgets_values": [ "widgets_values": [
"masterpiece, 1girl, (yuri:1.2), open shirt, breasts, medium breasts, nipples, city street, cityscape, full body, happy, blue hair, blue eyes, looking at another, eye contact, blue skirt" "masterpiece, 1girl, city street, cityscape, full body, happy, blue hair, blue eyes, looking at another, eye contact, blue skirt"
], ],
"color": "#223", "color": "#223",
"bgColor": "#335", "bgColor": "#335",
"comfyValue": "masterpiece, 1girl, (yuri:1.2), open shirt, breasts, medium breasts, nipples, city street, cityscape, full body, happy, blue hair, blue eyes, looking at another, eye contact, blue skirt", "comfyValue": "masterpiece, 1girl, city street, cityscape, full body, happy, blue hair, blue eyes, looking at another, eye contact, blue skirt",
"shownOutputProperties": {}, "shownOutputProperties": {},
"saveUserState": true "saveUserState": true
}, },
@@ -3461,17 +3461,17 @@
"title": "UI.Text", "title": "UI.Text",
"properties": { "properties": {
"tags": [], "tags": [],
"defaultValue": "masterpiece, 2girls, (yuri:1.2), open shirt, small breasts, nipples, city street, cityscape, full body, happy, yellow hair, yellow eyes, looking at another, eye contact, yellow skirt", "defaultValue": "masterpiece, 2girls, small city street, cityscape, full body, happy, yellow hair, yellow eyes, looking at another, eye contact, yellow skirt",
"multiline": true, "multiline": true,
"lines": 5, "lines": 5,
"maxLines": 5 "maxLines": 5
}, },
"widgets_values": [ "widgets_values": [
"masterpiece, 2girls, (yuri:1.2), open shirt, small breasts, nipples, city street, cityscape, full body, happy, yellow hair, yellow eyes, looking at another, eye contact, yellow skirt" "masterpiece, 2girls, small city street, cityscape, full body, happy, yellow hair, yellow eyes, looking at another, eye contact, yellow skirt"
], ],
"color": "#223", "color": "#223",
"bgColor": "#335", "bgColor": "#335",
"comfyValue": "masterpiece, 2girls, (yuri:1.2), open shirt, small breasts, nipples, city street, cityscape, full body, happy, yellow hair, yellow eyes, looking at another, eye contact, yellow skirt", "comfyValue": "masterpiece, 2girls, small city street, cityscape, full body, happy, yellow hair, yellow eyes, looking at another, eye contact, yellow skirt",
"shownOutputProperties": {}, "shownOutputProperties": {},
"saveUserState": true "saveUserState": true
}, },
@@ -3526,17 +3526,17 @@
"title": "UI.Text", "title": "UI.Text",
"properties": { "properties": {
"tags": [], "tags": [],
"defaultValue": "masterpiece, 2girls, (yuri:1.2), open shirt, flat chest, nipples, city street, cityscape, full body, happy, green hair, green eyes, looking at another, eye contact, green skirt", "defaultValue": "masterpiece, 2girls, city street, cityscape, full body, happy, green hair, green eyes, looking at another, eye contact, green skirt",
"multiline": true, "multiline": true,
"lines": 5, "lines": 5,
"maxLines": 5 "maxLines": 5
}, },
"widgets_values": [ "widgets_values": [
"masterpiece, 2girls, (yuri:1.2), open shirt, flat chest, nipples, city street, cityscape, full body, happy, green hair, green eyes, looking at another, eye contact, green skirt" "masterpiece, 2girls, city street, cityscape, full body, happy, green hair, green eyes, looking at another, eye contact, green skirt"
], ],
"color": "#223", "color": "#223",
"bgColor": "#335", "bgColor": "#335",
"comfyValue": "masterpiece, 2girls, (yuri:1.2), open shirt, flat chest, nipples, city street, cityscape, full body, happy, green hair, green eyes, looking at another, eye contact, green skirt", "comfyValue": "masterpiece, 2girls, city street, cityscape, full body, happy, green hair, green eyes, looking at another, eye contact, green skirt",
"shownOutputProperties": {}, "shownOutputProperties": {},
"saveUserState": true "saveUserState": true
}, },
@@ -4706,17 +4706,17 @@
"title": "UI.Text", "title": "UI.Text",
"properties": { "properties": {
"tags": [], "tags": [],
"defaultValue": "nsfw, masterpiece, 4girls, multiple girls, city street, cityscape, landscape, jeans, shoes, shirt, kanpai, happy, red hair, yellow hair, blue hair, green hair, looking at another, eye contact", "defaultValue": "masterpiece, 4girls, multiple girls, city street, cityscape, landscape, jeans, shoes, shirt, kanpai, happy, red hair, yellow hair, blue hair, green hair, looking at another, eye contact",
"multiline": true, "multiline": true,
"lines": 5, "lines": 5,
"maxLines": 5 "maxLines": 5
}, },
"widgets_values": [ "widgets_values": [
"nsfw, masterpiece, 4girls, multiple girls, city street, cityscape, landscape, jeans, shoes, shirt, kanpai, happy, red hair, yellow hair, blue hair, green hair, looking at another, eye contact" "masterpiece, 4girls, multiple girls, city street, cityscape, landscape, jeans, shoes, shirt, kanpai, happy, red hair, yellow hair, blue hair, green hair, looking at another, eye contact"
], ],
"color": "#223", "color": "#223",
"bgColor": "#335", "bgColor": "#335",
"comfyValue": "nsfw, masterpiece, 4girls, multiple girls, city street, cityscape, landscape, jeans, shoes, shirt, kanpai, happy, red hair, yellow hair, blue hair, green hair, looking at another, eye contact", "comfyValue": "masterpiece, 4girls, multiple girls, city street, cityscape, landscape, jeans, shoes, shirt, kanpai, happy, red hair, yellow hair, blue hair, green hair, looking at another, eye contact",
"shownOutputProperties": {}, "shownOutputProperties": {},
"saveUserState": true "saveUserState": true
}, },
@@ -10027,4 +10027,4 @@
], ],
"scale": 1 "scale": 1
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,7 @@ import queueState from "$lib/stores/queueState";
import selectionState from "$lib/stores/selectionState"; import selectionState from "$lib/stores/selectionState";
import uiState from "$lib/stores/uiState"; import uiState from "$lib/stores/uiState";
import workflowState, { ComfyBoxWorkflow, type WorkflowAttributes, type WorkflowInstID } from "$lib/stores/workflowState"; import workflowState, { ComfyBoxWorkflow, type WorkflowAttributes, type WorkflowInstID } from "$lib/stores/workflowState";
import { readFileToText, type SerializedPromptOutput } from "$lib/utils"; import { playSound, readFileToText, type SerializedPromptOutput } from "$lib/utils";
import { basename, capitalize, download, graphToGraphVis, jsonToJsObject, promptToGraphVis, range } from "$lib/utils"; import { basename, capitalize, download, graphToGraphVis, jsonToJsObject, promptToGraphVis, range } from "$lib/utils";
import { tick } from "svelte"; import { tick } from "svelte";
import { type SvelteComponentDev } from "svelte/internal"; import { type SvelteComponentDev } from "svelte/internal";
@@ -891,7 +891,7 @@ export default class ComfyApp {
if (workflow.attrs.queuePromptButtonRunWorkflow) { if (workflow.attrs.queuePromptButtonRunWorkflow) {
// Hold control to queue at the front // Hold control to queue at the front
const num = this.ctrlDown ? -1 : 0; const num = this.ctrlDown ? -1 : 0;
this.queuePrompt(num, 1); this.queuePrompt(workflow, num, 1);
} }
} }
@@ -941,14 +941,8 @@ export default class ComfyApp {
return this.promptSerializer.serialize(workflow.graph, tag) return this.promptSerializer.serialize(workflow.graph, tag)
} }
async queuePrompt(num: number, batchCount: number = 1, tag: string | null = null) { async queuePrompt(targetWorkflow: ComfyBoxWorkflow, num: number, batchCount: number = 1, tag: string | null = null) {
const activeWorkflow = workflowState.getActiveWorkflow(); this.queueItems.push({ num, batchCount, workflow: targetWorkflow });
if (activeWorkflow == null) {
notify("No workflow is opened!", { type: "error" })
return;
}
this.queueItems.push({ num, batchCount, workflow: activeWorkflow });
// Only have one action process the items so each one gets a unique seed correctly // Only have one action process the items so each one gets a unique seed correctly
if (this.processingQueue) { if (this.processingQueue) {
@@ -958,6 +952,10 @@ export default class ComfyApp {
if (tag === "") if (tag === "")
tag = null; tag = null;
if (targetWorkflow.attrs.showDefaultNotifications) {
notify("Prompt queued.", { type: "info" });
}
this.processingQueue = true; this.processingQueue = true;
let workflow: ComfyBoxWorkflow; let workflow: ComfyBoxWorkflow;

View File

@@ -47,7 +47,7 @@ export default class ComfyExecuteSubgraphAction extends ComfyGraphNode {
// Hold control to queue at the front // Hold control to queue at the front
const num = app.ctrlDown ? -1 : 0; const num = app.ctrlDown ? -1 : 0;
app.queuePrompt(num, 1, tag); app.queuePrompt(this.workflow, num, 1, tag);
} }
} }

View File

@@ -1,5 +1,6 @@
import { BuiltInSlotType, LiteGraph, type SlotLayout } from "@litegraph-ts/core"; import { BuiltInSlotType, LiteGraph, type SlotLayout } from "@litegraph-ts/core";
import ComfyGraphNode, { type ComfyGraphNodeProperties } from "../ComfyGraphNode"; import ComfyGraphNode, { type ComfyGraphNodeProperties } from "../ComfyGraphNode";
import { playSound } from "$lib/utils";
export interface ComfyPlaySoundActionProperties extends ComfyGraphNodeProperties { export interface ComfyPlaySoundActionProperties extends ComfyGraphNodeProperties {
sound: string, sound: string,
@@ -21,9 +22,7 @@ export default class ComfyPlaySoundAction extends ComfyGraphNode {
override onAction(action: any, param: any) { override onAction(action: any, param: any) {
const sound = this.getInputData(0) || this.properties.sound; const sound = this.getInputData(0) || this.properties.sound;
if (sound) { if (sound) {
const url = `${location.origin}/sound/${sound}`; playSound(sound)
const audio = new Audio(url);
audio.play();
} }
}; };
} }

View File

@@ -667,6 +667,13 @@ const ALL_ATTRIBUTES: AttributesSpecList = [
location: "workflow", location: "workflow",
editable: true, editable: true,
defaultValue: true defaultValue: true
},
{
name: "showDefaultNotifications",
type: "boolean",
location: "workflow",
editable: true,
defaultValue: true
} }
] ]
} }

View File

@@ -3,6 +3,8 @@ import type { Progress, SerializedPromptInputsAll, SerializedPromptOutputs, Work
import type { ComfyExecutionResult } from "$lib/nodes/ComfyWidgetNodes"; import type { ComfyExecutionResult } from "$lib/nodes/ComfyWidgetNodes";
import notify from "$lib/notify"; import notify from "$lib/notify";
import { get, writable, type Writable } from "svelte/store"; import { get, writable, type Writable } from "svelte/store";
import workflowState from "./workflowState";
import { playSound } from "$lib/utils";
export type QueueEntryStatus = "success" | "error" | "interrupted" | "all_cached" | "unknown"; export type QueueEntryStatus = "success" | "error" | "interrupted" | "all_cached" | "unknown";
@@ -267,6 +269,11 @@ function executingUpdated(promptID: PromptID, runningNodeID: ComfyNodeID | null)
moveToCompleted(index, queue, "all_cached", "(Execution was cached)"); moveToCompleted(index, queue, "all_cached", "(Execution was cached)");
} }
else if (entry.nodesRan.size >= totalNodesInPrompt) { else if (entry.nodesRan.size >= totalNodesInPrompt) {
const workflow = workflowState.getWorkflow(entry.extraData.workflowID);
if (workflow?.attrs.showDefaultNotifications) {
notify("Prompt finished!", { type: "success" });
playSound("notification.mp3")
}
moveToCompleted(index, queue, "success") moveToCompleted(index, queue, "success")
} }
else { else {

View File

@@ -54,6 +54,13 @@ export type WorkflowAttributes = {
* Comfy.QueueEvents node. * Comfy.QueueEvents node.
*/ */
queuePromptButtonRunWorkflow: boolean, queuePromptButtonRunWorkflow: boolean,
/*
* If true, notifications will be shown when a prompt is queued and
* completed. Set to false if you need more detailed control over the
* notification type/contents, and use the `ComfyNotifyAction` node instead.
*/
showDefaultNotifications: boolean,
} }
export class ComfyBoxWorkflow { export class ComfyBoxWorkflow {
@@ -217,7 +224,7 @@ export class ComfyBoxWorkflow {
// this.#invokeExtensions("loadedGraphNode", node); // this.#invokeExtensions("loadedGraphNode", node);
} }
this.attrs = data.attrs; this.attrs = { ...defaultWorkflowAttributes, ...data.attrs };
// Now restore the layout // Now restore the layout
// Subsequent added nodes will add the UI data to layoutState // Subsequent added nodes will add the UI data to layoutState

View File

@@ -622,3 +622,9 @@ export function nextLetter(s: string): string {
} }
}); });
} }
export function playSound(sound: string) {
const url = `${location.origin}/sound/${sound}`;
const audio = new Audio(url);
audio.play();
}