mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
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:
parent
5e83fc8ac7
commit
45546fdcea
@ -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",
|
||||||
|
@ -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:
|
||||||
|
@ -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',
|
|
||||||
},
|
|
||||||
};
|
|
@ -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));
|
||||||
|
|
||||||
|
@ -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');
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
export const STORAGE_PREFIX = '@@invokeai-';
|
export const STORAGE_PREFIX = '@@invokeai-';
|
||||||
|
export const EMPTY_ARRAY = [];
|
||||||
|
@ -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,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
@ -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>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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,
|
||||||
|
@ -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.
|
||||||
|
@ -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}"`);
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
export const EMPTY_ARRAY = [];
|
|
||||||
export const EMPTY_OBJECT = {};
|
|
@ -1 +0,0 @@
|
|||||||
export const Nbsp = () => <>{'\u00A0'}</>;
|
|
@ -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];
|
|
||||||
};
|
|
@ -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';
|
||||||
|
@ -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);
|
|
||||||
|
@ -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));
|
|
||||||
};
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import type { MouseEvent } from 'react';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents the default behavior of the event.
|
|
||||||
*/
|
|
||||||
export const skipMouseEvent = (e: MouseEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
import type { ClipboardEvent } from 'react';
|
|
||||||
|
|
||||||
export const stopPastePropagation = (e: ClipboardEvent) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
};
|
|
@ -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,
|
||||||
|
@ -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)
|
|
||||||
);
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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})`;
|
|
||||||
};
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
|
@ -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;
|
|
||||||
};
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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');
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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>;
|
||||||
/**
|
/**
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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';
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
@ -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';
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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';
|
||||||
|
@ -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';
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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']>>());
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
|
@ -67,5 +67,3 @@ export const ClearQueueIconButton = (props: ClearQueueButtonProps) => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ClearQueueIconButton;
|
|
||||||
|
@ -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';
|
||||||
|
@ -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';
|
||||||
|
Loading…
Reference in New Issue
Block a user