tidy(ui): rename canvas stuff

This commit is contained in:
psychedelicious 2024-08-02 14:00:51 +10:00
parent ad9312e989
commit fc558094c2
29 changed files with 235 additions and 235 deletions

View File

@ -6,7 +6,7 @@ import {
sessionStagingAreaImageAccepted,
sessionStagingAreaReset,
} from 'features/controlLayers/store/canvasV2Slice';
import type { LayerEntity } from 'features/controlLayers/store/types';
import type { CanvasLayerState } from 'features/controlLayers/store/types';
import { imageDTOToImageObject } from 'features/controlLayers/store/types';
import { toast } from 'features/toast/toast';
import { t } from 'i18next';
@ -62,7 +62,7 @@ export const addStagingListeners = (startAppListening: AppStartListening) => {
const { imageDTO, offsetX, offsetY } = stagingAreaImage;
const imageObject = imageDTOToImageObject(imageDTO);
const overrides: Partial<LayerEntity> = {
const overrides: Partial<CanvasLayerState> = {
position: { x: x + offsetX, y: y + offsetY },
objects: [imageObject],
};

View File

@ -5,7 +5,7 @@ import IAIDndImage from 'common/components/IAIDndImage';
import IAIDndImageIcon from 'common/components/IAIDndImageIcon';
import { bboxHeightChanged, bboxWidthChanged } from 'features/controlLayers/store/canvasV2Slice';
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
import type { ControlAdapterEntity } from 'features/controlLayers/store/types';
import type { CanvasControlAdapterState } from 'features/controlLayers/store/types';
import type { ImageDraggableData, TypesafeDroppableData } from 'features/dnd/types';
import { calculateNewSize } from 'features/parameters/components/DocumentSize/calculateNewSize';
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
@ -20,7 +20,7 @@ import {
import type { ImageDTO, PostUploadAction } from 'services/api/types';
type Props = {
controlAdapter: ControlAdapterEntity;
controlAdapter: CanvasControlAdapterState;
onChangeImage: (imageDTO: ImageDTO | null) => void;
droppableData: TypesafeDroppableData;
postUploadAction: PostUploadAction;

View File

@ -3,7 +3,7 @@ import { rgbaColorToString } from 'common/util/colorCodeTransformers';
import { deepClone } from 'common/util/deepClone';
import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { BrushLine } from 'features/controlLayers/store/types';
import type { CanvasBrushLineState } from 'features/controlLayers/store/types';
import Konva from 'konva';
import type { Logger } from 'roarr';
@ -18,13 +18,13 @@ export class CanvasBrushLine {
log: Logger;
getLoggingContext: (extra?: JSONObject) => JSONObject;
state: BrushLine;
state: CanvasBrushLineState;
konva: {
group: Konva.Group;
line: Konva.Line;
};
constructor(state: BrushLine, parent: CanvasLayer) {
constructor(state: CanvasBrushLineState, parent: CanvasLayer) {
const { id, strokeWidth, clip, color, points } = state;
this.id = id;
this.parent = parent;
@ -59,7 +59,7 @@ export class CanvasBrushLine {
this.state = state;
}
update(state: BrushLine, force?: boolean): boolean {
update(state: CanvasBrushLineState, force?: boolean): boolean {
if (force || this.state !== state) {
this.log.trace({ state }, 'Updating brush line');
const { points, color, clip, strokeWidth } = state;

View File

@ -2,7 +2,7 @@ import { CanvasEntity } from 'features/controlLayers/konva/CanvasEntity';
import { CanvasImage } from 'features/controlLayers/konva/CanvasImage';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasTransformer } from 'features/controlLayers/konva/CanvasTransformer';
import { type ControlAdapterEntity, isDrawingTool } from 'features/controlLayers/store/types';
import { type CanvasControlAdapterState, isDrawingTool } from 'features/controlLayers/store/types';
import Konva from 'konva';
export class CanvasControlAdapter extends CanvasEntity {
@ -13,7 +13,7 @@ export class CanvasControlAdapter extends CanvasEntity {
static OBJECT_GROUP_NAME = `${CanvasControlAdapter.NAME_PREFIX}_object-group`;
type = 'control_adapter';
_state: ControlAdapterEntity;
_state: CanvasControlAdapterState;
konva: {
layer: Konva.Layer;
@ -24,7 +24,7 @@ export class CanvasControlAdapter extends CanvasEntity {
image: CanvasImage | null;
transformer: CanvasTransformer;
constructor(state: ControlAdapterEntity, manager: CanvasManager) {
constructor(state: CanvasControlAdapterState, manager: CanvasManager) {
super(state.id, manager);
this.konva = {
layer: new Konva.Layer({
@ -47,7 +47,7 @@ export class CanvasControlAdapter extends CanvasEntity {
this._state = state;
}
async render(state: ControlAdapterEntity) {
async render(state: CanvasControlAdapterState) {
this._state = state;
// Update the layer's position and listening state

View File

@ -2,7 +2,7 @@ import { rgbaColorToString } from 'common/util/colorCodeTransformers';
import { deepClone } from 'common/util/deepClone';
import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { EraserLine, GetLoggingContext } from 'features/controlLayers/store/types';
import type { CanvasEraserLineState, GetLoggingContext } from 'features/controlLayers/store/types';
import { RGBA_RED } from 'features/controlLayers/store/types';
import Konva from 'konva';
import type { Logger } from 'roarr';
@ -18,13 +18,13 @@ export class CanvasEraserLine {
log: Logger;
getLoggingContext: GetLoggingContext;
state: EraserLine;
state: CanvasEraserLineState;
konva: {
group: Konva.Group;
line: Konva.Line;
};
constructor(state: EraserLine, parent: CanvasLayer) {
constructor(state: CanvasEraserLineState, parent: CanvasLayer) {
const { id, strokeWidth, clip, points } = state;
this.id = id;
this.parent = parent;
@ -58,7 +58,7 @@ export class CanvasEraserLine {
this.state = state;
}
update(state: EraserLine, force?: boolean): boolean {
update(state: CanvasEraserLineState, force?: boolean): boolean {
if (force || this.state !== state) {
this.log.trace({ state }, 'Updating eraser line');
const { points, clip, strokeWidth } = state;

View File

@ -4,7 +4,7 @@ import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { CanvasStagingArea } from 'features/controlLayers/konva/CanvasStagingArea';
import { FILTER_MAP } from 'features/controlLayers/konva/filters';
import { loadImage } from 'features/controlLayers/konva/util';
import type { GetLoggingContext, ImageObject } from 'features/controlLayers/store/types';
import type { GetLoggingContext, CanvasImageState } from 'features/controlLayers/store/types';
import { t } from 'i18next';
import Konva from 'konva';
import type { Logger } from 'roarr';
@ -24,7 +24,7 @@ export class CanvasImage {
log: Logger;
getLoggingContext: GetLoggingContext;
state: ImageObject;
state: CanvasImageState;
konva: {
group: Konva.Group;
placeholder: { group: Konva.Group; rect: Konva.Rect; text: Konva.Text };
@ -34,7 +34,7 @@ export class CanvasImage {
isLoading: boolean;
isError: boolean;
constructor(state: ImageObject, parent: CanvasLayer | CanvasStagingArea) {
constructor(state: CanvasImageState, parent: CanvasLayer | CanvasStagingArea) {
const { id, width, height, x, y } = state;
this.id = id;
this.parent = parent;
@ -138,7 +138,7 @@ export class CanvasImage {
}
}
async update(state: ImageObject, force?: boolean): Promise<boolean> {
async update(state: CanvasImageState, force?: boolean): Promise<boolean> {
if (this.state !== state || force) {
this.log.trace({ state }, 'Updating image');

View File

@ -5,7 +5,7 @@ import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasRect } from 'features/controlLayers/konva/CanvasRect';
import { getNodeBboxFast } from 'features/controlLayers/konva/entityBbox';
import { mapId } from 'features/controlLayers/konva/util';
import type { BrushLine, EraserLine, InpaintMaskEntity, RectShape } from 'features/controlLayers/store/types';
import type { CanvasBrushLineState, CanvasEraserLineState, CanvasInpaintMaskState, CanvasRectState } from 'features/controlLayers/store/types';
import { isDrawingTool, RGBA_RED } from 'features/controlLayers/store/types';
import Konva from 'konva';
import { assert } from 'tsafe';
@ -18,8 +18,8 @@ export class CanvasInpaintMask {
static OBJECT_GROUP_NAME = `${CanvasInpaintMask.NAME_PREFIX}_object-group`;
static COMPOSITING_RECT_NAME = `${CanvasInpaintMask.NAME_PREFIX}_compositing-rect`;
private drawingBuffer: BrushLine | EraserLine | RectShape | null;
private state: InpaintMaskEntity;
private drawingBuffer: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null;
private state: CanvasInpaintMaskState;
id = 'inpaint_mask';
manager: CanvasManager;
@ -33,7 +33,7 @@ export class CanvasInpaintMask {
};
objects: Map<string, CanvasBrushLine | CanvasEraserLine | CanvasRect>;
constructor(state: InpaintMaskEntity, manager: CanvasManager) {
constructor(state: CanvasInpaintMaskState, manager: CanvasManager) {
this.manager = manager;
this.konva = {
@ -87,12 +87,12 @@ export class CanvasInpaintMask {
return this.drawingBuffer;
}
async setDrawingBuffer(obj: BrushLine | EraserLine | RectShape | null) {
async setDrawingBuffer(obj: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null) {
this.drawingBuffer = obj;
if (this.drawingBuffer) {
if (this.drawingBuffer.type === 'brush_line') {
this.drawingBuffer.color = RGBA_RED;
} else if (this.drawingBuffer.type === 'rect_shape') {
} else if (this.drawingBuffer.type === 'rect') {
this.drawingBuffer.color = RGBA_RED;
}
@ -109,13 +109,13 @@ export class CanvasInpaintMask {
this.manager.stateApi.onBrushLineAdded({ id: this.id, brushLine: this.drawingBuffer }, 'inpaint_mask');
} else if (this.drawingBuffer.type === 'eraser_line') {
this.manager.stateApi.onEraserLineAdded({ id: this.id, eraserLine: this.drawingBuffer }, 'inpaint_mask');
} else if (this.drawingBuffer.type === 'rect_shape') {
} else if (this.drawingBuffer.type === 'rect') {
this.manager.stateApi.onRectShapeAdded({ id: this.id, rectShape: this.drawingBuffer }, 'inpaint_mask');
}
this.setDrawingBuffer(null);
}
async render(state: InpaintMaskEntity) {
async render(state: CanvasInpaintMaskState) {
this.state = state;
// Update the layer's position and listening state
@ -153,7 +153,7 @@ export class CanvasInpaintMask {
this.updateGroup(didDraw);
}
private async renderObject(obj: InpaintMaskEntity['objects'][number], force = false): Promise<boolean> {
private async renderObject(obj: CanvasInpaintMaskState['objects'][number], force = false): Promise<boolean> {
if (obj.type === 'brush_line') {
let brushLine = this.objects.get(obj.id);
assert(brushLine instanceof CanvasBrushLine || brushLine === undefined);
@ -182,7 +182,7 @@ export class CanvasInpaintMask {
return true;
}
}
} else if (obj.type === 'rect_shape') {
} else if (obj.type === 'rect') {
let rect = this.objects.get(obj.id);
assert(rect instanceof CanvasRect || rect === undefined);

View File

@ -9,14 +9,14 @@ import { CanvasTransformer } from 'features/controlLayers/konva/CanvasTransforme
import { getPrefixedId, konvaNodeToBlob, mapId, previewBlob } from 'features/controlLayers/konva/util';
import { layerRasterized } from 'features/controlLayers/store/canvasV2Slice';
import type {
BrushLine,
CanvasBrushLineState,
CanvasEraserLineState,
CanvasLayerState,
CanvasRectState,
CanvasV2State,
Coordinate,
EraserLine,
GetLoggingContext,
LayerEntity,
Rect,
RectShape,
} from 'features/controlLayers/store/types';
import { imageDTOToImageObject } from 'features/controlLayers/store/types';
import Konva from 'konva';
@ -39,8 +39,8 @@ export class CanvasLayer {
log: Logger;
getLoggingContext: GetLoggingContext;
drawingBuffer: BrushLine | EraserLine | RectShape | null;
state: LayerEntity;
drawingBuffer: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null;
state: CanvasLayerState;
konva: {
layer: Konva.Layer;
@ -57,7 +57,7 @@ export class CanvasLayer {
rect: Rect;
bbox: Rect;
constructor(state: LayerEntity, manager: CanvasManager) {
constructor(state: CanvasLayerState, manager: CanvasManager) {
this.id = state.id;
this.manager = manager;
this.getLoggingContext = this.manager.buildGetLoggingContext(this);
@ -104,7 +104,7 @@ export class CanvasLayer {
return this.drawingBuffer;
};
setDrawingBuffer = async (obj: BrushLine | EraserLine | RectShape | null) => {
setDrawingBuffer = async (obj: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null) => {
if (obj) {
this.drawingBuffer = obj;
await this._renderObject(this.drawingBuffer, true);
@ -129,13 +129,13 @@ export class CanvasLayer {
} else if (drawingBuffer.type === 'eraser_line') {
drawingBuffer.id = getPrefixedId('brush_line');
this.manager.stateApi.onEraserLineAdded({ id: this.id, eraserLine: drawingBuffer }, 'layer');
} else if (drawingBuffer.type === 'rect_shape') {
} else if (drawingBuffer.type === 'rect') {
drawingBuffer.id = getPrefixedId('brush_line');
this.manager.stateApi.onRectShapeAdded({ id: this.id, rectShape: drawingBuffer }, 'layer');
}
};
update = async (arg?: { state: LayerEntity; toolState: CanvasV2State['tool']; isSelected: boolean }) => {
update = async (arg?: { state: CanvasLayerState; toolState: CanvasV2State['tool']; isSelected: boolean }) => {
const state = get(arg, 'state', this.state);
const toolState = get(arg, 'toolState', this.manager.stateApi.getToolState());
const isSelected = get(arg, 'isSelected', this.manager.stateApi.getIsSelected(this.id));
@ -191,7 +191,7 @@ export class CanvasLayer {
this.transformer.update(position, this.bbox);
};
updateObjects = async (arg?: { objects: LayerEntity['objects'] }) => {
updateObjects = async (arg?: { objects: CanvasLayerState['objects'] }) => {
this.log.trace('Updating objects');
const objects = get(arg, 'objects', this.state.objects);
@ -297,7 +297,7 @@ export class CanvasLayer {
});
};
_renderObject = async (obj: LayerEntity['objects'][number], force = false): Promise<boolean> => {
_renderObject = async (obj: CanvasLayerState['objects'][number], force = false): Promise<boolean> => {
if (obj.type === 'brush_line') {
let brushLine = this.objects.get(obj.id);
assert(brushLine instanceof CanvasBrushLine || brushLine === undefined);
@ -324,7 +324,7 @@ export class CanvasLayer {
return true;
}
}
} else if (obj.type === 'rect_shape') {
} else if (obj.type === 'rect') {
let rect = this.objects.get(obj.id);
assert(rect instanceof CanvasRect || rect === undefined);

View File

@ -2,7 +2,7 @@ import { rgbaColorToString } from 'common/util/colorCodeTransformers';
import { deepClone } from 'common/util/deepClone';
import type { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { GetLoggingContext, RectShape } from 'features/controlLayers/store/types';
import type { GetLoggingContext, CanvasRectState } from 'features/controlLayers/store/types';
import Konva from 'konva';
import type { Logger } from 'roarr';
@ -17,13 +17,13 @@ export class CanvasRect {
log: Logger;
getLoggingContext: GetLoggingContext;
state: RectShape;
state: CanvasRectState;
konva: {
group: Konva.Group;
rect: Konva.Rect;
};
constructor(state: RectShape, parent: CanvasLayer) {
constructor(state: CanvasRectState, parent: CanvasLayer) {
const { id, x, y, width, height, color } = state;
this.id = id;
this.parent = parent;
@ -48,7 +48,7 @@ export class CanvasRect {
this.state = state;
}
update(state: RectShape, force?: boolean): boolean {
update(state: CanvasRectState, force?: boolean): boolean {
if (this.state !== state || force) {
this.log.trace({ state }, 'Updating rect');
const { x, y, width, height, color } = state;

View File

@ -5,7 +5,7 @@ import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasRect } from 'features/controlLayers/konva/CanvasRect';
import { getNodeBboxFast } from 'features/controlLayers/konva/entityBbox';
import { mapId } from 'features/controlLayers/konva/util';
import type { BrushLine, EraserLine, RectShape, RegionEntity } from 'features/controlLayers/store/types';
import type { CanvasBrushLineState, CanvasEraserLineState, CanvasRectState, CanvasRegionalGuidanceState } from 'features/controlLayers/store/types';
import { isDrawingTool, RGBA_RED } from 'features/controlLayers/store/types';
import Konva from 'konva';
import { assert } from 'tsafe';
@ -18,8 +18,8 @@ export class CanvasRegion {
static OBJECT_GROUP_NAME = `${CanvasRegion.NAME_PREFIX}_object-group`;
static COMPOSITING_RECT_NAME = `${CanvasRegion.NAME_PREFIX}_compositing-rect`;
private drawingBuffer: BrushLine | EraserLine | RectShape | null;
private state: RegionEntity;
private drawingBuffer: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null;
private state: CanvasRegionalGuidanceState;
id: string;
manager: CanvasManager;
@ -34,7 +34,7 @@ export class CanvasRegion {
objects: Map<string, CanvasBrushLine | CanvasEraserLine | CanvasRect>;
constructor(state: RegionEntity, manager: CanvasManager) {
constructor(state: CanvasRegionalGuidanceState, manager: CanvasManager) {
this.id = state.id;
this.manager = manager;
@ -86,12 +86,12 @@ export class CanvasRegion {
return this.drawingBuffer;
}
async setDrawingBuffer(obj: BrushLine | EraserLine | RectShape | null) {
async setDrawingBuffer(obj: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null) {
this.drawingBuffer = obj;
if (this.drawingBuffer) {
if (this.drawingBuffer.type === 'brush_line') {
this.drawingBuffer.color = RGBA_RED;
} else if (this.drawingBuffer.type === 'rect_shape') {
} else if (this.drawingBuffer.type === 'rect') {
this.drawingBuffer.color = RGBA_RED;
}
@ -108,13 +108,13 @@ export class CanvasRegion {
this.manager.stateApi.onBrushLineAdded({ id: this.id, brushLine: this.drawingBuffer }, 'regional_guidance');
} else if (this.drawingBuffer.type === 'eraser_line') {
this.manager.stateApi.onEraserLineAdded({ id: this.id, eraserLine: this.drawingBuffer }, 'regional_guidance');
} else if (this.drawingBuffer.type === 'rect_shape') {
} else if (this.drawingBuffer.type === 'rect') {
this.manager.stateApi.onRectShapeAdded({ id: this.id, rectShape: this.drawingBuffer }, 'regional_guidance');
}
this.setDrawingBuffer(null);
}
async render(state: RegionEntity) {
async render(state: CanvasRegionalGuidanceState) {
this.state = state;
// Update the layer's position and listening state
@ -152,7 +152,7 @@ export class CanvasRegion {
this.updateGroup(didDraw);
}
private async renderObject(obj: RegionEntity['objects'][number], force = false): Promise<boolean> {
private async renderObject(obj: CanvasRegionalGuidanceState['objects'][number], force = false): Promise<boolean> {
if (obj.type === 'brush_line') {
let brushLine = this.objects.get(obj.id);
assert(brushLine instanceof CanvasBrushLine || brushLine === undefined);
@ -181,7 +181,7 @@ export class CanvasRegion {
return true;
}
}
} else if (obj.type === 'rect_shape') {
} else if (obj.type === 'rect') {
let rect = this.objects.get(obj.id);
assert(rect instanceof CanvasRect || rect === undefined);

View File

@ -46,11 +46,11 @@ import {
} from 'features/controlLayers/store/canvasV2Slice';
import type {
BboxChangedArg,
BrushLine,
CanvasBrushLineState,
CanvasEntity,
EraserLine,
CanvasEraserLineState,
PositionChangedArg,
RectShape,
CanvasRectState,
ScaleChangedArg,
Tool,
} from 'features/controlLayers/store/types';
@ -111,7 +111,7 @@ export class CanvasStateApi {
this.store.dispatch(imBboxChanged(arg));
}
};
onBrushLineAdded = (arg: { id: string; brushLine: BrushLine }, entityType: CanvasEntity['type']) => {
onBrushLineAdded = (arg: { id: string; brushLine: CanvasBrushLineState }, entityType: CanvasEntity['type']) => {
log.debug('Brush line added');
if (entityType === 'layer') {
this.store.dispatch(layerBrushLineAdded(arg));
@ -121,7 +121,7 @@ export class CanvasStateApi {
this.store.dispatch(imBrushLineAdded(arg));
}
};
onEraserLineAdded = (arg: { id: string; eraserLine: EraserLine }, entityType: CanvasEntity['type']) => {
onEraserLineAdded = (arg: { id: string; eraserLine: CanvasEraserLineState }, entityType: CanvasEntity['type']) => {
log.debug('Eraser line added');
if (entityType === 'layer') {
this.store.dispatch(layerEraserLineAdded(arg));
@ -131,7 +131,7 @@ export class CanvasStateApi {
this.store.dispatch(imEraserLineAdded(arg));
}
};
onRectShapeAdded = (arg: { id: string; rectShape: RectShape }, entityType: CanvasEntity['type']) => {
onRectShapeAdded = (arg: { id: string; rectShape: CanvasRectState }, entityType: CanvasEntity['type']) => {
log.debug('Rect shape added');
if (entityType === 'layer') {
this.store.dispatch(layerRectShapeAdded(arg));

View File

@ -4,9 +4,9 @@ import { imageDataToDataURL } from 'features/controlLayers/konva/util';
import type {
BboxChangedArg,
CanvasEntity,
ControlAdapterEntity,
LayerEntity,
RegionEntity,
CanvasControlAdapterState,
CanvasLayerState,
CanvasRegionalGuidanceState,
} from 'features/controlLayers/store/types';
import Konva from 'konva';
import type { IRect } from 'konva/lib/types';
@ -198,9 +198,9 @@ const filterCAChildren = (node: Konva.Node): boolean => true;
*/
export const updateBboxes = (
stage: Konva.Stage,
layers: LayerEntity[],
controlAdapters: ControlAdapterEntity[],
regions: RegionEntity[],
layers: CanvasLayerState[],
controlAdapters: CanvasControlAdapterState[],
regions: CanvasRegionalGuidanceState[],
onBboxChanged: (arg: BboxChangedArg, entityType: CanvasEntity['type']) => void
): void => {
for (const entityState of [...layers, ...controlAdapters, ...regions]) {

View File

@ -8,9 +8,9 @@ import {
import type {
CanvasV2State,
Coordinate,
InpaintMaskEntity,
LayerEntity,
RegionEntity,
CanvasInpaintMaskState,
CanvasLayerState,
CanvasRegionalGuidanceState,
Tool,
} from 'features/controlLayers/store/types';
import { isDrawableEntity, isDrawableEntityAdapter } from 'features/controlLayers/store/types';
@ -81,7 +81,7 @@ const getLastPointOfLine = (points: number[]): Coordinate | null => {
};
const getLastPointOfLastLineOfEntity = (
entity: LayerEntity | RegionEntity | InpaintMaskEntity,
entity: CanvasLayerState | CanvasRegionalGuidanceState | CanvasInpaintMaskState,
tool: Tool
): Coordinate | null => {
const lastObject = entity.objects[entity.objects.length - 1];
@ -138,7 +138,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
return e.evt.buttons === 1;
}
function getClip(entity: RegionEntity | LayerEntity | InpaintMaskEntity) {
function getClip(entity: CanvasRegionalGuidanceState | CanvasLayerState | CanvasInpaintMaskState) {
const settings = getSettings();
const bboxRect = getBbox().rect;
@ -264,8 +264,8 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
await selectedEntityAdapter.finalizeDrawingBuffer();
}
await selectedEntityAdapter.setDrawingBuffer({
id: getObjectId('rect_shape', true),
type: 'rect_shape',
id: getObjectId('rect', true),
type: 'rect',
x: Math.round(normalizedPoint.x),
y: Math.round(normalizedPoint.y),
width: 0,
@ -314,7 +314,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
if (toolState.selected === 'rect') {
const drawingBuffer = selectedEntityAdapter.getDrawingBuffer();
if (drawingBuffer?.type === 'rect_shape') {
if (drawingBuffer?.type === 'rect') {
await selectedEntityAdapter.finalizeDrawingBuffer();
} else {
await selectedEntityAdapter.setDrawingBuffer(null);
@ -411,7 +411,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
if (toolState.selected === 'rect') {
const drawingBuffer = selectedEntityAdapter.getDrawingBuffer();
if (drawingBuffer) {
if (drawingBuffer.type === 'rect_shape') {
if (drawingBuffer.type === 'rect') {
const normalizedPoint = offsetCoord(pos, selectedEntity.position);
drawingBuffer.width = Math.round(normalizedPoint.x - drawingBuffer.x);
drawingBuffer.height = Math.round(normalizedPoint.y - drawingBuffer.y);
@ -455,7 +455,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
drawingBuffer.points.push(alignedPoint.x, alignedPoint.y);
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);
await selectedEntityAdapter.finalizeDrawingBuffer();
} else if (toolState.selected === 'rect' && drawingBuffer?.type === 'rect_shape') {
} else if (toolState.selected === 'rect' && drawingBuffer?.type === 'rect') {
drawingBuffer.width = Math.round(normalizedPoint.x - drawingBuffer.x);
drawingBuffer.height = Math.round(normalizedPoint.y - drawingBuffer.y);
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);

View File

@ -1,7 +1,7 @@
import { getImageDataTransparency } from 'common/util/arrayBuffer';
import { CanvasLayer } from 'features/controlLayers/konva/CanvasLayer';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { Coordinate, GenerationMode, Rect, RenderableObject, RgbaColor } from 'features/controlLayers/store/types';
import type { Coordinate, GenerationMode, Rect, CanvasObjectState, RgbaColor } from 'features/controlLayers/store/types';
import { isValidLayer } from 'features/nodes/util/graph/generation/addLayers';
import Konva from 'konva';
import type { KonvaEventObject } from 'konva/lib/Node';
@ -618,7 +618,7 @@ export function getPrefixedId(prefix: string): string {
return `${prefix}:${nanoid()}`;
}
export function getObjectId(type: RenderableObject['type'], isBuffer?: boolean): string {
export function getObjectId(type: CanvasObjectState['type'], isBuffer?: boolean): string {
if (isBuffer) {
return getPrefixedId(`buffer_${type}`);
} else {

View File

@ -9,16 +9,16 @@ import { v4 as uuidv4 } from 'uuid';
import type {
CanvasV2State,
ControlAdapterEntity,
CanvasControlAdapterState,
ControlModeV2,
ControlNetConfig,
ControlNetData,
CanvasControlNetState,
Filter,
PositionChangedArg,
ProcessorConfig,
ScaleChangedArg,
T2IAdapterConfig,
T2IAdapterData,
CanvasT2IAdapterState,
} from './types';
import { buildControlAdapterProcessorV2, imageDTOToImageObject } from './types';
@ -51,7 +51,7 @@ export const controlAdaptersReducers = {
payload: { id: uuidv4(), ...payload },
}),
},
caRecalled: (state, action: PayloadAction<{ data: ControlAdapterEntity }>) => {
caRecalled: (state, action: PayloadAction<{ data: CanvasControlAdapterState }>) => {
const { data } = action.payload;
state.controlAdapters.entities.push(data);
state.selectedEntityIdentifier = { type: 'control_adapter', id: data.id };
@ -217,11 +217,11 @@ export const controlAdaptersReducers = {
// We may need to convert the CA to match the model
if (ca.adapterType === 't2i_adapter' && ca.model.type === 'controlnet') {
const convertedCA: ControlNetData = { ...ca, adapterType: 'controlnet', controlMode: 'balanced' };
const convertedCA: CanvasControlNetState = { ...ca, adapterType: 'controlnet', controlMode: 'balanced' };
state.controlAdapters.entities.splice(state.controlAdapters.entities.indexOf(ca), 1, convertedCA);
} else if (ca.adapterType === 'controlnet' && ca.model.type === 't2i_adapter') {
const { controlMode: _, ...rest } = ca;
const convertedCA: T2IAdapterData = { ...rest, adapterType: 't2i_adapter' };
const convertedCA: CanvasT2IAdapterState = { ...rest, adapterType: 't2i_adapter' };
state.controlAdapters.entities.splice(state.controlAdapters.entities.indexOf(ca), 1, convertedCA);
}
},

View File

@ -1,11 +1,11 @@
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
import type {
BrushLine,
CanvasBrushLineState,
CanvasV2State,
Coordinate,
EraserLine,
InpaintMaskEntity,
RectShape,
CanvasEraserLineState,
CanvasInpaintMaskState,
CanvasRectState,
ScaleChangedArg,
} from 'features/controlLayers/store/types';
import { imageDTOToImageWithDims } from 'features/controlLayers/store/types';
@ -21,7 +21,7 @@ export const inpaintMaskReducers = {
state.inpaintMask.bboxNeedsUpdate = false;
state.inpaintMask.imageCache = null;
},
imRecalled: (state, action: PayloadAction<{ data: InpaintMaskEntity }>) => {
imRecalled: (state, action: PayloadAction<{ data: CanvasInpaintMaskState }>) => {
const { data } = action.payload;
state.inpaintMask = data;
state.selectedEntityIdentifier = { type: 'inpaint_mask', id: data.id };
@ -42,7 +42,7 @@ export const inpaintMaskReducers = {
} else if (obj.type === 'eraser_line') {
obj.points = obj.points.map((point) => point * scale);
obj.strokeWidth *= scale;
} else if (obj.type === 'rect_shape') {
} else if (obj.type === 'rect') {
obj.x *= scale;
obj.y *= scale;
obj.height *= scale;
@ -66,19 +66,19 @@ export const inpaintMaskReducers = {
const { imageDTO } = action.payload;
state.inpaintMask.imageCache = imageDTO ? imageDTOToImageWithDims(imageDTO) : null;
},
imBrushLineAdded: (state, action: PayloadAction<{ brushLine: BrushLine }>) => {
imBrushLineAdded: (state, action: PayloadAction<{ brushLine: CanvasBrushLineState }>) => {
const { brushLine } = action.payload;
state.inpaintMask.objects.push(brushLine);
state.inpaintMask.bboxNeedsUpdate = true;
state.layers.imageCache = null;
},
imEraserLineAdded: (state, action: PayloadAction<{ eraserLine: EraserLine }>) => {
imEraserLineAdded: (state, action: PayloadAction<{ eraserLine: CanvasEraserLineState }>) => {
const { eraserLine } = action.payload;
state.inpaintMask.objects.push(eraserLine);
state.inpaintMask.bboxNeedsUpdate = true;
state.layers.imageCache = null;
},
imRectShapeAdded: (state, action: PayloadAction<{ rectShape: RectShape }>) => {
imRectShapeAdded: (state, action: PayloadAction<{ rectShape: CanvasRectState }>) => {
const { rectShape } = action.payload;
state.inpaintMask.objects.push(rectShape);
state.inpaintMask.bboxNeedsUpdate = true;

View File

@ -4,7 +4,7 @@ import type { ImageDTO, IPAdapterModelConfig } from 'services/api/types';
import { assert } from 'tsafe';
import { v4 as uuidv4 } from 'uuid';
import type { CanvasV2State, CLIPVisionModelV2, IPAdapterConfig, IPAdapterEntity, IPMethodV2 } from './types';
import type { CanvasV2State, CLIPVisionModelV2, IPAdapterConfig, CanvasIPAdapterState, IPMethodV2 } from './types';
import { imageDTOToImageObject } from './types';
export const selectIPA = (state: CanvasV2State, id: string) => state.ipAdapters.entities.find((ipa) => ipa.id === id);
@ -18,7 +18,7 @@ export const ipAdaptersReducers = {
ipaAdded: {
reducer: (state, action: PayloadAction<{ id: string; config: IPAdapterConfig }>) => {
const { id, config } = action.payload;
const layer: IPAdapterEntity = {
const layer: CanvasIPAdapterState = {
id,
type: 'ip_adapter',
isEnabled: true,
@ -29,7 +29,7 @@ export const ipAdaptersReducers = {
},
prepare: (payload: { config: IPAdapterConfig }) => ({ payload: { id: uuidv4(), ...payload } }),
},
ipaRecalled: (state, action: PayloadAction<{ data: IPAdapterEntity }>) => {
ipaRecalled: (state, action: PayloadAction<{ data: CanvasIPAdapterState }>) => {
const { data } = action.payload;
state.ipAdapters.entities.push(data);
state.selectedEntityIdentifier = { type: 'ip_adapter', id: data.id };

View File

@ -7,15 +7,15 @@ import type { ImageDTO } from 'services/api/types';
import { assert } from 'tsafe';
import type {
BrushLine,
CanvasBrushLineState,
CanvasV2State,
Coordinate,
EraserLine,
ImageObject,
CanvasEraserLineState,
CanvasImageState,
ImageObjectAddedArg,
LayerEntity,
CanvasLayerState,
PositionChangedArg,
RectShape,
CanvasRectState,
} from './types';
import { imageDTOToImageObject, imageDTOToImageWithDims } from './types';
@ -28,9 +28,9 @@ export const selectLayerOrThrow = (state: CanvasV2State, id: string) => {
export const layersReducers = {
layerAdded: {
reducer: (state, action: PayloadAction<{ id: string; overrides?: Partial<LayerEntity> }>) => {
reducer: (state, action: PayloadAction<{ id: string; overrides?: Partial<CanvasLayerState> }>) => {
const { id } = action.payload;
const layer: LayerEntity = {
const layer: CanvasLayerState = {
id,
type: 'layer',
isEnabled: true,
@ -43,11 +43,11 @@ export const layersReducers = {
state.selectedEntityIdentifier = { type: 'layer', id };
state.layers.imageCache = null;
},
prepare: (payload: { overrides?: Partial<LayerEntity> }) => ({
prepare: (payload: { overrides?: Partial<CanvasLayerState> }) => ({
payload: { ...payload, id: getPrefixedId('layer') },
}),
},
layerRecalled: (state, action: PayloadAction<{ data: LayerEntity }>) => {
layerRecalled: (state, action: PayloadAction<{ data: CanvasLayerState }>) => {
const { data } = action.payload;
state.layers.entities.push(data);
state.selectedEntityIdentifier = { type: 'layer', id: data.id };
@ -148,7 +148,7 @@ export const layersReducers = {
moveToStart(state.layers.entities, layer);
state.layers.imageCache = null;
},
layerBrushLineAdded: (state, action: PayloadAction<{ id: string; brushLine: BrushLine }>) => {
layerBrushLineAdded: (state, action: PayloadAction<{ id: string; brushLine: CanvasBrushLineState }>) => {
const { id, brushLine } = action.payload;
const layer = selectLayer(state, id);
if (!layer) {
@ -158,7 +158,7 @@ export const layersReducers = {
layer.objects.push(brushLine);
state.layers.imageCache = null;
},
layerEraserLineAdded: (state, action: PayloadAction<{ id: string; eraserLine: EraserLine }>) => {
layerEraserLineAdded: (state, action: PayloadAction<{ id: string; eraserLine: CanvasEraserLineState }>) => {
const { id, eraserLine } = action.payload;
const layer = selectLayer(state, id);
if (!layer) {
@ -168,7 +168,7 @@ export const layersReducers = {
layer.objects.push(eraserLine);
state.layers.imageCache = null;
},
layerRectShapeAdded: (state, action: PayloadAction<{ id: string; rectShape: RectShape }>) => {
layerRectShapeAdded: (state, action: PayloadAction<{ id: string; rectShape: CanvasRectState }>) => {
const { id, rectShape } = action.payload;
const layer = selectLayer(state, id);
if (!layer) {
@ -199,7 +199,7 @@ export const layersReducers = {
const { imageDTO } = action.payload;
state.layers.imageCache = imageDTO ? imageDTOToImageWithDims(imageDTO) : null;
},
layerRasterized: (state, action: PayloadAction<{ id: string; imageObject: ImageObject; position: Coordinate }>) => {
layerRasterized: (state, action: PayloadAction<{ id: string; imageObject: CanvasImageState; position: Coordinate }>) => {
const { id, imageObject, position } = action.payload;
const layer = selectLayer(state, id);
if (!layer) {

View File

@ -1,13 +1,13 @@
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
import { moveOneToEnd, moveOneToStart, moveToEnd, moveToStart } from 'common/util/arrayUtils';
import type {
BrushLine,
CanvasBrushLineState,
CanvasV2State,
CLIPVisionModelV2,
EraserLine,
CanvasEraserLineState,
IPMethodV2,
PositionChangedArg,
RectShape,
CanvasRectState,
ScaleChangedArg,
} from 'features/controlLayers/store/types';
import { imageDTOToImageObject, imageDTOToImageWithDims } from 'features/controlLayers/store/types';
@ -19,7 +19,7 @@ import type { ImageDTO, IPAdapterModelConfig } from 'services/api/types';
import { assert } from 'tsafe';
import { v4 as uuidv4 } from 'uuid';
import type { IPAdapterEntity, RegionEntity, RgbColor } from './types';
import type { CanvasIPAdapterState, CanvasRegionalGuidanceState, RgbColor } from './types';
export const selectRG = (state: CanvasV2State, id: string) => state.regions.entities.find((rg) => rg.id === id);
export const selectRGOrThrow = (state: CanvasV2State, id: string) => {
@ -54,7 +54,7 @@ export const regionsReducers = {
rgAdded: {
reducer: (state, action: PayloadAction<{ id: string }>) => {
const { id } = action.payload;
const rg: RegionEntity = {
const rg: CanvasRegionalGuidanceState = {
id,
type: 'regional_guidance',
isEnabled: true,
@ -85,7 +85,7 @@ export const regionsReducers = {
rg.bboxNeedsUpdate = false;
rg.imageCache = null;
},
rgRecalled: (state, action: PayloadAction<{ data: RegionEntity }>) => {
rgRecalled: (state, action: PayloadAction<{ data: CanvasRegionalGuidanceState }>) => {
const { data } = action.payload;
state.regions.entities.push(data);
state.selectedEntityIdentifier = { type: 'regional_guidance', id: data.id };
@ -117,7 +117,7 @@ export const regionsReducers = {
} else if (obj.type === 'eraser_line') {
obj.points = obj.points.map((point) => point * scale);
obj.strokeWidth *= scale;
} else if (obj.type === 'rect_shape') {
} else if (obj.type === 'rect') {
obj.x *= scale;
obj.y *= scale;
obj.height *= scale;
@ -215,7 +215,7 @@ export const regionsReducers = {
}
rg.autoNegative = autoNegative;
},
rgIPAdapterAdded: (state, action: PayloadAction<{ id: string; ipAdapter: IPAdapterEntity }>) => {
rgIPAdapterAdded: (state, action: PayloadAction<{ id: string; ipAdapter: CanvasIPAdapterState }>) => {
const { id, ipAdapter } = action.payload;
const rg = selectRG(state, id);
if (!rg) {
@ -328,7 +328,7 @@ export const regionsReducers = {
}
ipa.clipVisionModel = clipVisionModel;
},
rgBrushLineAdded: (state, action: PayloadAction<{ id: string; brushLine: BrushLine }>) => {
rgBrushLineAdded: (state, action: PayloadAction<{ id: string; brushLine: CanvasBrushLineState }>) => {
const { id, brushLine } = action.payload;
const rg = selectRG(state, id);
if (!rg) {
@ -339,7 +339,7 @@ export const regionsReducers = {
rg.bboxNeedsUpdate = true;
state.layers.imageCache = null;
},
rgEraserLineAdded: (state, action: PayloadAction<{ id: string; eraserLine: EraserLine }>) => {
rgEraserLineAdded: (state, action: PayloadAction<{ id: string; eraserLine: CanvasEraserLineState }>) => {
const { id, eraserLine } = action.payload;
const rg = selectRG(state, id);
if (!rg) {
@ -350,7 +350,7 @@ export const regionsReducers = {
rg.bboxNeedsUpdate = true;
state.layers.imageCache = null;
},
rgRectShapeAdded: (state, action: PayloadAction<{ id: string; rectShape: RectShape }>) => {
rgRectShapeAdded: (state, action: PayloadAction<{ id: string; rectShape: CanvasRectState }>) => {
const { id, rectShape } = action.payload;
const rg = selectRG(state, id);
if (!rg) {

View File

@ -527,7 +527,7 @@ const zRect = z.object({
});
export type Rect = z.infer<typeof zRect>;
const zBrushLine = z.object({
const zCanvasBrushLineState = z.object({
id: zId,
type: z.literal('brush_line'),
strokeWidth: z.number().min(1),
@ -535,32 +535,32 @@ const zBrushLine = z.object({
color: zRgbaColor,
clip: zRect.nullable(),
});
export type BrushLine = z.infer<typeof zBrushLine>;
export type CanvasBrushLineState = z.infer<typeof zCanvasBrushLineState>;
const zEraserline = z.object({
const zCanvasEraserLineState = z.object({
id: zId,
type: z.literal('eraser_line'),
strokeWidth: z.number().min(1),
points: zPoints,
clip: zRect.nullable(),
});
export type EraserLine = z.infer<typeof zEraserline>;
export type CanvasEraserLineState = z.infer<typeof zCanvasEraserLineState>;
const zRectShape = z.object({
const zCanvasRectState = z.object({
id: zId,
type: z.literal('rect_shape'),
type: z.literal('rect'),
x: z.number(),
y: z.number(),
width: z.number().min(1),
height: z.number().min(1),
color: zRgbaColor,
});
export type RectShape = z.infer<typeof zRectShape>;
export type CanvasRectState = z.infer<typeof zCanvasRectState>;
const zFilter = z.enum(['LightnessToAlphaFilter']);
export type Filter = z.infer<typeof zFilter>;
const zImageObject = z.object({
const zCanvasImageState = z.object({
id: zId,
type: z.literal('image'),
image: zImageWithDims,
@ -570,46 +570,46 @@ const zImageObject = z.object({
height: z.number().min(1),
filters: z.array(zFilter),
});
export type ImageObject = z.infer<typeof zImageObject>;
export type CanvasImageState = z.infer<typeof zCanvasImageState>;
const zRenderableObject = z.discriminatedUnion('type', [zImageObject, zBrushLine, zEraserline, zRectShape]);
export type RenderableObject = z.infer<typeof zRenderableObject>;
const zCanvasObjectState = z.discriminatedUnion('type', [zCanvasImageState, zCanvasBrushLineState, zCanvasEraserLineState, zCanvasRectState]);
export type CanvasObjectState = z.infer<typeof zCanvasObjectState>;
export const zLayerEntity = z.object({
export const zCanvasLayerState = z.object({
id: zId,
type: z.literal('layer'),
isEnabled: z.boolean(),
position: zCoordinate,
opacity: zOpacity,
objects: z.array(zRenderableObject),
objects: z.array(zCanvasObjectState),
});
export type LayerEntity = z.infer<typeof zLayerEntity>;
export type CanvasLayerState = z.infer<typeof zCanvasLayerState>;
export const zIPAdapterEntity = z.object({
export const zCanvasIPAdapterState = z.object({
id: zId,
type: z.literal('ip_adapter'),
isEnabled: z.boolean(),
weight: z.number().gte(-1).lte(2),
method: zIPMethodV2,
imageObject: zImageObject.nullable(),
imageObject: zCanvasImageState.nullable(),
model: zModelIdentifierField.nullable(),
clipVisionModel: zCLIPVisionModelV2,
beginEndStepPct: zBeginEndStepPct,
});
export type IPAdapterEntity = z.infer<typeof zIPAdapterEntity>;
export type CanvasIPAdapterState = z.infer<typeof zCanvasIPAdapterState>;
export type IPAdapterConfig = Pick<
IPAdapterEntity,
CanvasIPAdapterState,
'weight' | 'imageObject' | 'beginEndStepPct' | 'model' | 'clipVisionModel' | 'method'
>;
const zMaskObject = z
.discriminatedUnion('type', [zOLD_VectorMaskLine, zOLD_VectorMaskRect, zBrushLine, zEraserline, zRectShape])
.discriminatedUnion('type', [zOLD_VectorMaskLine, zOLD_VectorMaskRect, zCanvasBrushLineState, zCanvasEraserLineState, zCanvasRectState])
.transform((val) => {
// Migrate old vector mask objects to new format
if (val.type === 'vector_mask_line') {
const { tool, ...rest } = val;
if (tool === 'brush') {
const asBrushline: BrushLine = {
const asBrushline: CanvasBrushLineState = {
...rest,
type: 'brush_line',
color: { r: 255, g: 255, b: 255, a: 1 },
@ -617,7 +617,7 @@ const zMaskObject = z
};
return asBrushline;
} else if (tool === 'eraser') {
const asEraserLine: EraserLine = {
const asEraserLine: CanvasEraserLineState = {
...rest,
type: 'eraser_line',
clip: null,
@ -625,9 +625,9 @@ const zMaskObject = z
return asEraserLine;
}
} else if (val.type === 'vector_mask_rect') {
const asRectShape: RectShape = {
const asRectShape: CanvasRectState = {
...val,
type: 'rect_shape',
type: 'rect',
color: { r: 255, g: 255, b: 255, a: 1 },
};
return asRectShape;
@ -635,9 +635,9 @@ const zMaskObject = z
return val;
}
})
.pipe(z.discriminatedUnion('type', [zBrushLine, zEraserline, zRectShape]));
.pipe(z.discriminatedUnion('type', [zCanvasBrushLineState, zCanvasEraserLineState, zCanvasRectState]));
export const zRegionEntity = z.object({
export const zCanvasRegionalGuidanceState = z.object({
id: zId,
type: z.literal('regional_guidance'),
isEnabled: z.boolean(),
@ -647,12 +647,12 @@ export const zRegionEntity = z.object({
objects: z.array(zMaskObject),
positivePrompt: zParameterPositivePrompt.nullable(),
negativePrompt: zParameterNegativePrompt.nullable(),
ipAdapters: z.array(zIPAdapterEntity),
ipAdapters: z.array(zCanvasIPAdapterState),
fill: zRgbColor,
autoNegative: zAutoNegative,
imageCache: zImageWithDims.nullable(),
});
export type RegionEntity = z.infer<typeof zRegionEntity>;
export type CanvasRegionalGuidanceState = z.infer<typeof zCanvasRegionalGuidanceState>;
const zColorFill = z.object({
type: z.literal('color_fill'),
@ -663,7 +663,7 @@ const zImageFill = z.object({
src: z.string(),
});
const zFill = z.discriminatedUnion('type', [zColorFill, zImageFill]);
const zInpaintMaskEntity = z.object({
const zCanvasInpaintMaskState = z.object({
id: z.literal('inpaint_mask'),
type: z.literal('inpaint_mask'),
isEnabled: z.boolean(),
@ -674,7 +674,7 @@ const zInpaintMaskEntity = z.object({
fill: zRgbColor,
imageCache: zImageWithDims.nullable(),
});
export type InpaintMaskEntity = z.infer<typeof zInpaintMaskEntity>;
export type CanvasInpaintMaskState = z.infer<typeof zCanvasInpaintMaskState>;
const zInitialImageEntity = z.object({
id: z.literal('initial_image'),
@ -682,11 +682,11 @@ const zInitialImageEntity = z.object({
isEnabled: z.boolean(),
bbox: zRect.nullable(),
bboxNeedsUpdate: z.boolean(),
imageObject: zImageObject.nullable(),
imageObject: zCanvasImageState.nullable(),
});
export type InitialImageEntity = z.infer<typeof zInitialImageEntity>;
const zControlAdapterEntityBase = z.object({
const zCanvasControlAdapterStateBase = z.object({
id: zId,
type: z.literal('control_adapter'),
isEnabled: z.boolean(),
@ -696,27 +696,27 @@ const zControlAdapterEntityBase = z.object({
opacity: zOpacity,
filters: z.array(zFilter),
weight: z.number().gte(-1).lte(2),
imageObject: zImageObject.nullable(),
processedImageObject: zImageObject.nullable(),
imageObject: zCanvasImageState.nullable(),
processedImageObject: zCanvasImageState.nullable(),
processorConfig: zProcessorConfig.nullable(),
processorPendingBatchId: z.string().nullable().default(null),
beginEndStepPct: zBeginEndStepPct,
model: zModelIdentifierField.nullable(),
});
const zControlNetEntity = zControlAdapterEntityBase.extend({
const zCanvasControlNetState = zCanvasControlAdapterStateBase.extend({
adapterType: z.literal('controlnet'),
controlMode: zControlModeV2,
});
export type ControlNetData = z.infer<typeof zControlNetEntity>;
const zT2IAdapterEntity = zControlAdapterEntityBase.extend({
export type CanvasControlNetState = z.infer<typeof zCanvasControlNetState>;
const zCanvasT2IAdapteState = zCanvasControlAdapterStateBase.extend({
adapterType: z.literal('t2i_adapter'),
});
export type T2IAdapterData = z.infer<typeof zT2IAdapterEntity>;
export type CanvasT2IAdapterState = z.infer<typeof zCanvasT2IAdapteState>;
export const zControlAdapterEntity = z.discriminatedUnion('adapterType', [zControlNetEntity, zT2IAdapterEntity]);
export type ControlAdapterEntity = z.infer<typeof zControlAdapterEntity>;
export const zCanvasControlAdapterState = z.discriminatedUnion('adapterType', [zCanvasControlNetState, zCanvasT2IAdapteState]);
export type CanvasControlAdapterState = z.infer<typeof zCanvasControlAdapterState>;
export type ControlNetConfig = Pick<
ControlNetData,
CanvasControlNetState,
| 'adapterType'
| 'weight'
| 'imageObject'
@ -727,7 +727,7 @@ export type ControlNetConfig = Pick<
| 'controlMode'
>;
export type T2IAdapterConfig = Pick<
T2IAdapterData,
CanvasT2IAdapterState,
'adapterType' | 'weight' | 'imageObject' | 'processedImageObject' | 'processorConfig' | 'beginEndStepPct' | 'model'
>;
@ -778,7 +778,7 @@ export const imageDTOToImageWithDims = ({ image_name, width, height }: ImageDTO)
height,
});
export const imageDTOToImageObject = (imageDTO: ImageDTO, overrides?: Partial<ImageObject>): ImageObject => {
export const imageDTOToImageObject = (imageDTO: ImageDTO, overrides?: Partial<CanvasImageState>): CanvasImageState => {
const { width, height, image_name } = imageDTO;
return {
id: getObjectId('image'),
@ -803,11 +803,11 @@ export const isBoundingBoxScaleMethod = (v: unknown): v is BoundingBoxScaleMetho
zBoundingBoxScaleMethod.safeParse(v).success;
export type CanvasEntity =
| LayerEntity
| ControlAdapterEntity
| RegionEntity
| InpaintMaskEntity
| IPAdapterEntity
| CanvasLayerState
| CanvasControlAdapterState
| CanvasRegionalGuidanceState
| CanvasInpaintMaskState
| CanvasIPAdapterState
| InitialImageEntity;
export type CanvasEntityIdentifier = Pick<CanvasEntity, 'id' | 'type'>;
@ -827,14 +827,14 @@ export type StagingAreaImage = {
export type CanvasV2State = {
_version: 3;
selectedEntityIdentifier: CanvasEntityIdentifier | null;
inpaintMask: InpaintMaskEntity;
inpaintMask: CanvasInpaintMaskState;
layers: {
imageCache: ImageWithDims | null;
entities: LayerEntity[];
entities: CanvasLayerState[];
};
controlAdapters: { entities: ControlAdapterEntity[] };
ipAdapters: { entities: IPAdapterEntity[] };
regions: { entities: RegionEntity[] };
controlAdapters: { entities: CanvasControlAdapterState[] };
ipAdapters: { entities: CanvasIPAdapterState[] };
regions: { entities: CanvasRegionalGuidanceState[] };
loras: LoRA[];
initialImage: InitialImageEntity;
tool: {
@ -932,7 +932,7 @@ export type RectShapeAddedArg = { id: string; rect: IRect; color: RgbaColor };
export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; position?: Coordinate };
//#region Type guards
export const isLine = (obj: RenderableObject): obj is BrushLine | EraserLine => {
export const isLine = (obj: CanvasObjectState): obj is CanvasBrushLineState | CanvasEraserLineState => {
return obj.type === 'brush_line' || obj.type === 'eraser_line';
};
@ -949,7 +949,7 @@ export type RemoveIndexString<T> = {
export type GenerationMode = 'txt2img' | 'img2img' | 'inpaint' | 'outpaint';
export function isDrawableEntity(entity: CanvasEntity): entity is LayerEntity | RegionEntity | InpaintMaskEntity {
export function isDrawableEntity(entity: CanvasEntity): entity is CanvasLayerState | CanvasRegionalGuidanceState | CanvasInpaintMaskState {
return entity.type === 'layer' || entity.type === 'regional_guidance' || entity.type === 'inpaint_mask';
}

View File

@ -1,4 +1,4 @@
import type { LayerEntity } from 'features/controlLayers/store/types';
import type { CanvasLayerState } from 'features/controlLayers/store/types';
import { MetadataItemView } from 'features/metadata/components/MetadataItemView';
import type { MetadataHandlers } from 'features/metadata/types';
import { handlers } from 'features/metadata/util/handlers';
@ -9,7 +9,7 @@ type Props = {
};
export const MetadataLayers = ({ metadata }: Props) => {
const [layers, setLayers] = useState<LayerEntity[]>([]);
const [layers, setLayers] = useState<CanvasLayerState[]>([]);
useEffect(() => {
const parse = async () => {
@ -40,8 +40,8 @@ const MetadataViewLayer = ({
handlers,
}: {
label: string;
layer: LayerEntity;
handlers: MetadataHandlers<LayerEntity[], LayerEntity>;
layer: CanvasLayerState;
handlers: MetadataHandlers<CanvasLayerState[], CanvasLayerState>;
}) => {
const onRecall = useCallback(() => {
if (!handlers.recallItem) {

View File

@ -2,7 +2,7 @@ import { getStore } from 'app/store/nanostores/store';
import { deepClone } from 'common/util/deepClone';
import { objectKeys } from 'common/util/objectKeys';
import { shouldConcatPromptsChanged } from 'features/controlLayers/store/canvasV2Slice';
import type { LayerEntity, LoRA } from 'features/controlLayers/store/types';
import type { CanvasLayerState, LoRA } from 'features/controlLayers/store/types';
import type {
AnyControlAdapterConfigMetadata,
BuildMetadataHandlers,
@ -48,7 +48,7 @@ const renderControlAdapterValue: MetadataRenderValueFunc<AnyControlAdapterConfig
return `${value.model.key} (${value.model.base.toUpperCase()}) - ${value.weight}`;
}
};
const renderLayerValue: MetadataRenderValueFunc<LayerEntity> = async (layer) => {
const renderLayerValue: MetadataRenderValueFunc<CanvasLayerState> = async (layer) => {
if (layer.type === 'initial_image_layer') {
let rendered = t('controlLayers.globalInitialImageLayer');
if (layer.image) {
@ -88,7 +88,7 @@ const renderLayerValue: MetadataRenderValueFunc<LayerEntity> = async (layer) =>
}
assert(false, 'Unknown layer type');
};
const renderLayersValue: MetadataRenderValueFunc<LayerEntity[]> = async (layers) => {
const renderLayersValue: MetadataRenderValueFunc<CanvasLayerState[]> = async (layers) => {
return `${layers.length} ${t('controlLayers.layers', { count: layers.length })}`;
};

View File

@ -1,6 +1,6 @@
import { getCAId, getImageObjectId, getIPAId, getLayerId } from 'features/controlLayers/konva/naming';
import { defaultLoRAConfig } from 'features/controlLayers/store/lorasReducers';
import type { ControlAdapterEntity, IPAdapterEntity, LayerEntity, LoRA } from 'features/controlLayers/store/types';
import type { CanvasControlAdapterState, CanvasIPAdapterState, CanvasLayerState, LoRA } from 'features/controlLayers/store/types';
import {
CA_PROCESSOR_DATA,
imageDTOToImageWithDims,
@ -8,7 +8,7 @@ import {
initialIPAdapterV2,
initialT2IAdapterV2,
isProcessorTypeV2,
zLayerEntity,
zCanvasLayerState,
} from 'features/controlLayers/store/types';
import type {
ControlNetConfigMetadata,
@ -424,22 +424,22 @@ const parseAllIPAdapters: MetadataParseFunc<IPAdapterConfigMetadata[]> = async (
};
//#region Control Layers
const parseLayer: MetadataParseFunc<LayerEntity> = async (metadataItem) => zLayerEntity.parseAsync(metadataItem);
const parseLayer: MetadataParseFunc<CanvasLayerState> = async (metadataItem) => zCanvasLayerState.parseAsync(metadataItem);
const parseLayers: MetadataParseFunc<LayerEntity[]> = async (metadata) => {
const parseLayers: MetadataParseFunc<CanvasLayerState[]> = async (metadata) => {
// We need to support recalling pre-Control Layers metadata into Control Layers. A separate set of parsers handles
// taking pre-CL metadata and parsing it into layers. It doesn't always map 1-to-1, so this is best-effort. For
// example, CL Control Adapters don't support resize mode, so we simply omit that property.
try {
const layers: LayerEntity[] = [];
const layers: CanvasLayerState[] = [];
try {
const control_layers = await getProperty(metadata, 'control_layers');
const controlLayersRaw = await getProperty(control_layers, 'layers', isArray);
const controlLayersParseResults = await Promise.allSettled(controlLayersRaw.map(parseLayer));
const controlLayers = controlLayersParseResults
.filter((result): result is PromiseFulfilledResult<LayerEntity> => result.status === 'fulfilled')
.filter((result): result is PromiseFulfilledResult<CanvasLayerState> => result.status === 'fulfilled')
.map((result) => result.value);
layers.push(...controlLayers);
} catch {
@ -452,7 +452,7 @@ const parseLayers: MetadataParseFunc<LayerEntity[]> = async (metadata) => {
controlNetsRaw.map(async (cn) => await parseControlNetToControlAdapterLayer(cn))
);
const controlNetsAsLayers = controlNetsParseResults
.filter((result): result is PromiseFulfilledResult<ControlAdapterEntity> => result.status === 'fulfilled')
.filter((result): result is PromiseFulfilledResult<CanvasControlAdapterState> => result.status === 'fulfilled')
.map((result) => result.value);
layers.push(...controlNetsAsLayers);
} catch {
@ -465,7 +465,7 @@ const parseLayers: MetadataParseFunc<LayerEntity[]> = async (metadata) => {
t2iAdaptersRaw.map(async (cn) => await parseT2IAdapterToControlAdapterLayer(cn))
);
const t2iAdaptersAsLayers = t2iAdaptersParseResults
.filter((result): result is PromiseFulfilledResult<ControlAdapterEntity> => result.status === 'fulfilled')
.filter((result): result is PromiseFulfilledResult<CanvasControlAdapterState> => result.status === 'fulfilled')
.map((result) => result.value);
layers.push(...t2iAdaptersAsLayers);
} catch {
@ -478,7 +478,7 @@ const parseLayers: MetadataParseFunc<LayerEntity[]> = async (metadata) => {
ipAdaptersRaw.map(async (cn) => await parseIPAdapterToIPAdapterLayer(cn))
);
const ipAdaptersAsLayers = ipAdaptersParseResults
.filter((result): result is PromiseFulfilledResult<IPAdapterEntity> => result.status === 'fulfilled')
.filter((result): result is PromiseFulfilledResult<CanvasIPAdapterState> => result.status === 'fulfilled')
.map((result) => result.value);
layers.push(...ipAdaptersAsLayers);
} catch {
@ -498,14 +498,14 @@ const parseLayers: MetadataParseFunc<LayerEntity[]> = async (metadata) => {
}
};
const parseInitialImageToInitialImageLayer: MetadataParseFunc<LayerEntity> = async (metadata) => {
const parseInitialImageToInitialImageLayer: MetadataParseFunc<CanvasLayerState> = async (metadata) => {
// TODO(psyche): recall denoise strength
// const denoisingStrength = await getProperty(metadata, 'strength', isParameterStrength);
const imageName = await getProperty(metadata, 'init_image', isString);
const imageDTO = await getImageDTO(imageName);
assert(imageDTO, 'ImageDTO is null');
const id = getLayerId(uuidv4());
const layer: LayerEntity = {
const layer: CanvasLayerState = {
id,
type: 'layer',
bbox: null,
@ -529,7 +529,7 @@ const parseInitialImageToInitialImageLayer: MetadataParseFunc<LayerEntity> = asy
return layer;
};
const parseControlNetToControlAdapterLayer: MetadataParseFunc<ControlAdapterEntity> = async (metadataItem) => {
const parseControlNetToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapterState> = async (metadataItem) => {
const control_model = await getProperty(metadataItem, 'control_model');
const key = await getModelKey(control_model, 'controlnet');
const controlNetModel = await fetchModelConfigWithTypeGuard(key, isControlNetModelConfig);
@ -569,7 +569,7 @@ const parseControlNetToControlAdapterLayer: MetadataParseFunc<ControlAdapterEnti
const imageDTO = image ? await getImageDTO(image.image_name) : null;
const processedImageDTO = processedImage ? await getImageDTO(processedImage.image_name) : null;
const layer: ControlAdapterEntity = {
const layer: CanvasControlAdapterState = {
id: getCAId(uuidv4()),
type: 'control_adapter',
bbox: null,
@ -593,7 +593,7 @@ const parseControlNetToControlAdapterLayer: MetadataParseFunc<ControlAdapterEnti
return layer;
};
const parseT2IAdapterToControlAdapterLayer: MetadataParseFunc<ControlAdapterEntity> = async (metadataItem) => {
const parseT2IAdapterToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapterState> = async (metadataItem) => {
const t2i_adapter_model = await getProperty(metadataItem, 't2i_adapter_model');
const key = await getModelKey(t2i_adapter_model, 't2i_adapter');
const t2iAdapterModel = await fetchModelConfigWithTypeGuard(key, isT2IAdapterModelConfig);
@ -630,7 +630,7 @@ const parseT2IAdapterToControlAdapterLayer: MetadataParseFunc<ControlAdapterEnti
const imageDTO = image ? await getImageDTO(image.image_name) : null;
const processedImageDTO = processedImage ? await getImageDTO(processedImage.image_name) : null;
const layer: ControlAdapterEntity = {
const layer: CanvasControlAdapterState = {
id: getCAId(uuidv4()),
bbox: null,
bboxNeedsUpdate: true,
@ -653,7 +653,7 @@ const parseT2IAdapterToControlAdapterLayer: MetadataParseFunc<ControlAdapterEnti
return layer;
};
const parseIPAdapterToIPAdapterLayer: MetadataParseFunc<IPAdapterEntity> = async (metadataItem) => {
const parseIPAdapterToIPAdapterLayer: MetadataParseFunc<CanvasIPAdapterState> = async (metadataItem) => {
const ip_adapter_model = await getProperty(metadataItem, 'ip_adapter_model');
const key = await getModelKey(ip_adapter_model, 'ip_adapter');
const ipAdapterModel = await fetchModelConfigWithTypeGuard(key, isIPAdapterModelConfig);
@ -685,7 +685,7 @@ const parseIPAdapterToIPAdapterLayer: MetadataParseFunc<IPAdapterEntity> = async
];
const imageDTO = image ? await getImageDTO(image.image_name) : null;
const layer: IPAdapterEntity = {
const layer: CanvasIPAdapterState = {
id: getIPAId(uuidv4()),
type: 'ip_adapter',
isEnabled: true,

View File

@ -40,11 +40,11 @@ import {
vaeSelected,
} from 'features/controlLayers/store/canvasV2Slice';
import type {
ControlAdapterEntity,
IPAdapterEntity,
LayerEntity,
CanvasControlAdapterState,
CanvasIPAdapterState,
CanvasLayerState,
LoRA,
RegionEntity,
CanvasRegionalGuidanceState,
} from 'features/controlLayers/store/types';
import { setHrfEnabled, setHrfMethod, setHrfStrength } from 'features/hrf/store/hrfSlice';
import type {
@ -246,7 +246,7 @@ const recallIPAdapters: MetadataRecallFunc<IPAdapterConfigMetadata[]> = (ipAdapt
});
};
const recallCA: MetadataRecallFunc<ControlAdapterEntity> = async (ca) => {
const recallCA: MetadataRecallFunc<CanvasControlAdapterState> = async (ca) => {
const { dispatch } = getStore();
const clone = deepClone(ca);
if (clone.image) {
@ -275,7 +275,7 @@ const recallCA: MetadataRecallFunc<ControlAdapterEntity> = async (ca) => {
return;
};
const recallIPA: MetadataRecallFunc<IPAdapterEntity> = async (ipa) => {
const recallIPA: MetadataRecallFunc<CanvasIPAdapterState> = async (ipa) => {
const { dispatch } = getStore();
const clone = deepClone(ipa);
if (clone.imageObject) {
@ -298,7 +298,7 @@ const recallIPA: MetadataRecallFunc<IPAdapterEntity> = async (ipa) => {
return;
};
const recallRG: MetadataRecallFunc<RegionEntity> = async (rg) => {
const recallRG: MetadataRecallFunc<CanvasRegionalGuidanceState> = async (rg) => {
const { dispatch } = getStore();
const clone = deepClone(rg);
// Strip out the uploaded mask image property - this is an intermediate image
@ -328,7 +328,7 @@ const recallRG: MetadataRecallFunc<RegionEntity> = async (rg) => {
};
//#region Control Layers
const recallLayer: MetadataRecallFunc<LayerEntity> = async (layer) => {
const recallLayer: MetadataRecallFunc<CanvasLayerState> = async (layer) => {
const { dispatch } = getStore();
const clone = deepClone(layer);
const invalidObjects: string[] = [];
@ -348,7 +348,7 @@ const recallLayer: MetadataRecallFunc<LayerEntity> = async (layer) => {
obj.id = getEraserLineId(clone.id, uuidv4());
} else if (obj.type === 'image') {
obj.id = getImageObjectId(clone.id, uuidv4());
} else if (obj.type === 'rect_shape') {
} else if (obj.type === 'rect') {
obj.id = getRectShapeId(clone.id, uuidv4());
} else {
logger('metadata').error(`Unknown object type ${obj.type}`);
@ -359,7 +359,7 @@ const recallLayer: MetadataRecallFunc<LayerEntity> = async (layer) => {
return;
};
const recallLayers: MetadataRecallFunc<LayerEntity[]> = (layers) => {
const recallLayers: MetadataRecallFunc<CanvasLayerState[]> = (layers) => {
const { dispatch } = getStore();
dispatch(layerAllDeleted());
for (const l of layers) {

View File

@ -1,5 +1,5 @@
import { getStore } from 'app/store/nanostores/store';
import type { LayerEntity, LoRA } from 'features/controlLayers/store/types';
import type { CanvasLayerState, LoRA } from 'features/controlLayers/store/types';
import type {
ControlNetConfigMetadata,
IPAdapterConfigMetadata,
@ -109,7 +109,7 @@ const validateIPAdapters: MetadataValidateFunc<IPAdapterConfigMetadata[]> = (ipA
return new Promise((resolve) => resolve(validatedIPAdapters));
};
const validateLayer: MetadataValidateFunc<LayerEntity> = async (layer) => {
const validateLayer: MetadataValidateFunc<CanvasLayerState> = async (layer) => {
if (layer.type === 'control_adapter_layer') {
const model = layer.controlAdapter.model;
assert(model, 'Control Adapter layer missing model');
@ -131,8 +131,8 @@ const validateLayer: MetadataValidateFunc<LayerEntity> = async (layer) => {
return layer;
};
const validateLayers: MetadataValidateFunc<LayerEntity[]> = async (layers) => {
const validatedLayers: LayerEntity[] = [];
const validateLayers: MetadataValidateFunc<CanvasLayerState[]> = async (layers) => {
const validatedLayers: CanvasLayerState[] = [];
for (const l of layers) {
try {
const validated = await validateLayer(l);

View File

@ -1,11 +1,11 @@
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type {
ControlAdapterEntity,
ControlNetData,
CanvasControlAdapterState,
CanvasControlNetState,
ImageWithDims,
ProcessorConfig,
Rect,
T2IAdapterData,
CanvasT2IAdapterState,
} from 'features/controlLayers/store/types';
import type { ImageField } from 'features/nodes/types/common';
import { CONTROL_NET_COLLECT, T2I_ADAPTER_COLLECT } from 'features/nodes/util/graph/constants';
@ -15,12 +15,12 @@ import { assert } from 'tsafe';
export const addControlAdapters = async (
manager: CanvasManager,
controlAdapters: ControlAdapterEntity[],
controlAdapters: CanvasControlAdapterState[],
g: Graph,
bbox: Rect,
denoise: Invocation<'denoise_latents'>,
base: BaseModelType
): Promise<ControlAdapterEntity[]> => {
): Promise<CanvasControlAdapterState[]> => {
const validControlAdapters = controlAdapters.filter((ca) => isValidControlAdapter(ca, base));
for (const ca of validControlAdapters) {
if (ca.adapterType === 'controlnet') {
@ -51,7 +51,7 @@ const addControlNetCollectorSafe = (g: Graph, denoise: Invocation<'denoise_laten
const addControlNetToGraph = async (
manager: CanvasManager,
ca: ControlNetData,
ca: CanvasControlNetState,
g: Graph,
bbox: Rect,
denoise: Invocation<'denoise_latents'>
@ -96,7 +96,7 @@ const addT2IAdapterCollectorSafe = (g: Graph, denoise: Invocation<'denoise_laten
const addT2IAdapterToGraph = async (
manager: CanvasManager,
ca: T2IAdapterData,
ca: CanvasT2IAdapterState,
g: Graph,
bbox: Rect,
denoise: Invocation<'denoise_latents'>
@ -140,7 +140,7 @@ const buildControlImage = (
assert(false, 'Attempted to add unprocessed control image');
};
const isValidControlAdapter = (ca: ControlAdapterEntity, base: BaseModelType): boolean => {
const isValidControlAdapter = (ca: CanvasControlAdapterState, base: BaseModelType): boolean => {
// Must be have a model that matches the current base and must have a control image
const hasModel = Boolean(ca.model);
const modelMatchesBase = ca.model?.base === base;

View File

@ -1,15 +1,15 @@
import type { IPAdapterEntity } from 'features/controlLayers/store/types';
import type { CanvasIPAdapterState } from 'features/controlLayers/store/types';
import { IP_ADAPTER_COLLECT } from 'features/nodes/util/graph/constants';
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
import type { BaseModelType, Invocation } from 'services/api/types';
import { assert } from 'tsafe';
export const addIPAdapters = (
ipAdapters: IPAdapterEntity[],
ipAdapters: CanvasIPAdapterState[],
g: Graph,
denoise: Invocation<'denoise_latents'>,
base: BaseModelType
): IPAdapterEntity[] => {
): CanvasIPAdapterState[] => {
const validIPAdapters = ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base));
for (const ipa of validIPAdapters) {
addIPAdapter(ipa, g, denoise);
@ -33,7 +33,7 @@ export const addIPAdapterCollectorSafe = (g: Graph, denoise: Invocation<'denoise
}
};
const addIPAdapter = (ipa: IPAdapterEntity, g: Graph, denoise: Invocation<'denoise_latents'>) => {
const addIPAdapter = (ipa: CanvasIPAdapterState, g: Graph, denoise: Invocation<'denoise_latents'>) => {
const { id, weight, model, clipVisionModel, method, beginEndStepPct, imageObject } = ipa;
assert(imageObject, 'IP Adapter image is required');
assert(model, 'IP Adapter model is required');
@ -55,7 +55,7 @@ const addIPAdapter = (ipa: IPAdapterEntity, g: Graph, denoise: Invocation<'denoi
g.addEdge(ipAdapter, 'ip_adapter', ipAdapterCollect, 'item');
};
export const isValidIPAdapter = (ipa: IPAdapterEntity, base: BaseModelType): boolean => {
export const isValidIPAdapter = (ipa: CanvasIPAdapterState, base: BaseModelType): boolean => {
// Must be have a model that matches the current base and must have a control image
const hasModel = Boolean(ipa.model);
const modelMatchesBase = ipa.model?.base === base;

View File

@ -1,6 +1,6 @@
import type { LayerEntity } from 'features/controlLayers/store/types';
import type { CanvasLayerState } from 'features/controlLayers/store/types';
export const isValidLayer = (entity: LayerEntity) => {
export const isValidLayer = (entity: CanvasLayerState) => {
return (
entity.isEnabled &&
// Boolean(entity.bbox) && TODO(psyche): Re-enable this check when we have a way to calculate bbox for all layers

View File

@ -1,6 +1,6 @@
import { deepClone } from 'common/util/deepClone';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { IPAdapterEntity, Rect, RegionEntity } from 'features/controlLayers/store/types';
import type { CanvasIPAdapterState, Rect, CanvasRegionalGuidanceState } from 'features/controlLayers/store/types';
import {
PROMPT_REGION_INVERT_TENSOR_MASK_PREFIX,
PROMPT_REGION_MASK_TO_TENSOR_PREFIX,
@ -28,7 +28,7 @@ import { assert } from 'tsafe';
export const addRegions = async (
manager: CanvasManager,
regions: RegionEntity[],
regions: CanvasRegionalGuidanceState[],
g: Graph,
bbox: Rect,
base: BaseModelType,
@ -37,7 +37,7 @@ export const addRegions = async (
negCond: Invocation<'compel'> | Invocation<'sdxl_compel_prompt'>,
posCondCollect: Invocation<'collect'>,
negCondCollect: Invocation<'collect'>
): Promise<RegionEntity[]> => {
): Promise<CanvasRegionalGuidanceState[]> => {
const isSDXL = base === 'sdxl';
const validRegions = regions.filter((rg) => isValidRegion(rg, base));
@ -173,7 +173,7 @@ export const addRegions = async (
}
}
const validRGIPAdapters: IPAdapterEntity[] = region.ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base));
const validRGIPAdapters: CanvasIPAdapterState[] = region.ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base));
for (const ipa of validRGIPAdapters) {
const ipAdapterCollect = addIPAdapterCollectorSafe(g, denoise);
@ -205,7 +205,7 @@ export const addRegions = async (
return validRegions;
};
export const isValidRegion = (rg: RegionEntity, base: BaseModelType) => {
export const isValidRegion = (rg: CanvasRegionalGuidanceState, base: BaseModelType) => {
const hasTextPrompt = Boolean(rg.positivePrompt || rg.negativePrompt);
const hasIPAdapter = rg.ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base)).length > 0;
return hasTextPrompt || hasIPAdapter;