tidy(ui): clean up unused code 1

- Only export when necessary
- Remove totally usused functions, variables, state, etc
- Remove unused packages
This commit is contained in:
psychedelicious 2024-02-27 14:26:09 +11:00 committed by Brandon Rising
parent 5e83fc8ac7
commit 45546fdcea
55 changed files with 83 additions and 751 deletions

View File

@ -58,7 +58,6 @@
"@dnd-kit/utilities": "^3.2.2", "@dnd-kit/utilities": "^3.2.2",
"@fontsource-variable/inter": "^5.0.16", "@fontsource-variable/inter": "^5.0.16",
"@invoke-ai/ui-library": "^0.0.21", "@invoke-ai/ui-library": "^0.0.21",
"@mantine/form": "6.0.21",
"@nanostores/react": "^0.7.2", "@nanostores/react": "^0.7.2",
"@reduxjs/toolkit": "2.2.1", "@reduxjs/toolkit": "2.2.1",
"@roarr/browser-log-writer": "^1.3.0", "@roarr/browser-log-writer": "^1.3.0",
@ -90,7 +89,6 @@
"react-redux": "9.1.0", "react-redux": "9.1.0",
"react-resizable-panels": "^2.0.9", "react-resizable-panels": "^2.0.9",
"react-select": "5.8.0", "react-select": "5.8.0",
"react-textarea-autosize": "^8.5.3",
"react-use": "^17.5.0", "react-use": "^17.5.0",
"react-virtuoso": "^4.7.0", "react-virtuoso": "^4.7.0",
"reactflow": "^11.10.4", "reactflow": "^11.10.4",

View File

@ -29,9 +29,6 @@ dependencies:
'@invoke-ai/ui-library': '@invoke-ai/ui-library':
specifier: ^0.0.21 specifier: ^0.0.21
version: 0.0.21(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.16)(@internationalized/date@3.5.2)(@types/react@18.2.57)(i18next@23.9.0)(react-dom@18.2.0)(react@18.2.0) version: 0.0.21(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.16)(@internationalized/date@3.5.2)(@types/react@18.2.57)(i18next@23.9.0)(react-dom@18.2.0)(react@18.2.0)
'@mantine/form':
specifier: 6.0.21
version: 6.0.21(react@18.2.0)
'@nanostores/react': '@nanostores/react':
specifier: ^0.7.2 specifier: ^0.7.2
version: 0.7.2(nanostores@0.10.0)(react@18.2.0) version: 0.7.2(nanostores@0.10.0)(react@18.2.0)
@ -125,9 +122,6 @@ dependencies:
react-select: react-select:
specifier: 5.8.0 specifier: 5.8.0
version: 5.8.0(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0) version: 5.8.0(@types/react@18.2.57)(react-dom@18.2.0)(react@18.2.0)
react-textarea-autosize:
specifier: ^8.5.3
version: 8.5.3(@types/react@18.2.57)(react@18.2.0)
react-use: react-use:
specifier: ^17.5.0 specifier: ^17.5.0
version: 17.5.0(react-dom@18.2.0)(react@18.2.0) version: 17.5.0(react-dom@18.2.0)(react@18.2.0)
@ -3961,16 +3955,6 @@ packages:
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
dev: true dev: true
/@mantine/form@6.0.21(react@18.2.0):
resolution: {integrity: sha512-d4tlxyZic7MSDnaPx/WliCX1sRFDkUd2nxx4MxxO2T4OSek0YDqTlSBCxeoveu60P+vrQQN5rbbsVsaOJBe4SQ==}
peerDependencies:
react: '>=16.8.0'
dependencies:
fast-deep-equal: 3.1.3
klona: 2.0.6
react: 18.2.0
dev: false
/@mdx-js/react@2.3.0(react@18.2.0): /@mdx-js/react@2.3.0(react@18.2.0):
resolution: {integrity: sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==} resolution: {integrity: sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==}
peerDependencies: peerDependencies:
@ -8360,6 +8344,7 @@ packages:
/clone@1.0.4: /clone@1.0.4:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'} engines: {node: '>=0.8'}
requiresBuild: true
dev: true dev: true
/color-convert@1.9.3: /color-convert@1.9.3:
@ -8782,6 +8767,7 @@ packages:
/defaults@1.0.4: /defaults@1.0.4:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
requiresBuild: true
dependencies: dependencies:
clone: 1.0.4 clone: 1.0.4
dev: true dev: true
@ -13151,20 +13137,6 @@ packages:
react: 18.2.0 react: 18.2.0
tslib: 2.6.2 tslib: 2.6.2
/react-textarea-autosize@8.5.3(@types/react@18.2.57)(react@18.2.0):
resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==}
engines: {node: '>=10'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@babel/runtime': 7.23.9
react: 18.2.0
use-composed-ref: 1.3.0(react@18.2.0)
use-latest: 1.2.1(@types/react@18.2.57)(react@18.2.0)
transitivePeerDependencies:
- '@types/react'
dev: false
/react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies: peerDependencies:
@ -14777,14 +14749,6 @@ packages:
react: 18.2.0 react: 18.2.0
tslib: 2.6.2 tslib: 2.6.2
/use-composed-ref@1.3.0(react@18.2.0):
resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
dev: false
/use-debounce@10.0.0(react@18.2.0): /use-debounce@10.0.0(react@18.2.0):
resolution: {integrity: sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A==} resolution: {integrity: sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A==}
engines: {node: '>= 16.0.0'} engines: {node: '>= 16.0.0'}
@ -14817,20 +14781,6 @@ packages:
react: 18.2.0 react: 18.2.0
dev: false dev: false
/use-latest@1.2.1(@types/react@18.2.57)(react@18.2.0):
resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@types/react': 18.2.57
react: 18.2.0
use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.57)(react@18.2.0)
dev: false
/use-resize-observer@9.1.0(react-dom@18.2.0)(react@18.2.0): /use-resize-observer@9.1.0(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==} resolution: {integrity: sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==}
peerDependencies: peerDependencies:

View File

@ -1,34 +0,0 @@
export const COLORS = {
reset: '\x1b[0m',
bright: '\x1b[1m',
dim: '\x1b[2m',
underscore: '\x1b[4m',
blink: '\x1b[5m',
reverse: '\x1b[7m',
hidden: '\x1b[8m',
fg: {
black: '\x1b[30m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
white: '\x1b[37m',
gray: '\x1b[90m',
crimson: '\x1b[38m',
},
bg: {
black: '\x1b[40m',
red: '\x1b[41m',
green: '\x1b[42m',
yellow: '\x1b[43m',
blue: '\x1b[44m',
magenta: '\x1b[45m',
cyan: '\x1b[46m',
white: '\x1b[47m',
gray: '\x1b[100m',
crimson: '\x1b[48m',
},
};

View File

@ -12,7 +12,6 @@ ROARR.serializeMessage = serializeMessage;
ROARR.write = createLogWriter(); ROARR.write = createLogWriter();
export const BASE_CONTEXT = {}; export const BASE_CONTEXT = {};
export const log = Roarr.child(BASE_CONTEXT);
export const $logger = atom<Logger>(Roarr.child(BASE_CONTEXT)); export const $logger = atom<Logger>(Roarr.child(BASE_CONTEXT));

View File

@ -1,10 +1,7 @@
import { createAction } from '@reduxjs/toolkit'; import { createAction } from '@reduxjs/toolkit';
import type { InvokeTabName } from 'features/ui/store/tabMap'; import type { InvokeTabName } from 'features/ui/store/tabMap';
import type { BatchConfig } from 'services/api/types';
export const enqueueRequested = createAction<{ export const enqueueRequested = createAction<{
tabName: InvokeTabName; tabName: InvokeTabName;
prepend: boolean; prepend: boolean;
}>('app/enqueueRequested'); }>('app/enqueueRequested');
export const batchEnqueued = createAction<BatchConfig>('app/batchEnqueued');

View File

@ -1 +1,2 @@
export const STORAGE_PREFIX = '@@invokeai-'; export const STORAGE_PREFIX = '@@invokeai-';
export const EMPTY_ARRAY = [];

View File

@ -13,19 +13,9 @@ export const createMemoizedSelector = createSelectorCreator({
argsMemoize: lruMemoize, argsMemoize: lruMemoize,
}); });
/**
* A memoized selector creator that uses LRU cache default shallow equality check.
*/
export const createLruSelector = createSelectorCreator({
memoize: lruMemoize,
argsMemoize: lruMemoize,
});
export const createLruDraftSafeSelector = createDraftSafeSelectorCreator({
memoize: lruMemoize,
argsMemoize: lruMemoize,
});
export const getSelectorsOptions: GetSelectorsOptions = { export const getSelectorsOptions: GetSelectorsOptions = {
createSelector: createLruDraftSafeSelector, createSelector: createDraftSafeSelectorCreator({
memoize: lruMemoize,
argsMemoize: lruMemoize,
}),
}; };

