feat: add ComfyUI integration for image generation and management

- Implemented ComfyGenerateRequest type and associated functions for generating images using various architectures and modes.
- Added functions for listing generation options and handling image uploads.
- Created workflows for different generation modes including SDXL, Z-Image, Z-Image Turbo, and Anima.
- Introduced GenerationJobStatus component to display the status of ongoing generation jobs.
- Developed MaskControls for managing mask operations and displaying mask analysis.
- Created palette items for tool selection, layer management, and generation settings.
This commit is contained in:
syntaxbullet
2026-07-10 23:15:02 +02:00
parent 41bbd1e16b
commit 5e4b548ad4
80 changed files with 2114 additions and 1954 deletions

View File

@@ -4,7 +4,7 @@ import type { AppState, MaskEditState } from "@editor/state";
import type { AppStore } from "@editor/store";
import type { InteractionMode } from "@editor/tools";
import type { GlobalKeybindConsumer, GlobalPointerConsumer, GlobalWheelConsumer } from "@input/index";
import { brushUnavailableHint, canPreviewBrush, type BrushTargetEditorState } from "./canvas/brush";
import { brushUnavailableHint, canPreviewBrush, type BrushTargetEditorState } from "@operations/paint/brush";
import { canvasCursorClass } from "./canvas/cursor";
import { useCanvasInput } from "./canvas/useCanvasInput";
import { useCanvasRenderer } from "./canvas/useCanvasRenderer";
@@ -37,10 +37,10 @@ export function CanvasViewport({
useCanvasRenderer(canvasRef, store);
useCanvasResize(canvasRef, store.dispatch);
const input = useCanvasInput(canvasRef, store, inputOptions);
useCanvasInput(canvasRef, store, inputOptions);
const brushHint = brushUnavailableHint(cursorState.document, cursorState.editor);
const hasBrushPreview = Boolean(cursorState.hasBrushPreview && !brushHint && canPreviewBrush(cursorState.document, cursorState.editor));
const cursorClass = canvasCursorClass(cursorState.editor.tools.interactionMode, input, hasBrushPreview, !brushHint);
const cursorClass = canvasCursorClass(cursorState.editor.tools.interactionMode, cursorState.isPanning, hasBrushPreview, !brushHint);
return <canvas ref={canvasRef} className={`h-full w-full ${cursorClass}`} />;
}
@@ -49,6 +49,7 @@ type CanvasCursorState = {
document: ImageDocument;
editor: BrushTargetEditorState;
hasBrushPreview: boolean;
isPanning: boolean;
};
function selectCanvasCursorState(state: AppState): CanvasCursorState {
@@ -63,6 +64,7 @@ function selectCanvasCursorState(state: AppState): CanvasCursorState {
maskEdit: state.editor.maskEdit,
},
hasBrushPreview: Boolean(state.editor.brushPreview),
isPanning: state.editor.pointerSession?.type === "pan",
};
}
@@ -70,6 +72,7 @@ function canvasCursorStatesEqual(a: CanvasCursorState, b: CanvasCursorState): bo
return (
a.document === b.document &&
a.hasBrushPreview === b.hasBrushPreview &&
a.isPanning === b.isPanning &&
a.editor.selection === b.editor.selection &&
a.editor.tools.activeTool === b.editor.tools.activeTool &&
interactionModesEqual(a.editor.tools.interactionMode, b.editor.tools.interactionMode) &&