tidy(ui): remove unused stuff 3

This commit is contained in:
psychedelicious 2024-08-23 15:37:16 +10:00
parent 9ff7647ec5
commit 1a14860b3b
16 changed files with 87 additions and 253 deletions

View File

@ -1,7 +1,7 @@
import { Badge } from '@invoke-ai/ui-library'; import { Badge } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext'; import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
import { selectControlLayerOrThrow } from 'features/controlLayers/store/controlLayersReducers'; import { selectControlLayerEntityOrThrow } from 'features/controlLayers/store/controlLayersReducers';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -9,7 +9,7 @@ export const ControlLayerBadges = memo(() => {
const { id } = useEntityIdentifierContext(); const { id } = useEntityIdentifierContext();
const { t } = useTranslation(); const { t } = useTranslation();
const withTransparencyEffect = useAppSelector( const withTransparencyEffect = useAppSelector(
(s) => selectControlLayerOrThrow(s.canvasV2, id).withTransparencyEffect (s) => selectControlLayerEntityOrThrow(s.canvasV2, id).withTransparencyEffect
); );
return ( return (

View File

@ -6,7 +6,7 @@ import {
controlLayerWithTransparencyEffectToggled, controlLayerWithTransparencyEffectToggled,
selectCanvasV2Slice, selectCanvasV2Slice,
} from 'features/controlLayers/store/canvasV2Slice'; } from 'features/controlLayers/store/canvasV2Slice';
import { selectControlLayerOrThrow } from 'features/controlLayers/store/controlLayersReducers'; import { selectControlLayerEntityOrThrow } from 'features/controlLayers/store/controlLayersReducers';
import { memo, useCallback, useMemo } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { PiDropHalfBold } from 'react-icons/pi'; import { PiDropHalfBold } from 'react-icons/pi';
@ -18,7 +18,7 @@ export const ControlLayerMenuItemsTransparencyEffect = memo(() => {
const selectWithTransparencyEffect = useMemo( const selectWithTransparencyEffect = useMemo(
() => () =>
createSelector(selectCanvasV2Slice, (canvasV2) => { createSelector(selectCanvasV2Slice, (canvasV2) => {
const entity = selectControlLayerOrThrow(canvasV2, entityIdentifier.id); const entity = selectControlLayerEntityOrThrow(canvasV2, entityIdentifier.id);
return entity.withTransparencyEffect; return entity.withTransparencyEffect;
}), }),
[entityIdentifier.id] [entityIdentifier.id]

View File

@ -5,6 +5,7 @@ import { CanvasDropArea } from 'features/controlLayers/components/CanvasDropArea
import { ControlLayersToolbar } from 'features/controlLayers/components/ControlLayersToolbar'; import { ControlLayersToolbar } from 'features/controlLayers/components/ControlLayersToolbar';
import { Filter } from 'features/controlLayers/components/Filters/Filter'; import { Filter } from 'features/controlLayers/components/Filters/Filter';
import { StageComponent } from 'features/controlLayers/components/StageComponent'; import { StageComponent } from 'features/controlLayers/components/StageComponent';
import { StagingAreaIsStagingGate } from 'features/controlLayers/components/StagingArea/StagingAreaIsStagingGate';
import { StagingAreaToolbar } from 'features/controlLayers/components/StagingArea/StagingAreaToolbar'; import { StagingAreaToolbar } from 'features/controlLayers/components/StagingArea/StagingAreaToolbar';
import { Transform } from 'features/controlLayers/components/Transform'; import { Transform } from 'features/controlLayers/components/Transform';
import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate'; import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
@ -32,7 +33,9 @@ export const CanvasEditor = memo(() => {
<ControlLayersToolbar /> <ControlLayersToolbar />
<StageComponent /> <StageComponent />
<Flex position="absolute" bottom={2} gap={2} align="center" justify="center"> <Flex position="absolute" bottom={2} gap={2} align="center" justify="center">
<StagingAreaToolbar /> <StagingAreaIsStagingGate>
<StagingAreaToolbar />
</StagingAreaIsStagingGate>
</Flex> </Flex>
<Flex position="absolute" bottom={16}> <Flex position="absolute" bottom={16}>
<CanvasManagerProviderGate> <CanvasManagerProviderGate>

View File

@ -0,0 +1,15 @@
import { useAppSelector } from 'app/store/storeHooks';
import type { PropsWithChildren } from 'react';
import { memo } from 'react';
export const StagingAreaIsStagingGate = memo((props: PropsWithChildren) => {
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
if (!isStaging) {
return null;
}
return props.children;
});
StagingAreaIsStagingGate.displayName = 'StagingAreaIsStagingGate';

View File

@ -25,18 +25,6 @@ import {
} from 'react-icons/pi'; } from 'react-icons/pi';
export const StagingAreaToolbar = memo(() => { export const StagingAreaToolbar = memo(() => {
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
if (!isStaging) {
return null;
}
return <StagingAreaToolbarContent />;
});
StagingAreaToolbar.displayName = 'StagingAreaToolbar';
export const StagingAreaToolbarContent = memo(() => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const session = useAppSelector((s) => s.canvasV2.session); const session = useAppSelector((s) => s.canvasV2.session);
const shouldShowStagedImage = useStore($shouldShowStagedImage); const shouldShowStagedImage = useStore($shouldShowStagedImage);
@ -204,4 +192,4 @@ export const StagingAreaToolbarContent = memo(() => {
); );
}); });
StagingAreaToolbarContent.displayName = 'StagingAreaToolbarContent'; StagingAreaToolbar.displayName = 'StagingAreaToolbar';

View File

@ -2,14 +2,14 @@ import { createMemoizedAppSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice'; import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice';
import { selectControlLayerOrThrow } from 'features/controlLayers/store/controlLayersReducers'; import { selectControlLayerEntityOrThrow } from 'features/controlLayers/store/controlLayersReducers';
import type { import type {
CanvasEntityIdentifier, CanvasEntityIdentifier,
ControlNetConfig, ControlNetConfig,
IPAdapterConfig, IPAdapterConfig,
T2IAdapterConfig, T2IAdapterConfig,
} from 'features/controlLayers/store/types'; } from 'features/controlLayers/store/types';
import { initialControlNetV2, initialIPAdapterV2, initialT2IAdapterV2 } from 'features/controlLayers/store/types'; import { initialControlNet, initialIPAdapter, initialT2IAdapter } from 'features/controlLayers/store/types';
import { zModelIdentifierField } from 'features/nodes/types/common'; import { zModelIdentifierField } from 'features/nodes/types/common';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useControlNetAndT2IAdapterModels, useIPAdapterModels } from 'services/api/hooks/modelsByType'; import { useControlNetAndT2IAdapterModels, useIPAdapterModels } from 'services/api/hooks/modelsByType';
@ -18,7 +18,7 @@ export const useControlLayerControlAdapter = (entityIdentifier: CanvasEntityIden
const selectControlAdapter = useMemo( const selectControlAdapter = useMemo(
() => () =>
createMemoizedAppSelector(selectCanvasV2Slice, (canvasV2) => { createMemoizedAppSelector(selectCanvasV2Slice, (canvasV2) => {
const layer = selectControlLayerOrThrow(canvasV2, entityIdentifier.id); const layer = selectControlLayerEntityOrThrow(canvasV2, entityIdentifier.id);
return layer.controlAdapter; return layer.controlAdapter;
}), }),
[entityIdentifier] [entityIdentifier]
@ -36,7 +36,7 @@ export const useDefaultControlAdapter = (): ControlNetConfig | T2IAdapterConfig
const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true)); const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true));
const model = compatibleModels[0] ?? modelConfigs[0] ?? null; const model = compatibleModels[0] ?? modelConfigs[0] ?? null;
const controlAdapter = const controlAdapter =
model?.type === 't2i_adapter' ? deepClone(initialT2IAdapterV2) : deepClone(initialControlNetV2); model?.type === 't2i_adapter' ? deepClone(initialT2IAdapter) : deepClone(initialControlNet);
if (model) { if (model) {
controlAdapter.model = zModelIdentifierField.parse(model); controlAdapter.model = zModelIdentifierField.parse(model);
@ -56,7 +56,7 @@ export const useDefaultIPAdapter = (): IPAdapterConfig => {
const defaultControlAdapter = useMemo(() => { const defaultControlAdapter = useMemo(() => {
const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true)); const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true));
const model = compatibleModels[0] ?? modelConfigs[0] ?? null; const model = compatibleModels[0] ?? modelConfigs[0] ?? null;
const ipAdapter = deepClone(initialIPAdapterV2); const ipAdapter = deepClone(initialIPAdapter);
if (model) { if (model) {
ipAdapter.model = zModelIdentifierField.parse(model); ipAdapter.model = zModelIdentifierField.parse(model);

View File

@ -14,12 +14,12 @@ import type {
ControlNetConfig, ControlNetConfig,
T2IAdapterConfig, T2IAdapterConfig,
} from './types'; } from './types';
import { initialControlNetV2 } from './types'; import { initialControlNet } from './types';
export const selectControlLayer = (state: CanvasV2State, id: string) => const selectControlLayerEntity = (state: CanvasV2State, id: string) =>
state.controlLayers.entities.find((layer) => layer.id === id); state.controlLayers.entities.find((entity) => entity.id === id);
export const selectControlLayerOrThrow = (state: CanvasV2State, id: string) => { export const selectControlLayerEntityOrThrow = (state: CanvasV2State, id: string) => {
const layer = selectControlLayer(state, id); const layer = selectControlLayerEntity(state, id);
assert(layer, `Layer with id ${id} not found`); assert(layer, `Layer with id ${id} not found`);
return layer; return layer;
}; };
@ -40,7 +40,7 @@ export const controlLayersReducers = {
objects: [], objects: [],
opacity: 1, opacity: 1,
position: { x: 0, y: 0 }, position: { x: 0, y: 0 },
controlAdapter: deepClone(initialControlNetV2), controlAdapter: deepClone(initialControlNet),
}; };
merge(layer, overrides); merge(layer, overrides);
state.controlLayers.entities.push(layer); state.controlLayers.entities.push(layer);
@ -63,7 +63,7 @@ export const controlLayersReducers = {
controlLayerConvertedToRasterLayer: { controlLayerConvertedToRasterLayer: {
reducer: (state, action: PayloadAction<{ id: string; newId: string }>) => { reducer: (state, action: PayloadAction<{ id: string; newId: string }>) => {
const { id, newId } = action.payload; const { id, newId } = action.payload;
const layer = selectControlLayer(state, id); const layer = selectControlLayerEntity(state, id);
if (!layer) { if (!layer) {
return; return;
} }
@ -95,7 +95,7 @@ export const controlLayersReducers = {
}> }>
) => { ) => {
const { id, modelConfig } = action.payload; const { id, modelConfig } = action.payload;
const layer = selectControlLayer(state, id); const layer = selectControlLayerEntity(state, id);
if (!layer || !layer.controlAdapter) { if (!layer || !layer.controlAdapter) {
return; return;
} }
@ -123,7 +123,7 @@ export const controlLayersReducers = {
}, },
controlLayerControlModeChanged: (state, action: PayloadAction<{ id: string; controlMode: ControlModeV2 }>) => { controlLayerControlModeChanged: (state, action: PayloadAction<{ id: string; controlMode: ControlModeV2 }>) => {
const { id, controlMode } = action.payload; const { id, controlMode } = action.payload;
const layer = selectControlLayer(state, id); const layer = selectControlLayerEntity(state, id);
if (!layer || !layer.controlAdapter || layer.controlAdapter.type !== 'controlnet') { if (!layer || !layer.controlAdapter || layer.controlAdapter.type !== 'controlnet') {
return; return;
} }
@ -131,7 +131,7 @@ export const controlLayersReducers = {
}, },
controlLayerWeightChanged: (state, action: PayloadAction<{ id: string; weight: number }>) => { controlLayerWeightChanged: (state, action: PayloadAction<{ id: string; weight: number }>) => {
const { id, weight } = action.payload; const { id, weight } = action.payload;
const layer = selectControlLayer(state, id); const layer = selectControlLayerEntity(state, id);
if (!layer || !layer.controlAdapter) { if (!layer || !layer.controlAdapter) {
return; return;
} }
@ -142,7 +142,7 @@ export const controlLayersReducers = {
action: PayloadAction<{ id: string; beginEndStepPct: [number, number] }> action: PayloadAction<{ id: string; beginEndStepPct: [number, number] }>
) => { ) => {
const { id, beginEndStepPct } = action.payload; const { id, beginEndStepPct } = action.payload;
const layer = selectControlLayer(state, id); const layer = selectControlLayerEntity(state, id);
if (!layer || !layer.controlAdapter) { if (!layer || !layer.controlAdapter) {
return; return;
} }
@ -150,7 +150,7 @@ export const controlLayersReducers = {
}, },
controlLayerWithTransparencyEffectToggled: (state, action: PayloadAction<{ id: string }>) => { controlLayerWithTransparencyEffectToggled: (state, action: PayloadAction<{ id: string }>) => {
const { id } = action.payload; const { id } = action.payload;
const layer = selectControlLayer(state, id); const layer = selectControlLayerEntity(state, id);
if (!layer) { if (!layer) {
return; return;
} }

View File

@ -5,7 +5,7 @@ import { merge } from 'lodash-es';
import { assert } from 'tsafe'; import { assert } from 'tsafe';
import type { CanvasControlLayerState, CanvasRasterLayerState, CanvasV2State } from './types'; import type { CanvasControlLayerState, CanvasRasterLayerState, CanvasV2State } from './types';
import { initialControlNetV2 } from './types'; import { initialControlNet } from './types';
export const selectRasterLayer = (state: CanvasV2State, id: string) => export const selectRasterLayer = (state: CanvasV2State, id: string) =>
state.rasterLayers.entities.find((layer) => layer.id === id); state.rasterLayers.entities.find((layer) => layer.id === id);
@ -62,7 +62,7 @@ export const rasterLayersReducers = {
...deepClone(layer), ...deepClone(layer),
id: newId, id: newId,
type: 'control_layer', type: 'control_layer',
controlAdapter: deepClone(initialControlNetV2), controlAdapter: deepClone(initialControlNet),
withTransparencyEffect: true, withTransparencyEffect: true,
}; };

View File

@ -1,6 +1,3 @@
import type { CanvasControlAdapter } from 'features/controlLayers/konva/CanvasControlAdapter';
import { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter';
import { CanvasMaskAdapter } from 'features/controlLayers/konva/CanvasMaskAdapter';
import { getPrefixedId } from 'features/controlLayers/konva/util'; import { getPrefixedId } from 'features/controlLayers/konva/util';
import { zModelIdentifierField } from 'features/nodes/types/common'; import { zModelIdentifierField } from 'features/nodes/types/common';
import type { AspectRatioState } from 'features/parameters/components/DocumentSize/types'; import type { AspectRatioState } from 'features/parameters/components/DocumentSize/types';
@ -25,45 +22,35 @@ import type {
ParameterVAEModel, ParameterVAEModel,
ParameterWidth, ParameterWidth,
} from 'features/parameters/types/parameterSchemas'; } from 'features/parameters/types/parameterSchemas';
import { import { zParameterNegativePrompt, zParameterPositivePrompt } from 'features/parameters/types/parameterSchemas';
zParameterNegativePrompt, import type { AnyInvocation, BaseModelType, ImageDTO, S } from 'services/api/types';
zParameterPositivePrompt,
} from 'features/parameters/types/parameterSchemas';
import type {
AnyInvocation,
BaseModelType,
ControlNetModelConfig,
ImageDTO,
S,
T2IAdapterModelConfig,
} from 'services/api/types';
import { z } from 'zod'; import { z } from 'zod';
export const zId = z.string().min(1); const zId = z.string().min(1);
export const zName = z.string().min(1).nullable(); const zName = z.string().min(1).nullable();
export const zImageWithDims = z.object({ const zImageWithDims = z.object({
image_name: z.string(), image_name: z.string(),
width: z.number().int().positive(), width: z.number().int().positive(),
height: z.number().int().positive(), height: z.number().int().positive(),
}); });
export type ImageWithDims = z.infer<typeof zImageWithDims>; export type ImageWithDims = z.infer<typeof zImageWithDims>;
export const zBeginEndStepPct = z const zBeginEndStepPct = z
.tuple([z.number().gte(0).lte(1), z.number().gte(0).lte(1)]) .tuple([z.number().gte(0).lte(1), z.number().gte(0).lte(1)])
.refine(([begin, end]) => begin < end, { .refine(([begin, end]) => begin < end, {
message: 'Begin must be less than end', message: 'Begin must be less than end',
}); });
export const zControlModeV2 = z.enum(['balanced', 'more_prompt', 'more_control', 'unbalanced']); const zControlModeV2 = z.enum(['balanced', 'more_prompt', 'more_control', 'unbalanced']);
export type ControlModeV2 = z.infer<typeof zControlModeV2>; export type ControlModeV2 = z.infer<typeof zControlModeV2>;
export const isControlModeV2 = (v: unknown): v is ControlModeV2 => zControlModeV2.safeParse(v).success; export const isControlModeV2 = (v: unknown): v is ControlModeV2 => zControlModeV2.safeParse(v).success;
export const zCLIPVisionModelV2 = z.enum(['ViT-H', 'ViT-G']); const zCLIPVisionModelV2 = z.enum(['ViT-H', 'ViT-G']);
export type CLIPVisionModelV2 = z.infer<typeof zCLIPVisionModelV2>; export type CLIPVisionModelV2 = z.infer<typeof zCLIPVisionModelV2>;
export const isCLIPVisionModelV2 = (v: unknown): v is CLIPVisionModelV2 => zCLIPVisionModelV2.safeParse(v).success; export const isCLIPVisionModelV2 = (v: unknown): v is CLIPVisionModelV2 => zCLIPVisionModelV2.safeParse(v).success;
export const zIPMethodV2 = z.enum(['full', 'style', 'composition']); const zIPMethodV2 = z.enum(['full', 'style', 'composition']);
export type IPMethodV2 = z.infer<typeof zIPMethodV2>; export type IPMethodV2 = z.infer<typeof zIPMethodV2>;
export const isIPMethodV2 = (v: unknown): v is IPMethodV2 => zIPMethodV2.safeParse(v).success; export const isIPMethodV2 = (v: unknown): v is IPMethodV2 => zIPMethodV2.safeParse(v).success;
@ -175,7 +162,7 @@ const zZoeDepthProcessorConfig = z.object({
}); });
export type ZoeDepthProcessorConfig = z.infer<typeof zZoeDepthProcessorConfig>; export type ZoeDepthProcessorConfig = z.infer<typeof zZoeDepthProcessorConfig>;
export const zFilterConfig = z.discriminatedUnion('type', [ const zFilterConfig = z.discriminatedUnion('type', [
zCannyProcessorConfig, zCannyProcessorConfig,
zColorMapProcessorConfig, zColorMapProcessorConfig,
zContentShuffleProcessorConfig, zContentShuffleProcessorConfig,
@ -471,31 +458,10 @@ export const IMAGE_FILTERS: { [key in FilterConfig['type']]: ImageFilterData<key
const zTool = z.enum(['brush', 'eraser', 'move', 'rect', 'view', 'bbox', 'eyeDropper']); const zTool = z.enum(['brush', 'eraser', 'move', 'rect', 'view', 'bbox', 'eyeDropper']);
export type Tool = z.infer<typeof zTool>; export type Tool = z.infer<typeof zTool>;
export function isDrawingTool(tool: Tool): tool is 'brush' | 'eraser' | 'rect' {
return tool === 'brush' || tool === 'eraser' || tool === 'rect';
}
const zDrawingTool = zTool.extract(['brush', 'eraser']);
const zPoints = z.array(z.number()).refine((points) => points.length % 2 === 0, { const zPoints = z.array(z.number()).refine((points) => points.length % 2 === 0, {
message: 'Must have an even number of points', message: 'Must have an even number of points',
}); });
const zOLD_VectorMaskLine = z.object({
id: zId,
type: z.literal('vector_mask_line'),
tool: zDrawingTool,
strokeWidth: z.number().min(1),
points: zPoints,
});
const zOLD_VectorMaskRect = z.object({
id: zId,
type: z.literal('vector_mask_rect'),
x: z.number(),
y: z.number(),
width: z.number().min(1),
height: z.number().min(1),
});
const zRgbColor = z.object({ const zRgbColor = z.object({
r: z.number().int().min(0).max(255), r: z.number().int().min(0).max(255),
@ -507,9 +473,7 @@ const zRgbaColor = zRgbColor.extend({
a: z.number().min(0).max(1), a: z.number().min(0).max(1),
}); });
export type RgbaColor = z.infer<typeof zRgbaColor>; export type RgbaColor = z.infer<typeof zRgbaColor>;
export const RGBA_RED: RgbaColor = { r: 255, g: 0, b: 0, a: 1 };
export const RGBA_BLACK: RgbaColor = { r: 0, g: 0, b: 0, a: 1 }; export const RGBA_BLACK: RgbaColor = { r: 0, g: 0, b: 0, a: 1 };
export const RGBA_WHITE: RgbaColor = { r: 255, g: 255, b: 255, a: 1 };
const zOpacity = z.number().gte(0).lte(1); const zOpacity = z.number().gte(0).lte(1);
@ -577,9 +541,6 @@ const zCanvasObjectState = z.discriminatedUnion('type', [
zCanvasRectState, zCanvasRectState,
]); ]);
export type CanvasObjectState = z.infer<typeof zCanvasObjectState>; export type CanvasObjectState = z.infer<typeof zCanvasObjectState>;
export function isCanvasBrushLineState(obj: CanvasObjectState): obj is CanvasBrushLineState {
return obj.type === 'brush_line';
}
const zIPAdapterConfig = z.object({ const zIPAdapterConfig = z.object({
image: zImageWithDims.nullable(), image: zImageWithDims.nullable(),
@ -591,7 +552,7 @@ const zIPAdapterConfig = z.object({
}); });
export type IPAdapterConfig = z.infer<typeof zIPAdapterConfig>; export type IPAdapterConfig = z.infer<typeof zIPAdapterConfig>;
export const zCanvasIPAdapterState = z.object({ const zCanvasIPAdapterState = z.object({
id: zId, id: zId,
name: zName, name: zName,
type: z.literal('ip_adapter'), type: z.literal('ip_adapter'),
@ -600,47 +561,6 @@ export const zCanvasIPAdapterState = z.object({
}); });
export type CanvasIPAdapterState = z.infer<typeof zCanvasIPAdapterState>; export type CanvasIPAdapterState = z.infer<typeof zCanvasIPAdapterState>;
const zMaskObject = z
.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: CanvasBrushLineState = {
...rest,
type: 'brush_line',
color: { r: 255, g: 255, b: 255, a: 1 },
clip: null,
};
return asBrushline;
} else if (tool === 'eraser') {
const asEraserLine: CanvasEraserLineState = {
...rest,
type: 'eraser_line',
clip: null,
};
return asEraserLine;
}
} else if (val.type === 'vector_mask_rect') {
const asRectShape: CanvasRectState = {
...val,
type: 'rect',
color: { r: 255, g: 255, b: 255, a: 1 },
};
return asRectShape;
} else {
return val;
}
})
.pipe(z.discriminatedUnion('type', [zCanvasBrushLineState, zCanvasEraserLineState, zCanvasRectState]));
const zFillStyle = z.enum(['solid', 'grid', 'crosshatch', 'diagonal', 'horizontal', 'vertical']); const zFillStyle = z.enum(['solid', 'grid', 'crosshatch', 'diagonal', 'horizontal', 'vertical']);
export type FillStyle = z.infer<typeof zFillStyle>; export type FillStyle = z.infer<typeof zFillStyle>;
export const isFillStyle = (v: unknown): v is FillStyle => zFillStyle.safeParse(v).success; export const isFillStyle = (v: unknown): v is FillStyle => zFillStyle.safeParse(v).success;
@ -658,7 +578,7 @@ const zRegionalGuidanceIPAdapterConfig = z.object({
}); });
export type RegionalGuidanceIPAdapterConfig = z.infer<typeof zRegionalGuidanceIPAdapterConfig>; export type RegionalGuidanceIPAdapterConfig = z.infer<typeof zRegionalGuidanceIPAdapterConfig>;
export const zCanvasRegionalGuidanceState = z.object({ const zCanvasRegionalGuidanceState = z.object({
id: zId, id: zId,
name: zName, name: zName,
type: z.literal('regional_guidance'), type: z.literal('regional_guidance'),
@ -686,37 +606,6 @@ const zCanvasInpaintMaskState = z.object({
}); });
export type CanvasInpaintMaskState = z.infer<typeof zCanvasInpaintMaskState>; export type CanvasInpaintMaskState = z.infer<typeof zCanvasInpaintMaskState>;
const zCanvasControlAdapterStateBase = z.object({
id: zId,
type: z.literal('control_adapter'),
isEnabled: z.boolean(),
position: zCoordinate,
opacity: zOpacity,
filters: z.array(zLayerEffect),
weight: z.number().gte(-1).lte(2),
imageObject: zCanvasImageState.nullable(),
processedImageObject: zCanvasImageState.nullable(),
processorConfig: zFilterConfig.nullable(),
processorPendingBatchId: z.string().nullable().default(null),
beginEndStepPct: zBeginEndStepPct,
model: zModelIdentifierField.nullable(),
});
const zCanvasControlNetState = zCanvasControlAdapterStateBase.extend({
adapterType: z.literal('controlnet'),
controlMode: zControlModeV2,
});
export type CanvasControlNetState = z.infer<typeof zCanvasControlNetState>;
const zCanvasT2IAdapteState = zCanvasControlAdapterStateBase.extend({
adapterType: z.literal('t2i_adapter'),
});
export type CanvasT2IAdapterState = z.infer<typeof zCanvasT2IAdapteState>;
export const zCanvasControlAdapterState = z.discriminatedUnion('adapterType', [
zCanvasControlNetState,
zCanvasT2IAdapteState,
]);
export type CanvasControlAdapterState = z.infer<typeof zCanvasControlAdapterState>;
const zControlNetConfig = z.object({ const zControlNetConfig = z.object({
type: z.literal('controlnet'), type: z.literal('controlnet'),
model: zModelIdentifierField.nullable(), model: zModelIdentifierField.nullable(),
@ -745,14 +634,14 @@ export const zCanvasRasterLayerState = z.object({
}); });
export type CanvasRasterLayerState = z.infer<typeof zCanvasRasterLayerState>; export type CanvasRasterLayerState = z.infer<typeof zCanvasRasterLayerState>;
export const zCanvasControlLayerState = zCanvasRasterLayerState.extend({ const zCanvasControlLayerState = zCanvasRasterLayerState.extend({
type: z.literal('control_layer'), type: z.literal('control_layer'),
withTransparencyEffect: z.boolean(), withTransparencyEffect: z.boolean(),
controlAdapter: z.discriminatedUnion('type', [zControlNetConfig, zT2IAdapterConfig]), controlAdapter: z.discriminatedUnion('type', [zControlNetConfig, zT2IAdapterConfig]),
}); });
export type CanvasControlLayerState = z.infer<typeof zCanvasControlLayerState>; export type CanvasControlLayerState = z.infer<typeof zCanvasControlLayerState>;
export const initialControlNetV2: ControlNetConfig = { export const initialControlNet: ControlNetConfig = {
type: 'controlnet', type: 'controlnet',
model: null, model: null,
weight: 1, weight: 1,
@ -760,14 +649,14 @@ export const initialControlNetV2: ControlNetConfig = {
controlMode: 'balanced', controlMode: 'balanced',
}; };
export const initialT2IAdapterV2: T2IAdapterConfig = { export const initialT2IAdapter: T2IAdapterConfig = {
type: 't2i_adapter', type: 't2i_adapter',
model: null, model: null,
weight: 1, weight: 1,
beginEndStepPct: [0, 1], beginEndStepPct: [0, 1],
}; };
export const initialIPAdapterV2: IPAdapterConfig = { export const initialIPAdapter: IPAdapterConfig = {
image: null, image: null,
model: null, model: null,
beginEndStepPct: [0, 1], beginEndStepPct: [0, 1],
@ -776,17 +665,6 @@ export const initialIPAdapterV2: IPAdapterConfig = {
weight: 1, weight: 1,
}; };
export const buildControlAdapterProcessorV2 = (
modelConfig: ControlNetModelConfig | T2IAdapterModelConfig
): FilterConfig | null => {
const defaultPreprocessor = modelConfig.default_settings?.preprocessor;
if (!isFilterType(defaultPreprocessor)) {
return null;
}
const processorConfig = IMAGE_FILTERS[defaultPreprocessor].buildDefaults(modelConfig.base);
return processorConfig;
};
export const imageDTOToImageWithDims = ({ image_name, width, height }: ImageDTO): ImageWithDims => ({ export const imageDTOToImageWithDims = ({ image_name, width, height }: ImageDTO): ImageWithDims => ({
image_name, image_name,
width, width,
@ -960,11 +838,6 @@ export type EntityRasterizedPayload = EntityIdentifierPayload<{
}>; }>;
export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; position?: Coordinate }; export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; position?: Coordinate };
//#region Type guards
export const isLine = (obj: CanvasObjectState): obj is CanvasBrushLineState | CanvasEraserLineState => {
return obj.type === 'brush_line' || obj.type === 'eraser_line';
};
/** /**
* A helper type to remove `[index: string]: any;` from a type. * A helper type to remove `[index: string]: any;` from a type.
* This is useful for some Konva types that include `[index: string]: any;` in addition to statically named * This is useful for some Konva types that include `[index: string]: any;` in addition to statically named
@ -993,12 +866,6 @@ export function isDrawableEntity(
return isDrawableEntityType(entity.type); return isDrawableEntityType(entity.type);
} }
export function isDrawableEntityAdapter(
adapter: CanvasLayerAdapter | CanvasControlAdapter | CanvasMaskAdapter
): adapter is CanvasLayerAdapter | CanvasMaskAdapter {
return adapter instanceof CanvasLayerAdapter || adapter instanceof CanvasMaskAdapter;
}
export const getEntityIdentifier = (entity: CanvasEntityState): CanvasEntityIdentifier => { export const getEntityIdentifier = (entity: CanvasEntityState): CanvasEntityIdentifier => {
return { id: entity.id, type: entity.type }; return { id: entity.id, type: entity.type };
}; };

View File

@ -131,7 +131,7 @@ type SimplifyOptions = {
}; };
// both algorithms combined for awesome performance // both algorithms combined for awesome performance
export function simplifyCoords(points: Coordinate[], options?: SimplifyOptions): Coordinate[] { function simplifyCoords(points: Coordinate[], options?: SimplifyOptions): Coordinate[] {
const { tolerance, highestQuality } = { ...options, tolerance: 1, highestQuality: false }; const { tolerance, highestQuality } = { ...options, tolerance: 1, highestQuality: false };
if (points.length <= 2) { if (points.length <= 2) {
@ -146,11 +146,11 @@ export function simplifyCoords(points: Coordinate[], options?: SimplifyOptions):
return secondPassPoints; return secondPassPoints;
} }
export function coordsToFlatNumbersArray(coords: Coordinate[]): number[] { function coordsToFlatNumbersArray(coords: Coordinate[]): number[] {
return coords.flatMap((coord) => [coord.x, coord.y]); return coords.flatMap((coord) => [coord.x, coord.y]);
} }
export function flatNumbersArrayToCoords(array: number[]): Coordinate[] { function flatNumbersArrayToCoords(array: number[]): Coordinate[] {
assert(array.length % 2 === 0, 'Array length must be even'); assert(array.length % 2 === 0, 'Array length must be even');
const coords: Coordinate[] = []; const coords: Coordinate[] = [];
for (let i = 0; i < array.length; i += 2) { for (let i = 0; i < array.length; i += 2) {

View File

@ -4,9 +4,9 @@ import type { CanvasControlAdapterState, CanvasIPAdapterState, CanvasRasterLayer
import { import {
IMAGE_FILTERS, IMAGE_FILTERS,
imageDTOToImageWithDims, imageDTOToImageWithDims,
initialControlNetV2, initialControlNet,
initialIPAdapterV2, initialIPAdapter,
initialT2IAdapterV2, initialT2IAdapter,
isFilterType, isFilterType,
zCanvasRasterLayerState, zCanvasRasterLayerState,
} from 'features/controlLayers/store/types'; } from 'features/controlLayers/store/types';
@ -563,8 +563,8 @@ const parseControlNetToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapt
? IMAGE_FILTERS[defaultPreprocessor].buildDefaults() ? IMAGE_FILTERS[defaultPreprocessor].buildDefaults()
: null; : null;
const beginEndStepPct: [number, number] = [ const beginEndStepPct: [number, number] = [
begin_step_percent ?? initialControlNetV2.beginEndStepPct[0], begin_step_percent ?? initialControlNet.beginEndStepPct[0],
end_step_percent ?? initialControlNetV2.beginEndStepPct[1], end_step_percent ?? initialControlNet.beginEndStepPct[1],
]; ];
const imageDTO = image ? await getImageDTO(image.image_name) : null; const imageDTO = image ? await getImageDTO(image.image_name) : null;
const processedImageDTO = processedImage ? await getImageDTO(processedImage.image_name) : null; const processedImageDTO = processedImage ? await getImageDTO(processedImage.image_name) : null;
@ -581,9 +581,9 @@ const parseControlNetToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapt
y: 0, y: 0,
adapterType: 'controlnet', adapterType: 'controlnet',
model: zModelIdentifierField.parse(controlNetModel), model: zModelIdentifierField.parse(controlNetModel),
weight: typeof control_weight === 'number' ? control_weight : initialControlNetV2.weight, weight: typeof control_weight === 'number' ? control_weight : initialControlNet.weight,
beginEndStepPct, beginEndStepPct,
controlMode: control_mode ?? initialControlNetV2.controlMode, controlMode: control_mode ?? initialControlNet.controlMode,
image: imageDTO ? imageDTOToImageWithDims(imageDTO) : null, image: imageDTO ? imageDTOToImageWithDims(imageDTO) : null,
processedImage: processedImageDTO ? imageDTOToImageWithDims(processedImageDTO) : null, processedImage: processedImageDTO ? imageDTOToImageWithDims(processedImageDTO) : null,
processorConfig, processorConfig,
@ -624,8 +624,8 @@ const parseT2IAdapterToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapt
? IMAGE_FILTERS[defaultPreprocessor].buildDefaults() ? IMAGE_FILTERS[defaultPreprocessor].buildDefaults()
: null; : null;
const beginEndStepPct: [number, number] = [ const beginEndStepPct: [number, number] = [
begin_step_percent ?? initialT2IAdapterV2.beginEndStepPct[0], begin_step_percent ?? initialT2IAdapter.beginEndStepPct[0],
end_step_percent ?? initialT2IAdapterV2.beginEndStepPct[1], end_step_percent ?? initialT2IAdapter.beginEndStepPct[1],
]; ];
const imageDTO = image ? await getImageDTO(image.image_name) : null; const imageDTO = image ? await getImageDTO(image.image_name) : null;
const processedImageDTO = processedImage ? await getImageDTO(processedImage.image_name) : null; const processedImageDTO = processedImage ? await getImageDTO(processedImage.image_name) : null;
@ -642,7 +642,7 @@ const parseT2IAdapterToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapt
y: 0, y: 0,
adapterType: 't2i_adapter', adapterType: 't2i_adapter',
model: zModelIdentifierField.parse(t2iAdapterModel), model: zModelIdentifierField.parse(t2iAdapterModel),
weight: typeof weight === 'number' ? weight : initialT2IAdapterV2.weight, weight: typeof weight === 'number' ? weight : initialT2IAdapter.weight,
beginEndStepPct, beginEndStepPct,
image: imageDTO ? imageDTOToImageWithDims(imageDTO) : null, image: imageDTO ? imageDTOToImageWithDims(imageDTO) : null,
processedImage: processedImageDTO ? imageDTOToImageWithDims(processedImageDTO) : null, processedImage: processedImageDTO ? imageDTOToImageWithDims(processedImageDTO) : null,
@ -680,8 +680,8 @@ const parseIPAdapterToIPAdapterLayer: MetadataParseFunc<CanvasIPAdapterState> =
.parse(await getProperty(metadataItem, 'end_step_percent')); .parse(await getProperty(metadataItem, 'end_step_percent'));
const beginEndStepPct: [number, number] = [ const beginEndStepPct: [number, number] = [
begin_step_percent ?? initialIPAdapterV2.beginEndStepPct[0], begin_step_percent ?? initialIPAdapter.beginEndStepPct[0],
end_step_percent ?? initialIPAdapterV2.beginEndStepPct[1], end_step_percent ?? initialIPAdapter.beginEndStepPct[1],
]; ];
const imageDTO = image ? await getImageDTO(image.image_name) : null; const imageDTO = image ? await getImageDTO(image.image_name) : null;
@ -690,11 +690,11 @@ const parseIPAdapterToIPAdapterLayer: MetadataParseFunc<CanvasIPAdapterState> =
type: 'ip_adapter', type: 'ip_adapter',
isEnabled: true, isEnabled: true,
model: zModelIdentifierField.parse(ipAdapterModel), model: zModelIdentifierField.parse(ipAdapterModel),
weight: typeof weight === 'number' ? weight : initialIPAdapterV2.weight, weight: typeof weight === 'number' ? weight : initialIPAdapter.weight,
beginEndStepPct, beginEndStepPct,
imageObject: imageDTO ? imageDTOToImageWithDims(imageDTO) : null, imageObject: imageDTO ? imageDTOToImageWithDims(imageDTO) : null,
clipVisionModel: initialIPAdapterV2.clipVisionModel, // TODO: This needs to be added to the zIPAdapterField... clipVisionModel: initialIPAdapter.clipVisionModel, // TODO: This needs to be added to the zIPAdapterField...
method: method ?? initialIPAdapterV2.method, method: method ?? initialIPAdapter.method,
}; };
return layer; return layer;

View File

@ -4,7 +4,7 @@ import type { Graph, GraphAndWorkflowResponse } from 'services/api/types';
const textToImageGraphBuilt = createAction<Graph>('nodes/textToImageGraphBuilt'); const textToImageGraphBuilt = createAction<Graph>('nodes/textToImageGraphBuilt');
const imageToImageGraphBuilt = createAction<Graph>('nodes/imageToImageGraphBuilt'); const imageToImageGraphBuilt = createAction<Graph>('nodes/imageToImageGraphBuilt');
export const canvasGraphBuilt = createAction<Graph>('nodes/canvasGraphBuilt'); const canvasGraphBuilt = createAction<Graph>('nodes/canvasGraphBuilt');
const nodesGraphBuilt = createAction<Graph>('nodes/nodesGraphBuilt'); const nodesGraphBuilt = createAction<Graph>('nodes/nodesGraphBuilt');
export const isAnyGraphBuilt = isAnyOf( export const isAnyGraphBuilt = isAnyOf(

View File

@ -18,6 +18,13 @@ type AddedRegionResult = {
addedIPAdapters: number; addedIPAdapters: number;
}; };
const isValidRegion = (rg: CanvasRegionalGuidanceState, base: BaseModelType) => {
const isEnabled = rg.isEnabled;
const hasTextPrompt = Boolean(rg.positivePrompt || rg.negativePrompt);
const hasIPAdapter = rg.ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base)).length > 0;
return isEnabled && (hasTextPrompt || hasIPAdapter);
};
/** /**
* Adds regional guidance to the graph * Adds regional guidance to the graph
* @param regions Array of regions to add * @param regions Array of regions to add
@ -227,10 +234,3 @@ export const addRegions = async (
return results; return results;
}; };
export const isValidRegion = (rg: CanvasRegionalGuidanceState, base: BaseModelType) => {
const isEnabled = rg.isEnabled;
const hasTextPrompt = Boolean(rg.positivePrompt || rg.negativePrompt);
const hasIPAdapter = rg.ipAdapters.filter((ipa) => isValidIPAdapter(ipa, base)).length > 0;
return isEnabled && (hasTextPrompt || hasIPAdapter);
};

View File

@ -3,7 +3,6 @@ import type { CanvasV2State } from 'features/controlLayers/store/types';
import type { BoardField } from 'features/nodes/types/common'; import type { BoardField } from 'features/nodes/types/common';
import type { Graph } from 'features/nodes/util/graph/generation/Graph'; import type { Graph } from 'features/nodes/util/graph/generation/Graph';
import { buildPresetModifiedPrompt } from 'features/stylePresets/hooks/usePresetModifiedPrompts'; import { buildPresetModifiedPrompt } from 'features/stylePresets/hooks/usePresetModifiedPrompts';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { pick } from 'lodash-es'; import { pick } from 'lodash-es';
import { stylePresetsApi } from 'services/api/endpoints/stylePresets'; import { stylePresetsApi } from 'services/api/endpoints/stylePresets';
import type { Invocation } from 'services/api/types'; import type { Invocation } from 'services/api/types';
@ -63,17 +62,6 @@ export const getPresetModifiedPrompts = (
}; };
}; };
/**
* Gets the is_intermediate field, based on the active tab and shouldAutoSave setting.
*/
export const getIsIntermediate = (state: RootState) => {
const activeTabName = activeTabNameSelector(state);
if (activeTabName === 'canvas') {
return !state.canvas.shouldAutoSave;
}
return false;
};
export const getSizes = (bboxState: CanvasV2State['bbox']) => { export const getSizes = (bboxState: CanvasV2State['bbox']) => {
const originalSize = pick(bboxState.rect, 'width', 'height'); const originalSize = pick(bboxState.rect, 'width', 'height');
const scaledSize = ['auto', 'manual'].includes(bboxState.scaleMethod) ? bboxState.scaledSize : originalSize; const scaledSize = ['auto', 'manual'].includes(bboxState.scaleMethod) ? bboxState.scaledSize : originalSize;

View File

@ -1,29 +1,7 @@
import type { ComboboxOption } from '@invoke-ai/ui-library'; import type { ComboboxOption } from '@invoke-ai/ui-library';
import type { AspectRatioID, AspectRatioState } from './types'; import type { AspectRatioID, AspectRatioState } from './types';
// When the aspect ratio is between these two values, we show the icon (experimentally determined)
export const ICON_LOW_CUTOFF = 0.23;
export const ICON_HIGH_CUTOFF = 1 / ICON_LOW_CUTOFF;
const ICON_SIZE_PX = 64;
const ICON_PADDING_PX = 16;
export const BOX_SIZE_CSS_CALC = `min(${ICON_SIZE_PX}px, calc(100% - ${ICON_PADDING_PX}px))`;
export const MOTION_ICON_INITIAL = {
opacity: 0,
};
export const MOTION_ICON_ANIMATE = {
opacity: 1,
transition: { duration: 0.1 },
};
export const MOTION_ICON_EXIT = {
opacity: 0,
transition: { duration: 0.1 },
};
export const ICON_CONTAINER_STYLES = {
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
};
export const ASPECT_RATIO_OPTIONS: ComboboxOption[] = [ export const ASPECT_RATIO_OPTIONS: ComboboxOption[] = [
{ label: 'Free' as const, value: 'Free' }, { label: 'Free' as const, value: 'Free' },
{ label: '16:9' as const, value: '16:9' }, { label: '16:9' as const, value: '16:9' },

View File

@ -132,7 +132,7 @@ export type ParameterSpandrelImageToImageModel = z.infer<typeof zParameterSpandr
// #endregion // #endregion
// #region Strength (l2l strength) // #region Strength (l2l strength)
export const zParameterStrength = z.number().min(0).max(1); const zParameterStrength = z.number().min(0).max(1);
export type ParameterStrength = z.infer<typeof zParameterStrength>; export type ParameterStrength = z.infer<typeof zParameterStrength>;
export const isParameterStrength = (val: unknown): val is ParameterStrength => export const isParameterStrength = (val: unknown): val is ParameterStrength =>
zParameterStrength.safeParse(val).success; zParameterStrength.safeParse(val).success;
@ -201,8 +201,3 @@ const zLoRAWeight = z.number();
type ParameterLoRAWeight = z.infer<typeof zLoRAWeight>; type ParameterLoRAWeight = z.infer<typeof zLoRAWeight>;
export const isParameterLoRAWeight = (val: unknown): val is ParameterLoRAWeight => zLoRAWeight.safeParse(val).success; export const isParameterLoRAWeight = (val: unknown): val is ParameterLoRAWeight => zLoRAWeight.safeParse(val).success;
// #endregion // #endregion
// #region Regional Prompts AutoNegative
export const zAutoNegative = z.enum(['off', 'invert']);
export type ParameterAutoNegative = z.infer<typeof zAutoNegative>;
// #endregion