View File

@ -1,5 +1,5 @@
import type { ListenerEffect, TypedAddListener, TypedStartListening, UnknownAction } from '@reduxjs/toolkit'; import type { ListenerEffect, TypedStartListening, UnknownAction } from '@reduxjs/toolkit';
import { addListener, createListenerMiddleware } from '@reduxjs/toolkit'; import { createListenerMiddleware } from '@reduxjs/toolkit';
import { addBulkDownloadListeners } from 'app/store/middleware/listenerMiddleware/listeners/bulkDownload'; import { addBulkDownloadListeners } from 'app/store/middleware/listenerMiddleware/listeners/bulkDownload';
import { addGalleryImageClickedListener } from 'app/store/middleware/listenerMiddleware/listeners/galleryImageClicked'; import { addGalleryImageClickedListener } from 'app/store/middleware/listenerMiddleware/listeners/galleryImageClicked';
import type { AppDispatch, RootState } from 'app/store/store'; import type { AppDispatch, RootState } from 'app/store/store';
@ -74,8 +74,6 @@ export type AppStartListening = TypedStartListening<RootState, AppDispatch>;
export const startAppListening = listenerMiddleware.startListening as AppStartListening; export const startAppListening = listenerMiddleware.startListening as AppStartListening;
export const addAppListener = addListener as TypedAddListener<RootState, AppDispatch>;
export type AppListenerEffect = ListenerEffect<UnknownAction, RootState, AppDispatch>; export type AppListenerEffect = ListenerEffect<UnknownAction, RootState, AppDispatch>;
/** /**

View File

@ -1,4 +1,3 @@
import { createAction } from '@reduxjs/toolkit';
import { imageSelected } from 'features/gallery/store/gallerySlice'; import { imageSelected } from 'features/gallery/store/gallerySlice';
import { IMAGE_CATEGORIES } from 'features/gallery/store/types'; import { IMAGE_CATEGORIES } from 'features/gallery/store/types';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
@ -7,8 +6,6 @@ import { getListImagesUrl, imagesSelectors } from 'services/api/util';
import { startAppListening } from '..'; import { startAppListening } from '..';
export const appStarted = createAction('app/appStarted');
export const addFirstListImagesListener = () => { export const addFirstListImagesListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.listImages.matchFulfilled, matcher: imagesApi.endpoints.listImages.matchFulfilled,

View File

@ -1,6 +1,6 @@
import { atom } from 'nanostores'; import { atom } from 'nanostores';
export const DEFAULT_BULK_DOWNLOAD_ID = 'default'; const DEFAULT_BULK_DOWNLOAD_ID = 'default';
/** /**
* The download id for a bulk download. Used for socket subscriptions. * The download id for a bulk download. Used for socket subscriptions.

View File

@ -136,7 +136,7 @@ const unserialize: UnserializeFunction = (data, key) => {
} }
}; };
export const serialize: SerializeFunction = (data, key) => { const serialize: SerializeFunction = (data, key) => {
const persistConfig = persistConfigs[key as keyof typeof persistConfigs]; const persistConfig = persistConfigs[key as keyof typeof persistConfigs];
if (!persistConfig) { if (!persistConfig) {
throw new Error(`No persist config for slice "${key}"`); throw new Error(`No persist config for slice "${key}"`);

View File

@ -1,2 +0,0 @@
export const EMPTY_ARRAY = [];
export const EMPTY_OBJECT = {};

View File

@ -1 +0,0 @@
export const Nbsp = () => <>{'\u00A0'}</>;

View File

@ -1,102 +0,0 @@
import { useLayoutEffect, useRef, useState } from 'react';
// Adapted from https://github.com/konvajs/use-image
type CrossOrigin = 'anonymous' | 'use-credentials';
type ReferrerPolicy =
| 'no-referrer'
| 'no-referrer-when-downgrade'
| 'origin'
| 'origin-when-cross-origin'
| 'same-origin'
| 'strict-origin'
| 'strict-origin-when-cross-origin'
| 'unsafe-url';
type ImageStatus = 'loaded' | 'loading' | 'failed';
export const useImage = (
url: string,
crossOrigin?: CrossOrigin,
referrerpolicy?: ReferrerPolicy
): [undefined | HTMLImageElement, ImageStatus, Blob | null] => {
// lets use refs for image and status
// so we can update them during render
// to have instant update in status/image when new data comes in
const statusRef = useRef<ImageStatus>('loading');
const imageRef = useRef<HTMLImageElement>();
const blobRef = useRef<Blob | null>(null);
// we are not going to use token
// but we need to just to trigger state update
const [_, setStateToken] = useState(0);
// keep track of old props to trigger changes
const oldUrl = useRef<string>();
const oldCrossOrigin = useRef<string>();
const oldReferrerPolicy = useRef<string>();
if (
oldUrl.current !== url ||
oldCrossOrigin.current !== crossOrigin ||
oldReferrerPolicy.current !== referrerpolicy
) {
statusRef.current = 'loading';
imageRef.current = undefined;
oldUrl.current = url;
oldCrossOrigin.current = crossOrigin;
oldReferrerPolicy.current = referrerpolicy;
}
useLayoutEffect(
function () {
if (!url) {
return;
}
const img = document.createElement('img');
function onload() {
statusRef.current = 'loaded';
imageRef.current = img;
const canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;
const context = canvas.getContext('2d');
if (context) {
context.drawImage(img, 0, 0);
canvas.toBlob(function (blob) {
blobRef.current = blob;
}, 'image/png');
}
setStateToken(Math.random());
}
function onerror() {
statusRef.current = 'failed';
imageRef.current = undefined;
setStateToken(Math.random());
}
img.addEventListener('load', onload);
img.addEventListener('error', onerror);
if (crossOrigin) {
img.crossOrigin = crossOrigin;
}
if (referrerpolicy) {
img.referrerPolicy = referrerpolicy;
}
img.src = url;
return function cleanup() {
img.removeEventListener('load', onload);
img.removeEventListener('error', onerror);
};
},
[url, crossOrigin, referrerpolicy]
);
// return array because it is better to use in case of several useImage hooks
// const [background, backgroundStatus] = useImage(url1);
// const [patter] = useImage(url2);
return [imageRef.current, statusRef.current, blobRef.current];
};

View File

@ -1,6 +1,6 @@
import type { Item } from '@invoke-ai/ui-library'; import type { Item } from '@invoke-ai/ui-library';
import type { EntityState } from '@reduxjs/toolkit'; import type { EntityState } from '@reduxjs/toolkit';
import { EMPTY_ARRAY } from 'app/store/util'; import { EMPTY_ARRAY } from "app/store/constants";
import type { ModelIdentifierWithBase } from 'features/nodes/types/common'; import type { ModelIdentifierWithBase } from 'features/nodes/types/common';
import { MODEL_TYPE_SHORT_MAP } from 'features/parameters/types/constants'; import { MODEL_TYPE_SHORT_MAP } from 'features/parameters/types/constants';
import { filter } from 'lodash-es'; import { filter } from 'lodash-es';

View File

@ -16,5 +16,3 @@ export const generateSeeds = ({ count, start, min = NUMPY_RAND_MIN, max = NUMPY_
} }
return seeds; return seeds;
}; };
export const generateOneSeed = (min: number = NUMPY_RAND_MIN, max: number = NUMPY_RAND_MAX) => random(min, max);

View File

@ -8,7 +8,3 @@ export const roundDownToMultipleMin = (num: number, multiple: number): number =>
export const roundToMultiple = (num: number, multiple: number): number => { export const roundToMultiple = (num: number, multiple: number): number => {
return Math.round(num / multiple) * multiple; return Math.round(num / multiple) * multiple;
}; };
export const roundToMultipleMin = (num: number, multiple: number): number => {
return Math.max(multiple, roundToMultiple(num, multiple));
};

View File

@ -1,8 +0,0 @@
import type { MouseEvent } from 'react';
/**
* Prevents the default behavior of the event.
*/
export const skipMouseEvent = (e: MouseEvent) => {
e.preventDefault();
};

View File

@ -1,5 +0,0 @@
import type { ClipboardEvent } from 'react';
export const stopPastePropagation = (e: ClipboardEvent) => {
e.stopPropagation();
};

View File

@ -9,7 +9,7 @@ import { isNumber } from 'lodash-es';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Rect } from 'react-konva'; import { Rect } from 'react-konva';
export const canvasMaskCompositerSelector = createMemoizedSelector(selectCanvasSlice, (canvas) => { const canvasMaskCompositerSelector = createMemoizedSelector(selectCanvasSlice, (canvas) => {
return { return {
stageCoordinates: canvas.stageCoordinates, stageCoordinates: canvas.stageCoordinates,
stageDimensions: canvas.stageDimensions, stageDimensions: canvas.stageDimensions,

View File

@ -1,14 +1,8 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { selectCanvasSlice } from './canvasSlice'; import { selectCanvasSlice } from './canvasSlice';
import { isCanvasBaseImage } from './canvasTypes';
export const isStagingSelector = createSelector( export const isStagingSelector = createSelector(
selectCanvasSlice, selectCanvasSlice,
(canvas) => canvas.batchIds.length > 0 || canvas.layerState.stagingArea.images.length > 0 (canvas) => canvas.batchIds.length > 0 || canvas.layerState.stagingArea.images.length > 0
); );
export const initialCanvasImageSelector = createMemoizedSelector(selectCanvasSlice, (canvas) =>
canvas.layerState.objects.find(isCanvasBaseImage)
);

View File

@ -38,7 +38,7 @@ import { CANVAS_GRID_SIZE_FINE } from './constants';
*/ */
const MAX_HISTORY = 128; const MAX_HISTORY = 128;
export const initialLayerState: CanvasLayerState = { const initialLayerState: CanvasLayerState = {
objects: [], objects: [],
stagingArea: { stagingArea: {
images: [], images: [],
@ -46,11 +46,10 @@ export const initialLayerState: CanvasLayerState = {
}, },
}; };
export const initialCanvasState: CanvasState = { const initialCanvasState: CanvasState = {
_version: 1, _version: 1,
boundingBoxCoordinates: { x: 0, y: 0 }, boundingBoxCoordinates: { x: 0, y: 0 },
boundingBoxDimensions: { width: 512, height: 512 }, boundingBoxDimensions: { width: 512, height: 512 },
boundingBoxPreviewFill: { r: 0, g: 0, b: 0, a: 0.5 },
boundingBoxScaleMethod: 'auto', boundingBoxScaleMethod: 'auto',
brushColor: { r: 90, g: 90, b: 255, a: 1 }, brushColor: { r: 90, g: 90, b: 255, a: 1 },
brushSize: 50, brushSize: 50,
@ -215,9 +214,6 @@ export const canvasSlice = createSlice({
setStageCoordinates: (state, action: PayloadAction<Vector2d>) => { setStageCoordinates: (state, action: PayloadAction<Vector2d>) => {
state.stageCoordinates = action.payload; state.stageCoordinates = action.payload;
}, },
setBoundingBoxPreviewFill: (state, action: PayloadAction<RgbaColor>) => {
state.boundingBoxPreviewFill = action.payload;
},
setStageScale: (state, action: PayloadAction<number>) => { setStageScale: (state, action: PayloadAction<number>) => {
state.stageScale = action.payload; state.stageScale = action.payload;
}, },
@ -231,9 +227,6 @@ export const canvasSlice = createSlice({
setShouldLockBoundingBox: (state, action: PayloadAction<boolean>) => { setShouldLockBoundingBox: (state, action: PayloadAction<boolean>) => {
state.shouldLockBoundingBox = action.payload; state.shouldLockBoundingBox = action.payload;
}, },
toggleShouldLockBoundingBox: (state) => {
state.shouldLockBoundingBox = !state.shouldLockBoundingBox;
},
setShouldShowBoundingBox: (state, action: PayloadAction<boolean>) => { setShouldShowBoundingBox: (state, action: PayloadAction<boolean>) => {
state.shouldShowBoundingBox = action.payload; state.shouldShowBoundingBox = action.payload;
}, },
@ -573,19 +566,6 @@ export const canvasSlice = createSlice({
}, },
}), }),
}, },
scaledBoundingBoxDimensionsReset: {
reducer: (state, action: PayloadActionWithOptimalDimension) => {
const scaledDimensions = getScaledBoundingBoxDimensions(
state.boundingBoxDimensions,
action.meta.optimalDimension
);
state.scaledBoundingBoxDimensions = scaledDimensions;
},
prepare: (payload: void, optimalDimension: number) => ({
payload: undefined,
meta: { optimalDimension },
}),
},
setShouldShowStagingImage: (state, action: PayloadAction<boolean>) => { setShouldShowStagingImage: (state, action: PayloadAction<boolean>) => {
state.shouldShowStagingImage = action.payload; state.shouldShowStagingImage = action.payload;
}, },
@ -682,7 +662,6 @@ export const {
resetCanvasView, resetCanvasView,
setBoundingBoxCoordinates, setBoundingBoxCoordinates,
setBoundingBoxDimensions, setBoundingBoxDimensions,
setBoundingBoxPreviewFill,
setBoundingBoxScaleMethod, setBoundingBoxScaleMethod,
setBrushColor, setBrushColor,
setBrushSize, setBrushSize,
@ -706,7 +685,6 @@ export const {
setShouldSnapToGrid, setShouldSnapToGrid,
setStageCoordinates, setStageCoordinates,
setStageScale, setStageScale,
toggleShouldLockBoundingBox,
undo, undo,
setScaledBoundingBoxDimensions, setScaledBoundingBoxDimensions,
setShouldRestrictStrokesToBox, setShouldRestrictStrokesToBox,
@ -716,13 +694,12 @@ export const {
canvasBatchIdAdded, canvasBatchIdAdded,
canvasBatchIdsReset, canvasBatchIdsReset,
aspectRatioChanged, aspectRatioChanged,
scaledBoundingBoxDimensionsReset,
} = canvasSlice.actions; } = canvasSlice.actions;
export const selectCanvasSlice = (state: RootState) => state.canvas; export const selectCanvasSlice = (state: RootState) => state.canvas;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateCanvasState = (state: any): any => { const migrateCanvasState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
state.aspectRatio = initialAspectRatioState; state.aspectRatio = initialAspectRatioState;

View File

@ -10,9 +10,9 @@ export const LAYER_NAMES_DICT: { label: string; value: CanvasLayer }[] = [
{ label: 'Mask', value: 'mask' }, { label: 'Mask', value: 'mask' },
]; ];
export const LAYER_NAMES = ['base', 'mask'] as const; const LAYER_NAMES = ['base', 'mask'] as const;
export const zBoundingBoxScaleMethod = z.enum(['none', 'auto', 'manual']); const zBoundingBoxScaleMethod = z.enum(['none', 'auto', 'manual']);
export type BoundingBoxScaleMethod = z.infer<typeof zBoundingBoxScaleMethod>; export type BoundingBoxScaleMethod = z.infer<typeof zBoundingBoxScaleMethod>;
export const isBoundingBoxScaleMethod = (v: unknown): v is BoundingBoxScaleMethod => export const isBoundingBoxScaleMethod = (v: unknown): v is BoundingBoxScaleMethod =>
zBoundingBoxScaleMethod.safeParse(v).success; zBoundingBoxScaleMethod.safeParse(v).success;
@ -112,7 +112,6 @@ export interface CanvasState {
_version: 1; _version: 1;
boundingBoxCoordinates: Vector2d; boundingBoxCoordinates: Vector2d;
boundingBoxDimensions: Dimensions; boundingBoxDimensions: Dimensions;
boundingBoxPreviewFill: RgbaColor;
boundingBoxScaleMethod: BoundingBoxScaleMethod; boundingBoxScaleMethod: BoundingBoxScaleMethod;
brushColor: RgbaColor; brushColor: RgbaColor;
brushSize: number; brushSize: number;

View File

@ -1,16 +1,6 @@
import type { RgbaColor, RgbColor } from 'react-colorful'; import type { RgbaColor } from 'react-colorful';
export const rgbaColorToString = (color: RgbaColor): string => { export const rgbaColorToString = (color: RgbaColor): string => {
const { r, g, b, a } = color; const { r, g, b, a } = color;
return `rgba(${r}, ${g}, ${b}, ${a})`; return `rgba(${r}, ${g}, ${b}, ${a})`;
}; };
export const rgbaColorToRgbString = (color: RgbaColor): string => {
const { r, g, b } = color;
return `rgba(${r}, ${g}, ${b})`;
};
export const rgbColorToString = (color: RgbColor): string => {
const { r, g, b } = color;
return `rgba(${r}, ${g}, ${b})`;
};

View File

@ -1,6 +1,3 @@
// bounding box anchor size
export const TRANSFORMER_ANCHOR_SIZE = 15;
// canvas wheel zoom exponential scale factor // canvas wheel zoom exponential scale factor
export const CANVAS_SCALE_BY = 0.999; export const CANVAS_SCALE_BY = 0.999;

View File

@ -1,11 +0,0 @@
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import type { Dimensions } from 'features/canvas/store/canvasTypes';
const roundDimensionsToMultiple = (dimensions: Dimensions, multiple: number): Dimensions => {
return {
width: roundToMultiple(dimensions.width, multiple),
height: roundToMultiple(dimensions.height, multiple),
};
};
export default roundDimensionsToMultiple;

View File

@ -1,21 +0,0 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks';
import {
selectControlAdapterById,
selectControlAdaptersSlice,
} from 'features/controlAdapters/store/controlAdaptersSlice';
import { useMemo } from 'react';
export const useControlAdapter = (id: string) => {
const selector = useMemo(
() =>
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) =>
selectControlAdapterById(controlAdapters, id)
),
[id]
);
const controlAdapter = useAppSelector(selector);
return controlAdapter;
};

View File

@ -30,10 +30,10 @@ import type {
} from './types'; } from './types';
import { isControlNet, isControlNetOrT2IAdapter, isIPAdapter, isT2IAdapter } from './types'; import { isControlNet, isControlNetOrT2IAdapter, isIPAdapter, isT2IAdapter } from './types';
export const caAdapter = createEntityAdapter<ControlAdapterConfig, string>({ const caAdapter = createEntityAdapter<ControlAdapterConfig, string>({
selectId: (ca) => ca.id, selectId: (ca) => ca.id,
}); });
export const caAdapterSelectors = caAdapter.getSelectors(undefined, getSelectorsOptions); const caAdapterSelectors = caAdapter.getSelectors(undefined, getSelectorsOptions);
export const { export const {
selectById: selectControlAdapterById, selectById: selectControlAdapterById,
@ -43,7 +43,7 @@ export const {
selectTotal: selectControlAdapterTotal, selectTotal: selectControlAdapterTotal,
} = caAdapterSelectors; } = caAdapterSelectors;
export const initialControlAdaptersState: ControlAdaptersState = caAdapter.getInitialState<{ const initialControlAdaptersState: ControlAdaptersState = caAdapter.getInitialState<{
_version: 1; _version: 1;
pendingControlImages: string[]; pendingControlImages: string[];
}>({ }>({
@ -131,22 +131,6 @@ export const controlAdaptersSlice = createSlice({
return { payload: { id, newId: uuidv4() } }; return { payload: { id, newId: uuidv4() } };
}, },
}, },
controlAdapterAddedFromImage: {
reducer: (
state,
action: PayloadAction<{
id: string;
type: ControlAdapterType;
controlImage: string;
}>
) => {
const { id, type, controlImage } = action.payload;
caAdapter.addOne(state, buildControlAdapter(id, type, { controlImage }));
},
prepare: (payload: { type: ControlAdapterType; controlImage: string }) => {
return { payload: { ...payload, id: uuidv4() } };
},
},
controlAdapterRemoved: (state, action: PayloadAction<{ id: string }>) => { controlAdapterRemoved: (state, action: PayloadAction<{ id: string }>) => {
caAdapter.removeOne(state, action.payload.id); caAdapter.removeOne(state, action.payload.id);
}, },
@ -407,7 +391,6 @@ export const {
controlAdapterAdded, controlAdapterAdded,
controlAdapterRecalled, controlAdapterRecalled,
controlAdapterDuplicated, controlAdapterDuplicated,
controlAdapterAddedFromImage,
controlAdapterRemoved, controlAdapterRemoved,
controlAdapterImageChanged, controlAdapterImageChanged,
controlAdapterProcessedImageChanged, controlAdapterProcessedImageChanged,
@ -426,16 +409,12 @@ export const {
controlAdapterModelCleared, controlAdapterModelCleared,
} = controlAdaptersSlice.actions; } = controlAdaptersSlice.actions;
export const isAnyControlAdapterAdded = isAnyOf( export const isAnyControlAdapterAdded = isAnyOf(controlAdapterAdded, controlAdapterRecalled);
controlAdapterAdded,
controlAdapterAddedFromImage,
controlAdapterRecalled
);
export const selectControlAdaptersSlice = (state: RootState) => state.controlAdapters; export const selectControlAdaptersSlice = (state: RootState) => state.controlAdapters;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateControlAdaptersState = (state: any): any => { const migrateControlAdaptersState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -4,7 +4,6 @@ import type {
ParameterIPAdapterModel, ParameterIPAdapterModel,
ParameterT2IAdapterModel, ParameterT2IAdapterModel,
} from 'features/parameters/types/parameterSchemas'; } from 'features/parameters/types/parameterSchemas';
import { isObject } from 'lodash-es';
import type { components } from 'services/api/schema'; import type { components } from 'services/api/schema';
import type { import type {
CannyImageProcessorInvocation, CannyImageProcessorInvocation,
@ -81,7 +80,7 @@ export type RequiredDepthAnythingImageProcessorInvocation = O.Required<
'type' | 'model_size' | 'resolution' | 'offload' 'type' | 'model_size' | 'resolution' | 'offload'
>; >;
export const zDepthAnythingModelSize = z.enum(['large', 'base', 'small']); const zDepthAnythingModelSize = z.enum(['large', 'base', 'small']);
export type DepthAnythingModelSize = z.infer<typeof zDepthAnythingModelSize>; export type DepthAnythingModelSize = z.infer<typeof zDepthAnythingModelSize>;
export const isDepthAnythingModelSize = (v: unknown): v is DepthAnythingModelSize => export const isDepthAnythingModelSize = (v: unknown): v is DepthAnythingModelSize =>
zDepthAnythingModelSize.safeParse(v).success; zDepthAnythingModelSize.safeParse(v).success;
@ -186,151 +185,9 @@ export type RequiredControlAdapterProcessorNode =
> >
| { type: 'none' }; | { type: 'none' };
/**
* Type guard for CannyImageProcessorInvocation
*/
export const isCannyImageProcessorInvocation = (obj: unknown): obj is CannyImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'canny_image_processor') {
return true;
}
return false;
};
/**
* Type guard for ColorMapImageProcessorInvocation
*/
export const isColorMapImageProcessorInvocation = (obj: unknown): obj is ColorMapImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'color_map_image_processor') {
return true;
}
return false;
};
/**
* Type guard for ContentShuffleImageProcessorInvocation
*/
export const isContentShuffleImageProcessorInvocation = (
obj: unknown
): obj is ContentShuffleImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'content_shuffle_image_processor') {
return true;
}
return false;
};
/**
* Type guard for DepthAnythingImageProcessorInvocation
*/
export const isDepthAnythingImageProcessorInvocation = (obj: unknown): obj is DepthAnythingImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'depth_anything_image_processor') {
return true;
}
return false;
};
/**
* Type guard for HedImageprocessorInvocation
*/
export const isHedImageprocessorInvocation = (obj: unknown): obj is HedImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'hed_image_processor') {
return true;
}
return false;
};
/**
* Type guard for LineartAnimeImageProcessorInvocation
*/
export const isLineartAnimeImageProcessorInvocation = (obj: unknown): obj is LineartAnimeImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'lineart_anime_image_processor') {
return true;
}
return false;
};
/**
* Type guard for LineartImageProcessorInvocation
*/
export const isLineartImageProcessorInvocation = (obj: unknown): obj is LineartImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'lineart_image_processor') {
return true;
}
return false;
};
/**
* Type guard for MediapipeFaceProcessorInvocation
*/
export const isMediapipeFaceProcessorInvocation = (obj: unknown): obj is MediapipeFaceProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'mediapipe_face_processor') {
return true;
}
return false;
};
/**
* Type guard for MidasDepthImageProcessorInvocation
*/
export const isMidasDepthImageProcessorInvocation = (obj: unknown): obj is MidasDepthImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'midas_depth_image_processor') {
return true;
}
return false;
};
/**
* Type guard for MlsdImageProcessorInvocation
*/
export const isMlsdImageProcessorInvocation = (obj: unknown): obj is MlsdImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'mlsd_image_processor') {
return true;
}
return false;
};
/**
* Type guard for NormalbaeImageProcessorInvocation
*/
export const isNormalbaeImageProcessorInvocation = (obj: unknown): obj is NormalbaeImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'normalbae_image_processor') {
return true;
}
return false;
};
/**
* Type guard for DWOpenposeImageProcessorInvocation
*/
export const isDWOpenposeImageProcessorInvocation = (obj: unknown): obj is DWOpenposeImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'dw_openpose_image_processor') {
return true;
}
return false;
};
/**
* Type guard for PidiImageProcessorInvocation
*/
export const isPidiImageProcessorInvocation = (obj: unknown): obj is PidiImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'pidi_image_processor') {
return true;
}
return false;
};
/**
* Type guard for ZoeDepthImageProcessorInvocation
*/
export const isZoeDepthImageProcessorInvocation = (obj: unknown): obj is ZoeDepthImageProcessorInvocation => {
if (isObject(obj) && 'type' in obj && obj.type === 'zoe_depth_image_processor') {
return true;
}
return false;
};
export type ControlMode = NonNullable<components['schemas']['ControlNetInvocation']['control_mode']>; export type ControlMode = NonNullable<components['schemas']['ControlNetInvocation']['control_mode']>;
export const zResizeMode = z.enum(['just_resize', 'crop_resize', 'fill_resize', 'just_resize_simple']); const zResizeMode = z.enum(['just_resize', 'crop_resize', 'fill_resize', 'just_resize_simple']);
export type ResizeMode = z.infer<typeof zResizeMode>; export type ResizeMode = z.infer<typeof zResizeMode>;
export const isResizeMode = (v: unknown): v is ResizeMode => zResizeMode.safeParse(v).success; export const isResizeMode = (v: unknown): v is ResizeMode => zResizeMode.safeParse(v).success;

View File

@ -3,11 +3,11 @@ import { createSlice } from '@reduxjs/toolkit';
import type { PersistConfig, RootState } from 'app/store/store'; import type { PersistConfig, RootState } from 'app/store/store';
import { z } from 'zod'; import { z } from 'zod';
export const zSeedBehaviour = z.enum(['PER_ITERATION', 'PER_PROMPT']); const zSeedBehaviour = z.enum(['PER_ITERATION', 'PER_PROMPT']);
export type SeedBehaviour = z.infer<typeof zSeedBehaviour>; export type SeedBehaviour = z.infer<typeof zSeedBehaviour>;
export const isSeedBehaviour = (v: unknown): v is SeedBehaviour => zSeedBehaviour.safeParse(v).success; export const isSeedBehaviour = (v: unknown): v is SeedBehaviour => zSeedBehaviour.safeParse(v).success;
export interface DynamicPromptsState { interface DynamicPromptsState {
_version: 1; _version: 1;
maxPrompts: number; maxPrompts: number;
combinatorial: boolean; combinatorial: boolean;
@ -18,7 +18,7 @@ export interface DynamicPromptsState {
seedBehaviour: SeedBehaviour; seedBehaviour: SeedBehaviour;
} }
export const initialDynamicPromptsState: DynamicPromptsState = { const initialDynamicPromptsState: DynamicPromptsState = {
_version: 1, _version: 1,
maxPrompts: 100, maxPrompts: 100,
combinatorial: true, combinatorial: true,
@ -29,11 +29,9 @@ export const initialDynamicPromptsState: DynamicPromptsState = {
seedBehaviour: 'PER_ITERATION', seedBehaviour: 'PER_ITERATION',
}; };
const initialState: DynamicPromptsState = initialDynamicPromptsState;
export const dynamicPromptsSlice = createSlice({ export const dynamicPromptsSlice = createSlice({
name: 'dynamicPrompts', name: 'dynamicPrompts',
initialState, initialState: initialDynamicPromptsState,
reducers: { reducers: {
maxPromptsChanged: (state, action: PayloadAction<number>) => { maxPromptsChanged: (state, action: PayloadAction<number>) => {
state.maxPrompts = action.payload; state.maxPrompts = action.payload;
@ -77,7 +75,7 @@ export const {
export const selectDynamicPromptsSlice = (state: RootState) => state.dynamicPrompts; export const selectDynamicPromptsSlice = (state: RootState) => state.dynamicPrompts;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateDynamicPromptsState = (state: any): any => { const migrateDynamicPromptsState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -1,15 +1,4 @@
import { createAction } from '@reduxjs/toolkit'; import { createAction } from '@reduxjs/toolkit';
import type { ImageUsage } from 'features/deleteImageModal/store/types';
import type { BoardDTO } from 'services/api/types';
export type RequestedBoardImagesDeletionArg = {
board: BoardDTO;
imagesUsage: ImageUsage;
};
export const requestedBoardImagesDeletion = createAction<RequestedBoardImagesDeletionArg>(
'gallery/requestedBoardImagesDeletion'
);
export const sentImageToCanvas = createAction('gallery/sentImageToCanvas'); export const sentImageToCanvas = createAction('gallery/sentImageToCanvas');

View File

@ -9,7 +9,7 @@ import type { ImageDTO } from 'services/api/types';
import type { BoardId, GalleryState, GalleryView } from './types'; import type { BoardId, GalleryState, GalleryView } from './types';
import { IMAGE_LIMIT, INITIAL_IMAGE_LIMIT } from './types'; import { IMAGE_LIMIT, INITIAL_IMAGE_LIMIT } from './types';
export const initialGalleryState: GalleryState = { const initialGalleryState: GalleryState = {
selection: [], selection: [],
shouldAutoSwitch: true, shouldAutoSwitch: true,
autoAssignBoardOnClick: true, autoAssignBoardOnClick: true,
@ -117,7 +117,7 @@ const isAnyBoardDeleted = isAnyOf(
export const selectGallerySlice = (state: RootState) => state.gallery; export const selectGallerySlice = (state: RootState) => state.gallery;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateGalleryState = (state: any): any => { const migrateGalleryState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -10,18 +10,16 @@ export interface HRFState {
hrfMethod: ParameterHRFMethod; hrfMethod: ParameterHRFMethod;
} }
export const initialHRFState: HRFState = { const initialHRFState: HRFState = {
_version: 1, _version: 1,
hrfStrength: 0.45, hrfStrength: 0.45,
hrfEnabled: false, hrfEnabled: false,
hrfMethod: 'ESRGAN', hrfMethod: 'ESRGAN',
}; };
const initialState: HRFState = initialHRFState;
export const hrfSlice = createSlice({ export const hrfSlice = createSlice({
name: 'hrf', name: 'hrf',
initialState, initialState: initialHRFState,
reducers: { reducers: {
setHrfStrength: (state, action: PayloadAction<number>) => { setHrfStrength: (state, action: PayloadAction<number>) => {
state.hrfStrength = action.payload; state.hrfStrength = action.payload;
@ -40,7 +38,7 @@ export const { setHrfEnabled, setHrfStrength, setHrfMethod } = hrfSlice.actions;
export const selectHrfSlice = (state: RootState) => state.hrf; export const selectHrfSlice = (state: RootState) => state.hrf;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateHRFState = (state: any): any => { const migrateHRFState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -21,7 +21,7 @@ export type LoraState = {
loras: Record<string, LoRA>; loras: Record<string, LoRA>;
}; };
export const initialLoraState: LoraState = { const initialLoraState: LoraState = {
_version: 1, _version: 1,
loras: {}, loras: {},
}; };
@ -41,9 +41,6 @@ export const loraSlice = createSlice({
const key = action.payload; const key = action.payload;
delete state.loras[key]; delete state.loras[key];
}, },
lorasCleared: (state) => {
state.loras = {};
},
loraWeightChanged: (state, action: PayloadAction<{ key: string; weight: number }>) => { loraWeightChanged: (state, action: PayloadAction<{ key: string; weight: number }>) => {
const { key, weight } = action.payload; const { key, weight } = action.payload;
const lora = state.loras[key]; const lora = state.loras[key];
@ -52,14 +49,6 @@ export const loraSlice = createSlice({
} }
lora.weight = weight; lora.weight = weight;
}, },
loraWeightReset: (state, action: PayloadAction<string>) => {
const key = action.payload;
const lora = state.loras[key];
if (!lora) {
return;
}
lora.weight = defaultLoRAConfig.weight;
},
loraIsEnabledChanged: (state, action: PayloadAction<{ key: string; isEnabled: boolean }>) => { loraIsEnabledChanged: (state, action: PayloadAction<{ key: string; isEnabled: boolean }>) => {
const { key, isEnabled } = action.payload; const { key, isEnabled } = action.payload;
const lora = state.loras[key]; const lora = state.loras[key];
@ -71,20 +60,12 @@ export const loraSlice = createSlice({
}, },
}); });
export const { export const { loraAdded, loraRemoved, loraWeightChanged, loraIsEnabledChanged, loraRecalled } = loraSlice.actions;
loraAdded,
loraRemoved,
loraWeightChanged,
loraWeightReset,
loraIsEnabledChanged,
lorasCleared,
loraRecalled,
} = loraSlice.actions;
export const selectLoraSlice = (state: RootState) => state.lora; export const selectLoraSlice = (state: RootState) => state.lora;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateLoRAState = (state: any): any => { const migrateLoRAState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -1,27 +1 @@
/**
* Raised when metadata parsing fails.
*/
export class MetadataParseError extends Error {
/**
* Create MetadataParseError
* @param {String} message
*/
constructor(message: string) {
super(message);
this.name = this.constructor.name;
}
}
/**
* Raised when metadata recall fails.
*/
export class MetadataRecallError extends Error {
/**
* Create MetadataRecallError
* @param {String} message
*/
constructor(message: string) {
super(message);
this.name = this.constructor.name;
}
}

View File

@ -22,7 +22,6 @@ export type MetadataRecallOptions = MetadataParseOptions;
* A function that recalls a parsed and validated metadata value. * A function that recalls a parsed and validated metadata value.
* *
* @param value The value to recall. * @param value The value to recall.
* @throws MetadataRecallError if the value cannot be recalled.
*/ */
export type MetadataRecallFunc<T> = (value: T) => void; export type MetadataRecallFunc<T> = (value: T) => void;
@ -49,7 +48,7 @@ export type MetadataParseFunc<T = unknown> = (metadata: unknown) => Promise<T>;
* *
* @param value The value to validate. * @param value The value to validate.
* @returns A promise that resolves to the validated value. * @returns A promise that resolves to the validated value.
* @throws MetadataRecallError if the value is invalid. * @throws MetadataParseError if the value is invalid.
*/ */
export type MetadataValidateFunc<T> = (value: T) => Promise<T>; export type MetadataValidateFunc<T> = (value: T) => Promise<T>;
@ -88,7 +87,6 @@ export type MetadataHandlers<TValue = unknown, TItem = unknown> = {
* @param value The value to recall. * @param value The value to recall.
* @param withToast Whether to show a toast on success or failure. * @param withToast Whether to show a toast on success or failure.
* @returns A promise that resolves when the recall operation is complete. * @returns A promise that resolves when the recall operation is complete.
* @throws MetadataRecallError if the value cannot be recalled.
*/ */
recall?: (value: TValue, withToast?: boolean) => Promise<void>; recall?: (value: TValue, withToast?: boolean) => Promise<void>;
/** /**
@ -99,7 +97,6 @@ export type MetadataHandlers<TValue = unknown, TItem = unknown> = {
* @param item The item to recall. It should be an item from the array. * @param item The item to recall. It should be an item from the array.
* @param withToast Whether to show a toast on success or failure. * @param withToast Whether to show a toast on success or failure.
* @returns A promise that resolves when the recall operation is complete. * @returns A promise that resolves when the recall operation is complete.
* @throws MetadataRecallError if the value cannot be recalled.
*/ */
recallItem?: (item: TItem, withToast?: boolean) => Promise<void>; recallItem?: (item: TItem, withToast?: boolean) => Promise<void>;
/** /**

View File

@ -4,8 +4,6 @@ import { isModelIdentifier, isModelIdentifierV2 } from 'features/nodes/types/com
import { modelsApi } from 'services/api/endpoints/models'; import { modelsApi } from 'services/api/endpoints/models';
import type { AnyModelConfig, BaseModelType, ModelType } from 'services/api/types'; import type { AnyModelConfig, BaseModelType, ModelType } from 'services/api/types';
/** /**
* Raised when a model config is unable to be fetched. * Raised when a model config is unable to be fetched.
*/ */
@ -93,19 +91,6 @@ export const fetchModelConfigWithTypeGuard = async <T extends AnyModelConfig>(
return modelConfig; return modelConfig;
}; };
/**
* Raises an error if the source base model is incompatible with the target base model.
* @param sourceBase The source base model.
* @param targetBase The target base model.
* @param message An optional custom message to include in the error.
* @throws {InvalidModelConfigError} If the source base model is incompatible with the target base model.
*/
export const raiseIfBaseIncompatible = (sourceBase: BaseModelType, targetBase?: BaseModelType, message?: string) => {
if (targetBase && sourceBase !== targetBase) {
throw new InvalidModelConfigError(message || `Incompatible base models: ${sourceBase} and ${targetBase}`);
}
};
/** /**
* Fetches the model key from a model identifier. This includes fetching the key for MM1 format model identifiers. * Fetches the model key from a model identifier. This includes fetching the key for MM1 format model identifiers.
* @param modelIdentifier The model identifier. The MM2 format `{key: string}` simply extracts the key. The MM1 format * @param modelIdentifier The model identifier. The MM2 format `{key: string}` simply extracts the key. The MM1 format

View File

@ -6,12 +6,13 @@ import {
} from 'features/controlAdapters/util/buildControlAdapter'; } from 'features/controlAdapters/util/buildControlAdapter';
import type { LoRA } from 'features/lora/store/loraSlice'; import type { LoRA } from 'features/lora/store/loraSlice';
import { defaultLoRAConfig } from 'features/lora/store/loraSlice'; import { defaultLoRAConfig } from 'features/lora/store/loraSlice';
import { MetadataParseError } from 'features/metadata/exceptions'; import type {
import type { ControlNetConfigMetadata, IPAdapterConfigMetadata, MetadataParseFunc, T2IAdapterConfigMetadata } from 'features/metadata/types'; ControlNetConfigMetadata,
import { IPAdapterConfigMetadata,
fetchModelConfigWithTypeGuard, MetadataParseFunc,
getModelKey, T2IAdapterConfigMetadata,
} from 'features/metadata/util/modelFetchingHelpers'; } from 'features/metadata/types';
import { fetchModelConfigWithTypeGuard, getModelKey } from 'features/metadata/util/modelFetchingHelpers';
import { import {
zControlField, zControlField,
zIPAdapterField, zIPAdapterField,
@ -74,6 +75,19 @@ import { v4 as uuidv4 } from 'uuid';
export const MetadataParsePendingToken = Symbol('pending'); export const MetadataParsePendingToken = Symbol('pending');
export const MetadataParseFailedToken = Symbol('failed'); export const MetadataParseFailedToken = Symbol('failed');
/**
* Raised when metadata parsing fails.
*/
export class MetadataParseError extends Error {
/**
* Create MetadataParseError
* @param {String} message
*/
constructor(message: string) {
super(message);
this.name = this.constructor.name;
}
}
/** /**
* An async function that a property from an object and validates its type using a type guard. If the property is missing * An async function that a property from an object and validates its type using a type guard. If the property is missing

View File

@ -1,32 +0,0 @@
import type { ButtonProps } from '@invoke-ai/ui-library';
import { Button } from '@invoke-ai/ui-library';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiArrowsClockwiseBold } from 'react-icons/pi';
import { useSyncModels } from './useSyncModels';
export const SyncModelsButton = memo((props: Omit<ButtonProps, 'children'>) => {
const { t } = useTranslation();
const { syncModels, isLoading } = useSyncModels();
const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled;
if (!isSyncModelEnabled) {
return null;
}
return (
<Button
isLoading={isLoading}
onClick={syncModels}
leftIcon={<PiArrowsClockwiseBold />}
minW="max-content"
{...props}
>
{t('modelManager.syncModels')}
</Button>
);
});
SyncModelsButton.displayName = 'SyncModelsButton';

View File

@ -10,7 +10,7 @@ type ModelManagerState = {
filteredModelType: string | null; filteredModelType: string | null;
}; };
export const initialModelManagerState: ModelManagerState = { const initialModelManagerState: ModelManagerState = {
_version: 1, _version: 1,
selectedModelKey: null, selectedModelKey: null,
selectedModelMode: 'view', selectedModelMode: 'view',
@ -42,10 +42,10 @@ export const modelManagerV2Slice = createSlice({
export const { setSelectedModelKey, setSearchTerm, setFilteredModelType, setSelectedModelMode } = export const { setSelectedModelKey, setSearchTerm, setFilteredModelType, setSelectedModelMode } =
modelManagerV2Slice.actions; modelManagerV2Slice.actions;
export const selectModelManagerSlice = (state: RootState) => state.modelmanager; export const selectModelManagerSlice = (state: RootState) => state.modelmanagerV2;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateModelManagerState = (state: any): any => { const migrateModelManagerState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -16,11 +16,6 @@ import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useImportAdvancedModelMutation } from 'services/api/endpoints/models'; import { useImportAdvancedModelMutation } from 'services/api/endpoints/models';
import type { AnyModelConfig } from 'services/api/types'; import type { AnyModelConfig } from 'services/api/types';
import { z } from 'zod';
export const zManualAddMode = z.enum(['diffusers', 'checkpoint']);
export type ManualAddMode = z.infer<typeof zManualAddMode>;
export const isManualAddMode = (v: unknown): v is ManualAddMode => zManualAddMode.safeParse(v).success;
export const AdvancedImport = () => { export const AdvancedImport = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();

View File

@ -9,23 +9,6 @@ import { memo, useMemo } from 'react';
import type { HandleType } from 'reactflow'; import type { HandleType } from 'reactflow';
import { Handle, Position } from 'reactflow'; import { Handle, Position } from 'reactflow';
export const handleBaseStyles: CSSProperties = {
position: 'absolute',
width: '1rem',
height: '1rem',
borderWidth: 0,
zIndex: 1,
};
``;
export const inputHandleStyles: CSSProperties = {
left: '-1rem',
};
export const outputHandleStyles: CSSProperties = {
right: '-0.5rem',
};
type FieldHandleProps = { type FieldHandleProps = {
fieldTemplate: FieldInputTemplate | FieldOutputTemplate; fieldTemplate: FieldInputTemplate | FieldOutputTemplate;
handleType: HandleType; handleType: HandleType;

View File

@ -1,34 +0,0 @@
import { Flex, forwardRef, Text } from '@invoke-ai/ui-library';
import { useFieldLabel } from 'features/nodes/hooks/useFieldLabel';
import { useFieldTemplateTitle } from 'features/nodes/hooks/useFieldTemplateTitle';
import { memo } from 'react';
interface Props {
nodeId: string;
fieldName: string;
kind: 'inputs' | 'outputs';
isMissingInput?: boolean;
}
const FieldTitle = forwardRef((props: Props, ref) => {
const { nodeId, fieldName, kind, isMissingInput = false } = props;
const label = useFieldLabel(nodeId, fieldName);
const fieldTemplateTitle = useFieldTemplateTitle(nodeId, fieldName, kind);
return (
<Flex
ref={ref}
position="relative"
overflow="hidden"
alignItems="center"
justifyContent="flex-start"
gap={1}
h="full"
w="full"
>
<Text fontWeight={isMissingInput ? 'bold' : 'normal'}>{label || fieldTemplateTitle}</Text>
</Flex>
);
});
export default memo(FieldTitle);

View File

@ -1,6 +1,6 @@
import { EMPTY_ARRAY } from "app/store/constants";
import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { EMPTY_ARRAY } from 'app/store/util';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice'; import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplate } from 'features/nodes/store/selectors'; import { selectNodeTemplate } from 'features/nodes/store/selectors';
import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames'; import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames';

View File

@ -1,17 +1,12 @@
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { DRAG_HANDLE_CLASSNAME, NODE_WIDTH } from 'features/nodes/types/constants'; import { NODE_WIDTH } from 'features/nodes/types/constants';
import type { AnyNode, InvocationTemplate } from 'features/nodes/types/invocation'; import type { AnyNode, InvocationTemplate } from 'features/nodes/types/invocation';
import { buildCurrentImageNode } from 'features/nodes/util/node/buildCurrentImageNode'; import { buildCurrentImageNode } from 'features/nodes/util/node/buildCurrentImageNode';
import { buildInvocationNode } from 'features/nodes/util/node/buildInvocationNode'; import { buildInvocationNode } from 'features/nodes/util/node/buildInvocationNode';
import { buildNotesNode } from 'features/nodes/util/node/buildNotesNode'; import { buildNotesNode } from 'features/nodes/util/node/buildNotesNode';
import { useCallback } from 'react'; import { useCallback } from 'react';
import type { Node } from 'reactflow';
import { useReactFlow } from 'reactflow'; import { useReactFlow } from 'reactflow';
export const SHARED_NODE_PROPERTIES: Partial<Node> = {
dragHandle: `.${DRAG_HANDLE_CLASSNAME}`,
};
export const useBuildNode = () => { export const useBuildNode = () => {
const nodeTemplates = useAppSelector((s) => s.nodes.templates); const nodeTemplates = useAppSelector((s) => s.nodes.templates);

View File

@ -1,6 +1,6 @@
import { EMPTY_ARRAY } from "app/store/constants";
import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { EMPTY_ARRAY } from 'app/store/util';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice'; import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplate } from 'features/nodes/store/selectors'; import { selectNodeTemplate } from 'features/nodes/store/selectors';
import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames'; import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames';

View File

@ -1,6 +1,6 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { EMPTY_ARRAY } from "app/store/constants";
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { EMPTY_ARRAY } from 'app/store/util';
import { selectNodesSlice } from 'features/nodes/store/nodesSlice'; import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
import { selectNodeTemplate } from 'features/nodes/store/selectors'; import { selectNodeTemplate } from 'features/nodes/store/selectors';
import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames'; import { getSortedFilteredFieldNames } from 'features/nodes/util/node/getSortedFilteredFieldNames';

View File

@ -2,10 +2,10 @@ import { createAction, isAnyOf } from '@reduxjs/toolkit';
import type { WorkflowV3 } from 'features/nodes/types/workflow'; import type { WorkflowV3 } from 'features/nodes/types/workflow';
import type { Graph } from 'services/api/types'; import type { Graph } from 'services/api/types';
export const textToImageGraphBuilt = createAction<Graph>('nodes/textToImageGraphBuilt'); const textToImageGraphBuilt = createAction<Graph>('nodes/textToImageGraphBuilt');
export const imageToImageGraphBuilt = createAction<Graph>('nodes/imageToImageGraphBuilt'); const imageToImageGraphBuilt = createAction<Graph>('nodes/imageToImageGraphBuilt');
export const canvasGraphBuilt = createAction<Graph>('nodes/canvasGraphBuilt'); export const canvasGraphBuilt = createAction<Graph>('nodes/canvasGraphBuilt');
export const nodesGraphBuilt = createAction<Graph>('nodes/nodesGraphBuilt'); const nodesGraphBuilt = createAction<Graph>('nodes/nodesGraphBuilt');
export const isAnyGraphBuilt = isAnyOf( export const isAnyGraphBuilt = isAnyOf(
textToImageGraphBuilt, textToImageGraphBuilt,

View File

@ -64,7 +64,6 @@ import {
getIncomers, getIncomers,
getOutgoers, getOutgoers,
SelectionMode, SelectionMode,
updateEdge,
} from 'reactflow'; } from 'reactflow';
import { import {
socketGeneratorProgress, socketGeneratorProgress,
@ -88,7 +87,7 @@ const initialNodeExecutionState: Omit<NodeExecutionState, 'nodeId'> = {
outputs: [], outputs: [],
}; };
export const initialNodesState: NodesState = { const initialNodesState: NodesState = {
_version: 1, _version: 1,
nodes: [], nodes: [],
edges: [], edges: [],
@ -215,10 +214,6 @@ export const nodesSlice = createSlice({
edgeAdded: (state, action: PayloadAction<Edge>) => { edgeAdded: (state, action: PayloadAction<Edge>) => {
state.edges = addEdge(action.payload, state.edges); state.edges = addEdge(action.payload, state.edges);
}, },
edgeUpdated: (state, action: PayloadAction<{ oldEdge: Edge; newConnection: Connection }>) => {
const { oldEdge, newConnection } = action.payload;
state.edges = updateEdge(oldEdge, newConnection, state.edges);
},
connectionStarted: (state, action: PayloadAction<OnConnectStartParams>) => { connectionStarted: (state, action: PayloadAction<OnConnectStartParams>) => {
state.connectionStartParams = action.payload; state.connectionStartParams = action.payload;
state.connectionMade = state.modifyingEdge; state.connectionMade = state.modifyingEdge;
@ -674,9 +669,6 @@ export const nodesSlice = createSlice({
state.connectionStartParams = null; state.connectionStartParams = null;
state.connectionStartFieldType = null; state.connectionStartFieldType = null;
}, },
addNodePopoverToggled: (state) => {
state.isAddNodePopoverOpen = !state.isAddNodePopoverOpen;
},
selectionModeChanged: (state, action: PayloadAction<boolean>) => { selectionModeChanged: (state, action: PayloadAction<boolean>) => {
state.selectionMode = action.payload ? SelectionMode.Full : SelectionMode.Partial; state.selectionMode = action.payload ? SelectionMode.Full : SelectionMode.Partial;
}, },
@ -762,7 +754,6 @@ export const nodesSlice = createSlice({
export const { export const {
addNodePopoverClosed, addNodePopoverClosed,
addNodePopoverOpened, addNodePopoverOpened,
addNodePopoverToggled,
connectionEnded, connectionEnded,
connectionMade, connectionMade,
connectionStarted, connectionStarted,
@ -770,7 +761,6 @@ export const {
edgeChangeStarted, edgeChangeStarted,
edgesChanged, edgesChanged,
edgesDeleted, edgesDeleted,
edgeUpdated,
fieldValueReset, fieldValueReset,
fieldBoardValueChanged, fieldBoardValueChanged,
fieldBooleanValueChanged, fieldBooleanValueChanged,
@ -824,7 +814,6 @@ export const isAnyNodeOrEdgeMutation = isAnyOf(
edgeDeleted, edgeDeleted,
edgesChanged, edgesChanged,
edgesDeleted, edgesDeleted,
edgeUpdated,
fieldBoardValueChanged, fieldBoardValueChanged,
fieldBooleanValueChanged, fieldBooleanValueChanged,
fieldColorValueChanged, fieldColorValueChanged,
@ -857,7 +846,7 @@ export const isAnyNodeOrEdgeMutation = isAnyOf(
export const selectNodesSlice = (state: RootState) => state.nodes; export const selectNodesSlice = (state: RootState) => state.nodes;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateNodesState = (state: any): any => { const migrateNodesState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -13,7 +13,7 @@ import { isInvocationNode } from 'features/nodes/types/invocation';
import type { WorkflowCategory, WorkflowV3 } from 'features/nodes/types/workflow'; import type { WorkflowCategory, WorkflowV3 } from 'features/nodes/types/workflow';
import { cloneDeep, isEqual, omit, uniqBy } from 'lodash-es'; import { cloneDeep, isEqual, omit, uniqBy } from 'lodash-es';
export const blankWorkflow: Omit<WorkflowV3, 'nodes' | 'edges'> = { const blankWorkflow: Omit<WorkflowV3, 'nodes' | 'edges'> = {
name: '', name: '',
author: '', author: '',
description: '', description: '',
@ -26,7 +26,7 @@ export const blankWorkflow: Omit<WorkflowV3, 'nodes' | 'edges'> = {
id: undefined, id: undefined,
}; };
export const initialWorkflowState: WorkflowState = { const initialWorkflowState: WorkflowState = {
_version: 1, _version: 1,
isTouched: false, isTouched: false,
mode: 'view', mode: 'view',
@ -195,7 +195,7 @@ export const {
export const selectWorkflowSlice = (state: RootState) => state.workflow; export const selectWorkflowSlice = (state: RootState) => state.workflow;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
export const migrateWorkflowState = (state: any): any => { const migrateWorkflowState = (state: any): any => {
if (!('_version' in state)) { if (!('_version' in state)) {
state._version = 1; state._version = 1;
} }

View File

@ -2,17 +2,11 @@ import type {
BaseModel, BaseModel,
BoardField, BoardField,
Classification, Classification,
CLIPField,
ColorField, ColorField,
ControlField, ControlField,
ControlNetModelField,
ImageField, ImageField,
ImageOutput, ImageOutput,
IPAdapterField, IPAdapterField,
IPAdapterModelField,
LoraInfo,
LoRAModelField,
MainModelField,
ModelInfo, ModelInfo,
ModelType, ModelType,
ProgressImage, ProgressImage,
@ -20,8 +14,6 @@ import type {
SDXLRefinerModelField, SDXLRefinerModelField,
SubModelType, SubModelType,
T2IAdapterField, T2IAdapterField,
T2IAdapterModelField,
UNetField,
VAEField, VAEField,
} from 'features/nodes/types/common'; } from 'features/nodes/types/common';
import type { S } from 'services/api/types'; import type { S } from 'services/api/types';
@ -40,19 +32,17 @@ describe('Common types', () => {
test('BoardField', () => assert<Equals<BoardField, S['BoardField']>>()); test('BoardField', () => assert<Equals<BoardField, S['BoardField']>>());
test('ColorField', () => assert<Equals<ColorField, S['ColorField']>>()); test('ColorField', () => assert<Equals<ColorField, S['ColorField']>>());
test('SchedulerField', () => assert<Equals<SchedulerField, NonNullable<S['SchedulerInvocation']['scheduler']>>>()); test('SchedulerField', () => assert<Equals<SchedulerField, NonNullable<S['SchedulerInvocation']['scheduler']>>>());
test('UNetField', () => assert<Extends<S['UNetField'], UNetField>>()); // test('MainModelField', () => assert<Equals<MainModelField, S['MainModelField']>>());
test('CLIPField', () => assert<Extends<S['ClipField'], CLIPField>>());
test('MainModelField', () => assert<Equals<MainModelField, S['MainModelField']>>());
test('SDXLRefinerModelField', () => assert<Equals<SDXLRefinerModelField, S['MainModelField']>>()); test('SDXLRefinerModelField', () => assert<Equals<SDXLRefinerModelField, S['MainModelField']>>());
test('VAEField', () => assert<Extends<S['VaeField'], VAEField>>()); test('VAEField', () => assert<Extends<S['VaeField'], VAEField>>());
test('ControlField', () => assert<Equals<ControlField, S['ControlField']>>()); test('ControlField', () => assert<Equals<ControlField, S['ControlField']>>());
// @ts-expect-error TODO(psyche): fix types // @ts-expect-error TODO(psyche): fix types
test('IPAdapterField', () => assert<Extends<IPAdapterField, S['IPAdapterField']>>()); test('IPAdapterField', () => assert<Extends<IPAdapterField, S['IPAdapterField']>>());
test('T2IAdapterField', () => assert<Equals<T2IAdapterField, S['T2IAdapterField']>>()); test('T2IAdapterField', () => assert<Equals<T2IAdapterField, S['T2IAdapterField']>>());
test('LoRAModelField', () => assert<Equals<LoRAModelField, S['LoRAModelField']>>()); // test('LoRAModelField', () => assert<Equals<LoRAModelField, S['LoRAModelField']>>());
test('ControlNetModelField', () => assert<Equals<ControlNetModelField, S['ControlNetModelField']>>()); // test('ControlNetModelField', () => assert<Equals<ControlNetModelField, S['ControlNetModelField']>>());
test('IPAdapterModelField', () => assert<Equals<IPAdapterModelField, S['IPAdapterModelField']>>()); // test('IPAdapterModelField', () => assert<Equals<IPAdapterModelField, S['IPAdapterModelField']>>());
test('T2IAdapterModelField', () => assert<Equals<T2IAdapterModelField, S['T2IAdapterModelField']>>()); // test('T2IAdapterModelField', () => assert<Equals<T2IAdapterModelField, S['T2IAdapterModelField']>>());
// Model component types // Model component types
test('BaseModel', () => assert<Equals<BaseModel, S['BaseModelType']>>()); test('BaseModel', () => assert<Equals<BaseModel, S['BaseModelType']>>());
@ -61,7 +51,6 @@ describe('Common types', () => {
test('ModelInfo', () => assert<Equals<ModelInfo, S['ModelInfo']>>()); test('ModelInfo', () => assert<Equals<ModelInfo, S['ModelInfo']>>());
// Misc types // Misc types
test('LoraInfo', () => assert<Extends<S['LoraInfo'], LoraInfo>>());
// @ts-expect-error TODO(psyche): There is no `ProgressImage` in the server types yet // @ts-expect-error TODO(psyche): There is no `ProgressImage` in the server types yet
test('ProgressImage', () => assert<Equals<ProgressImage, S['ProgressImage']>>()); test('ProgressImage', () => assert<Equals<ProgressImage, S['ProgressImage']>>());
test('ImageOutput', () => assert<Equals<ImageOutput, S['ImageOutput']>>()); test('ImageOutput', () => assert<Equals<ImageOutput, S['ImageOutput']>>());

View File

@ -102,7 +102,7 @@ export type SubModelType = z.infer<typeof zSubModelType>;
export const zVAEModelField = zModelIdentifierWithBase; export const zVAEModelField = zModelIdentifierWithBase;
export const zModelInfo = zModelIdentifier.extend({ const zModelInfo = zModelIdentifier.extend({
submodel_type: zSubModelType.nullish(), submodel_type: zSubModelType.nullish(),
}); });
export type ModelInfo = z.infer<typeof zModelInfo>; export type ModelInfo = z.infer<typeof zModelInfo>;
@ -119,26 +119,6 @@ export type IPAdapterModelField = z.infer<typeof zIPAdapterModelField>;
export const zT2IAdapterModelField = zModelIdentifierWithBase; export const zT2IAdapterModelField = zModelIdentifierWithBase;
export type T2IAdapterModelField = z.infer<typeof zT2IAdapterModelField>; export type T2IAdapterModelField = z.infer<typeof zT2IAdapterModelField>;
export const zLoraInfo = zModelInfo.extend({
weight: z.number().optional(),
});
export type LoraInfo = z.infer<typeof zLoraInfo>;
export const zUNetField = z.object({
unet: zModelInfo,
scheduler: zModelInfo,
loras: z.array(zLoraInfo),
});
export type UNetField = z.infer<typeof zUNetField>;
export const zCLIPField = z.object({
tokenizer: zModelInfo,
text_encoder: zModelInfo,
skipped_layers: z.number(),
loras: z.array(zLoraInfo),
});
export type CLIPField = z.infer<typeof zCLIPField>;
export const zVAEField = z.object({ export const zVAEField = z.object({
vae: zModelInfo, vae: zModelInfo,
}); });

View File

@ -67,5 +67,3 @@ export const ClearQueueIconButton = (props: ClearQueueButtonProps) => {
</> </>
); );
}; };
export default ClearQueueIconButton;

View File

@ -1,5 +1,5 @@
import { ButtonGroup, Flex, Spacer } from '@invoke-ai/ui-library'; import { ButtonGroup, Flex, Spacer } from '@invoke-ai/ui-library';
import ClearQueueIconButton from 'features/queue/components/ClearQueueIconButton'; import { ClearQueueIconButton } from 'features/queue/components/ClearQueueIconButton';
import QueueFrontButton from 'features/queue/components/QueueFrontButton'; import QueueFrontButton from 'features/queue/components/QueueFrontButton';
import ProgressBar from 'features/system/components/ProgressBar'; import ProgressBar from 'features/system/components/ProgressBar';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';

View File

@ -10,9 +10,9 @@ import {
TabPanels, TabPanels,
Tabs, Tabs,
} from '@invoke-ai/ui-library'; } from '@invoke-ai/ui-library';
import { EMPTY_ARRAY } from "app/store/constants";
import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { EMPTY_ARRAY } from 'app/store/util';
import { LoRAList } from 'features/lora/components/LoRAList'; import { LoRAList } from 'features/lora/components/LoRAList';
import LoRASelect from 'features/lora/components/LoRASelect'; import LoRASelect from 'features/lora/components/LoRASelect';
import { selectLoraSlice } from 'features/lora/store/loraSlice'; import { selectLoraSlice } from 'features/lora/store/loraSlice';