From c5147d0f57e60893d5fb7eb2694f2e6240e0628d Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 22 Jul 2023 23:26:14 +1000 Subject: [PATCH] fix(ui): fix all eslint & prettier issues --- invokeai/frontend/web/.prettierignore | 4 + .../frontend/web/src/app/logging/useLogger.ts | 2 + .../enhancers/reduxRemember/unserialize.ts | 2 +- .../addFirstListImagesListener.ts.ts | 2 +- .../listeners/appStarted.ts | 5 +- .../listeners/boardAndImagesDeleted.ts | 4 +- .../listeners/canvasMerged.ts | 2 +- .../listeners/canvasSavedToGallery.ts | 2 +- .../listeners/controlNetAutoProcess.ts | 5 +- .../listeners/controlNetImageProcessed.ts | 7 +- .../listeners/imageAddedToBoard.ts | 4 +- .../listeners/imageDeleted.ts | 8 +- .../listeners/imageDropped.ts | 2 +- .../listeners/imageRemovedFromBoard.ts | 4 +- .../listeners/imageToDeleteSelected.ts | 2 +- .../listeners/imageUploaded.ts | 11 +- .../listeners/initialImageSelected.ts | 2 +- .../listeners/modelsLoaded.ts | 6 +- .../listeners/receivedOpenAPISchema.ts | 6 +- .../listeners/sessionCanceled.ts | 7 +- .../listeners/sessionCreated.ts | 9 +- .../listeners/sessionInvoked.ts | 9 +- .../listeners/socketio/socketDisconnected.ts | 2 +- .../socketGraphExecutionStateComplete.ts | 2 +- .../socketio/socketInvocationComplete.ts | 2 +- .../socketio/socketInvocationError.ts | 2 +- .../listeners/socketio/socketModelLoad.ts | 13 +- .../listeners/socketio/socketSubscribed.ts | 2 +- .../listeners/socketio/socketUnsubscribed.ts | 2 +- .../listeners/stagingAreaImageSaved.ts | 4 +- .../listeners/upscaleRequested.ts | 5 +- invokeai/frontend/web/src/app/store/store.ts | 2 +- .../src/common/components/IAIDroppable.tsx | 3 +- .../IAIMantineSelectItemWithTooltip.tsx | 5 +- .../web/src/common/components/IAISlider.tsx | 6 +- .../features/canvas/components/IAICanvas.tsx | 4 +- .../src/features/canvas/store/canvasSlice.ts | 26 +-- .../components/ControlNetImagePreview.tsx | 20 +-- .../parameters/ParamControlNetBeginEnd.tsx | 5 - .../parameters/ParamControlNetControlMode.tsx | 3 - .../ParamControlNetProcessorSelect.tsx | 1 - .../parameters/ParamControlNetResizeMode.tsx | 3 - .../processors/ZoeDepthProcessor.tsx | 2 +- .../controlNet/store/controlNetSlice.ts | 4 +- .../components/Boards/BoardContextMenu.tsx | 22 +-- .../Boards/BoardsList/BoardsList.tsx | 10 +- .../Boards/BoardsList/GalleryBoard.tsx | 11 +- .../Boards/BoardsList/NoBoardBoard.tsx | 9 +- .../Boards/GalleryBoardContextMenuItems.tsx | 39 +---- .../Boards/NoBoardContextMenuItems.tsx | 15 +- .../CurrentImage/CurrentImageButtons.tsx | 2 +- .../CurrentImage/CurrentImagePreview.tsx | 11 +- .../components/ImageGalleryContent.tsx | 8 +- .../components/ImageGrid/BatchImage.tsx | 36 ++--- .../components/ImageGrid/GalleryImage.tsx | 26 ++- .../features/gallery/store/gallerySlice.ts | 68 ++++---- .../fields/ArrayInputFieldComponent.tsx | 4 +- .../fields/ClipInputFieldComponent.tsx | 4 +- .../ConditioningInputFieldComponent.tsx | 4 +- .../fields/ControlInputFieldComponent.tsx | 4 +- .../ControlNetModelInputFieldComponent.tsx | 2 - .../ImageCollectionInputFieldComponent.tsx | 59 +++---- .../fields/ImageInputFieldComponent.tsx | 27 ++-- .../fields/ItemInputFieldComponent.tsx | 4 +- .../fields/LatentsInputFieldComponent.tsx | 4 +- .../fields/UnetInputFieldComponent.tsx | 3 +- .../fields/VaeInputFieldComponent.tsx | 3 +- .../fields/VaeModelInputFieldComponent.tsx | 2 - .../nodes/components/search/NodeSearch.tsx | 13 +- .../nodes/hooks/useIsValidConnection.ts | 153 +++++++++--------- .../nodes/util/fieldTemplateBuilders.ts | 4 + .../util/graphBuilders/buildNodesGraph.ts | 6 +- .../src/features/nodes/util/parseSchema.ts | 2 + .../ControlNet/ParamControlNetCollapse.tsx | 2 - .../components/Parameters/Core/ParamWidth.tsx | 2 +- .../Parameters/ImageToImage/InitialImage.tsx | 9 +- .../Parameters/Noise/ParamCpuNoise.tsx | 3 - .../Parameters/Noise/ParamNoiseToggle.tsx | 3 - .../Upscale/ParamRealESRGANModel.tsx | 1 - .../Variations/ParamVariationToggle.tsx | 3 - .../_ImageDimensions/AspectRatioPreview.tsx | 75 --------- .../_ImageDimensions/DimensionsSettings.tsx | 76 --------- .../parameters/hooks/useRecallParameters.ts | 1 - .../parameters/store/generationSlice.ts | 2 +- .../util/modelIdToControlNetModelParam.ts | 2 +- .../util/modelIdToLoRAModelParam.ts | 2 +- .../util/modelIdToMainModelParam.ts | 2 +- .../parameters/util/modelIdToVAEModelParam.ts | 2 +- .../system/components/StatusIndicator.tsx | 9 +- .../ui/components/ParametersPinnedWrapper.tsx | 1 - .../ImageToImageTabCoreParameters.tsx | 7 +- invokeai/frontend/web/src/i18n.ts | 3 +- .../services/events/util/setEventListeners.ts | 4 +- .../web/src/theme/components/button.ts | 8 +- .../web/src/theme/components/modal.ts | 8 +- 95 files changed, 333 insertions(+), 670 deletions(-) delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/AspectRatioPreview.tsx delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/DimensionsSettings.tsx diff --git a/invokeai/frontend/web/.prettierignore b/invokeai/frontend/web/.prettierignore index b351fc6a96..b23772e167 100644 --- a/invokeai/frontend/web/.prettierignore +++ b/invokeai/frontend/web/.prettierignore @@ -5,6 +5,10 @@ patches/ stats.html index.html .yarn/ +.yalc/ *.scss src/services/api/ src/services/fixtures/* +docs/ +static/ +src/theme/css/overlayscrollbars.css diff --git a/invokeai/frontend/web/src/app/logging/useLogger.ts b/invokeai/frontend/web/src/app/logging/useLogger.ts index 13c62edcd3..6c60bd4fd0 100644 --- a/invokeai/frontend/web/src/app/logging/useLogger.ts +++ b/invokeai/frontend/web/src/app/logging/useLogger.ts @@ -48,6 +48,8 @@ export const useLogger = () => { // Update the module-scoped logger context as needed useEffect(() => { + // TODO: type this properly + //eslint-disable-next-line @typescript-eslint/no-explicit-any const newContext: Record = { ...BASE_CONTEXT, }; diff --git a/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/unserialize.ts b/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/unserialize.ts index 5d94abd738..159952d654 100644 --- a/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/unserialize.ts +++ b/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/unserialize.ts @@ -12,7 +12,7 @@ import { defaultsDeep } from 'lodash-es'; import { UnserializeFunction } from 'redux-remember'; const initialStates: { - [key: string]: any; + [key: string]: object; // TODO: type this properly } = { canvas: initialCanvasState, gallery: initialGalleryState, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts index 315dd2f5f9..ee12f39a12 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts.ts @@ -15,7 +15,7 @@ export const addFirstListImagesListener = () => { matcher: imagesApi.endpoints.listImages.matchFulfilled, effect: async ( action, - { getState, dispatch, unsubscribe, cancelActiveListeners } + { dispatch, unsubscribe, cancelActiveListeners } ) => { // Only run this listener on the first listImages request for no-board images if ( diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appStarted.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appStarted.ts index cfe9fd4a1c..189a5a3530 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appStarted.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appStarted.ts @@ -6,10 +6,7 @@ export const appStarted = createAction('app/appStarted'); export const addAppStartedListener = () => { startAppListening({ actionCreator: appStarted, - effect: async ( - action, - { getState, dispatch, unsubscribe, cancelActiveListeners } - ) => { + effect: async (action, { unsubscribe, cancelActiveListeners }) => { // this should only run once cancelActiveListeners(); unsubscribe(); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts index 5320846e15..f0af52ced6 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts @@ -9,8 +9,8 @@ import { boardsApi } from '../../../../../services/api/endpoints/boards'; export const addDeleteBoardAndImagesFulfilledListener = () => { startAppListening({ matcher: boardsApi.endpoints.deleteBoardAndImages.matchFulfilled, - effect: async (action, { dispatch, getState, condition }) => { - const { board_id, deleted_board_images, deleted_images } = action.payload; + effect: async (action, { dispatch, getState }) => { + const { deleted_images } = action.payload; // Remove all deleted images from the UI diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts index c55eb7bc2b..21c506242d 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts @@ -10,7 +10,7 @@ import { startAppListening } from '..'; export const addCanvasMergedListener = () => { startAppListening({ actionCreator: canvasMerged, - effect: async (action, { dispatch, getState, take }) => { + effect: async (action, { dispatch }) => { const moduleLog = $logger .get() .child({ namespace: 'canvasCopiedToClipboardListener' }); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts index 8e7dc0c8ea..47f7aded27 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts @@ -8,7 +8,7 @@ import { startAppListening } from '..'; export const addCanvasSavedToGalleryListener = () => { startAppListening({ actionCreator: canvasSavedToGallery, - effect: async (action, { dispatch, getState, take }) => { + effect: async (action, { dispatch, getState }) => { const log = logger('canvas'); const state = getState(); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts index 3aa01d54cb..4a47e8d64e 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess.ts @@ -62,10 +62,7 @@ const predicate: AnyListenerPredicate = ( export const addControlNetAutoProcessListener = () => { startAppListening({ predicate, - effect: async ( - action, - { dispatch, getState, cancelActiveListeners, delay } - ) => { + effect: async (action, { dispatch, cancelActiveListeners, delay }) => { const log = logger('session'); const { controlNetId } = action.payload; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts index 830585154c..313b2a02d8 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed.ts @@ -1,4 +1,4 @@ -import { $logger, logger } from 'app/logging/logger'; +import { logger } from 'app/logging/logger'; import { controlNetImageProcessed } from 'features/controlNet/store/actions'; import { controlNetProcessedImageChanged } from 'features/controlNet/store/controlNetSlice'; import { sessionReadyToInvoke } from 'features/system/store/actions'; @@ -12,10 +12,7 @@ import { startAppListening } from '..'; export const addControlNetImageProcessedListener = () => { startAppListening({ actionCreator: controlNetImageProcessed, - effect: async ( - action, - { dispatch, getState, take, unsubscribe, subscribe } - ) => { + effect: async (action, { dispatch, getState, take }) => { const log = logger('session'); const { controlNetId } = action.payload; const controlNet = getState().controlNet.controlNets[controlNetId]; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageAddedToBoard.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageAddedToBoard.ts index eab627b3f4..039cbb657a 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageAddedToBoard.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageAddedToBoard.ts @@ -5,7 +5,7 @@ import { startAppListening } from '..'; export const addImageAddedToBoardFulfilledListener = () => { startAppListening({ matcher: imagesApi.endpoints.addImageToBoard.matchFulfilled, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('images'); const { board_id, imageDTO } = action.meta.arg.originalArgs; @@ -19,7 +19,7 @@ export const addImageAddedToBoardFulfilledListener = () => { export const addImageAddedToBoardRejectedListener = () => { startAppListening({ matcher: imagesApi.endpoints.addImageToBoard.matchRejected, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('images'); const { board_id, imageDTO } = action.meta.arg.originalArgs; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts index 2643a461d7..428ce53219 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDeleted.ts @@ -19,7 +19,6 @@ export const addRequestedImageDeletionListener = () => { startAppListening({ actionCreator: imageDeletionConfirmed, effect: async (action, { dispatch, getState, condition }) => { - const log = logger('images'); const { imageDTO, imageUsage } = action.payload; dispatch(isModalOpenChanged(false)); @@ -104,8 +103,7 @@ export const addRequestedImageDeletionListener = () => { export const addImageDeletedPendingListener = () => { startAppListening({ matcher: imagesApi.endpoints.deleteImage.matchPending, - effect: (action, { dispatch, getState }) => { - const log = logger('images'); + effect: () => { // }, }); @@ -117,7 +115,7 @@ export const addImageDeletedPendingListener = () => { export const addImageDeletedFulfilledListener = () => { startAppListening({ matcher: imagesApi.endpoints.deleteImage.matchFulfilled, - effect: (action, { dispatch, getState }) => { + effect: (action) => { const log = logger('images'); log.debug({ imageDTO: action.meta.arg.originalArgs }, 'Image deleted'); }, @@ -130,7 +128,7 @@ export const addImageDeletedFulfilledListener = () => { export const addImageDeletedRejectedListener = () => { startAppListening({ matcher: imagesApi.endpoints.deleteImage.matchRejected, - effect: (action, { dispatch, getState }) => { + effect: (action) => { const log = logger('images'); log.debug( { imageDTO: action.meta.arg.originalArgs }, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts index 296bd0b953..fdf0849a12 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageDropped.ts @@ -23,7 +23,7 @@ export const dndDropped = createAction<{ export const addImageDroppedListener = () => { startAppListening({ actionCreator: dndDropped, - effect: async (action, { dispatch, getState, take }) => { + effect: async (action, { dispatch }) => { const log = logger('images'); const { activeData, overData } = action.payload; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageRemovedFromBoard.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageRemovedFromBoard.ts index 33c8dd5372..a8bf0e6791 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageRemovedFromBoard.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageRemovedFromBoard.ts @@ -5,7 +5,7 @@ import { startAppListening } from '..'; export const addImageRemovedFromBoardFulfilledListener = () => { startAppListening({ matcher: imagesApi.endpoints.removeImageFromBoard.matchFulfilled, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('images'); const imageDTO = action.meta.arg.originalArgs; @@ -17,7 +17,7 @@ export const addImageRemovedFromBoardFulfilledListener = () => { export const addImageRemovedFromBoardRejectedListener = () => { startAppListening({ matcher: imagesApi.endpoints.removeImageFromBoard.matchRejected, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('images'); const imageDTO = action.meta.arg.originalArgs; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts index 646cd259ad..3a5eed95db 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected.ts @@ -9,7 +9,7 @@ import { startAppListening } from '..'; export const addImageToDeleteSelectedListener = () => { startAppListening({ actionCreator: imageToDeleteSelected, - effect: async (action, { dispatch, getState, condition }) => { + effect: async (action, { dispatch, getState }) => { const imageDTO = action.payload; const state = getState(); const { shouldConfirmOnDelete } = state.system; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts index 40c2209077..dd581d893c 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts @@ -9,6 +9,7 @@ import { addToast } from 'features/system/store/systemSlice'; import { boardsApi } from 'services/api/endpoints/boards'; import { startAppListening } from '..'; import { imagesApi } from '../../../../../services/api/endpoints/images'; +import { omit } from 'lodash-es'; const DEFAULT_UPLOADED_TOAST: UseToastOptions = { title: 'Image Uploaded', @@ -22,7 +23,7 @@ export const addImageUploadedFulfilledListener = () => { const log = logger('images'); const imageDTO = action.payload; const state = getState(); - const { selectedBoardId, autoAddBoardId } = state.gallery; + const { autoAddBoardId } = state.gallery; log.debug({ imageDTO }, 'Image uploaded'); @@ -140,8 +141,12 @@ export const addImageUploadedRejectedListener = () => { matcher: imagesApi.endpoints.uploadImage.matchRejected, effect: (action, { dispatch }) => { const log = logger('images'); - const { file, postUploadAction, ...rest } = action.meta.arg.originalArgs; - const sanitizedData = { arg: { ...rest, file: '' } }; + const sanitizedData = { + arg: { + ...omit(action.meta.arg.originalArgs, ['file', 'postUploadAction']), + file: '', + }, + }; log.error({ ...sanitizedData }, 'Image upload failed'); dispatch( addToast({ diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts index 17a52f2bfc..7748ca6fe5 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/initialImageSelected.ts @@ -8,7 +8,7 @@ import { startAppListening } from '..'; export const addInitialImageSelectedListener = () => { startAppListening({ actionCreator: initialImageSelected, - effect: (action, { getState, dispatch }) => { + effect: (action, { dispatch }) => { if (!action.payload) { dispatch( addToast( diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts index 131898695a..57981918d8 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts @@ -1,4 +1,5 @@ -import { $logger, logger } from 'app/logging/logger'; +import { logger } from 'app/logging/logger'; +import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice'; import { loraRemoved } from 'features/lora/store/loraSlice'; import { modelChanged, @@ -11,7 +12,6 @@ import { import { forEach, some } from 'lodash-es'; import { modelsApi } from 'services/api/endpoints/models'; import { startAppListening } from '..'; -import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice'; export const addModelsLoadedListener = () => { startAppListening({ @@ -167,7 +167,7 @@ export const addModelsLoadedListener = () => { }); startAppListening({ matcher: modelsApi.endpoints.getTextualInversionModels.matchFulfilled, - effect: async (action, { getState, dispatch }) => { + effect: async (action) => { const log = logger('models'); log.info( { models: action.payload.entities }, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts index e9bf690a27..44729f215a 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/receivedOpenAPISchema.ts @@ -1,15 +1,15 @@ import { logger } from 'app/logging/logger'; +import { parseify } from 'common/util/serialize'; import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice'; import { parseSchema } from 'features/nodes/util/parseSchema'; import { size } from 'lodash-es'; import { receivedOpenAPISchema } from 'services/api/thunks/schema'; import { startAppListening } from '..'; -import { parseify } from 'common/util/serialize'; export const addReceivedOpenAPISchemaListener = () => { startAppListening({ actionCreator: receivedOpenAPISchema.fulfilled, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('system'); const schemaJSON = action.payload; @@ -28,7 +28,7 @@ export const addReceivedOpenAPISchemaListener = () => { startAppListening({ actionCreator: receivedOpenAPISchema.rejected, - effect: (action, { dispatch, getState }) => { + effect: () => { const log = logger('system'); log.error('Problem dereferencing OpenAPI Schema'); }, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCanceled.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCanceled.ts index 2bc4ecad39..2592437348 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCanceled.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCanceled.ts @@ -6,8 +6,7 @@ import { startAppListening } from '..'; export const addSessionCanceledPendingListener = () => { startAppListening({ actionCreator: sessionCanceled.pending, - effect: (action, { getState, dispatch }) => { - const log = logger('session'); + effect: () => { // }, }); @@ -16,7 +15,7 @@ export const addSessionCanceledPendingListener = () => { export const addSessionCanceledFulfilledListener = () => { startAppListening({ actionCreator: sessionCanceled.fulfilled, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('session'); const { session_id } = action.meta.arg; log.debug({ session_id }, `Session canceled (${session_id})`); @@ -27,7 +26,7 @@ export const addSessionCanceledFulfilledListener = () => { export const addSessionCanceledRejectedListener = () => { startAppListening({ actionCreator: sessionCanceled.rejected, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('session'); const { session_id } = action.meta.arg; if (action.payload) { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts index eeaf725818..5709d87d22 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts @@ -7,8 +7,7 @@ import { startAppListening } from '..'; export const addSessionCreatedPendingListener = () => { startAppListening({ actionCreator: sessionCreated.pending, - effect: (action, { getState, dispatch }) => { - const log = logger('session'); + effect: () => { // }, }); @@ -17,7 +16,7 @@ export const addSessionCreatedPendingListener = () => { export const addSessionCreatedFulfilledListener = () => { startAppListening({ actionCreator: sessionCreated.fulfilled, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('session'); const session = action.payload; log.debug( @@ -31,10 +30,10 @@ export const addSessionCreatedFulfilledListener = () => { export const addSessionCreatedRejectedListener = () => { startAppListening({ actionCreator: sessionCreated.rejected, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('session'); if (action.payload) { - const { arg, error } = action.payload; + const { error } = action.payload; const graph = parseify(action.meta.arg); const stringifiedError = JSON.stringify(error); log.error( diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionInvoked.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionInvoked.ts index 1c73f17444..60009ed194 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionInvoked.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionInvoked.ts @@ -6,8 +6,7 @@ import { startAppListening } from '..'; export const addSessionInvokedPendingListener = () => { startAppListening({ actionCreator: sessionInvoked.pending, - effect: (action, { getState, dispatch }) => { - const log = logger('session'); + effect: () => { // }, }); @@ -16,7 +15,7 @@ export const addSessionInvokedPendingListener = () => { export const addSessionInvokedFulfilledListener = () => { startAppListening({ actionCreator: sessionInvoked.fulfilled, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('session'); const { session_id } = action.meta.arg; log.debug({ session_id }, `Session invoked (${session_id})`); @@ -27,11 +26,11 @@ export const addSessionInvokedFulfilledListener = () => { export const addSessionInvokedRejectedListener = () => { startAppListening({ actionCreator: sessionInvoked.rejected, - effect: (action, { getState, dispatch }) => { + effect: (action) => { const log = logger('session'); const { session_id } = action.meta.arg; if (action.payload) { - const { arg, error } = action.payload; + const { error } = action.payload; const stringifiedError = JSON.stringify(error); log.error( { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketDisconnected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketDisconnected.ts index cce2bbf52a..dfbdd25595 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketDisconnected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketDisconnected.ts @@ -8,7 +8,7 @@ import { startAppListening } from '../..'; export const addSocketDisconnectedEventListener = () => { startAppListening({ actionCreator: socketDisconnected, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('socketio'); log.debug('Disconnected'); // pass along the socket event as an application action diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketGraphExecutionStateComplete.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketGraphExecutionStateComplete.ts index 98a581ea1f..23ab9a8cb3 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketGraphExecutionStateComplete.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketGraphExecutionStateComplete.ts @@ -8,7 +8,7 @@ import { startAppListening } from '../..'; export const addGraphExecutionStateCompleteEventListener = () => { startAppListening({ actionCreator: socketGraphExecutionStateComplete, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('socketio'); log.debug(action.payload, 'Session complete'); // pass along the socket event as an application action diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts index 174a7de075..e36c49be63 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete.ts @@ -22,7 +22,7 @@ const nodeDenylist = ['dataURL_image']; export const addInvocationCompleteEventListener = () => { startAppListening({ actionCreator: socketInvocationComplete, - effect: async (action, { dispatch, getState, take }) => { + effect: async (action, { dispatch, getState }) => { const log = logger('socketio'); const { data } = action.payload; log.debug( diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts index d40ff1e944..ce15b8398c 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError.ts @@ -8,7 +8,7 @@ import { startAppListening } from '../..'; export const addInvocationErrorEventListener = () => { startAppListening({ actionCreator: socketInvocationError, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('socketio'); log.error( action.payload, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts index f221485c1f..0f3fabbc1e 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad.ts @@ -1,5 +1,4 @@ import { logger } from 'app/logging/logger'; -import { ModelType } from 'services/api/types'; import { appSocketModelLoadCompleted, appSocketModelLoadStarted, @@ -8,18 +7,10 @@ import { } from 'services/events/actions'; import { startAppListening } from '../..'; -const MODEL_TYPES: Record = { - main: 'main', - vae: 'VAE', - lora: 'LoRA', - controlnet: 'ControlNet', - embedding: 'embedding', -}; - export const addModelLoadEventListener = () => { startAppListening({ actionCreator: socketModelLoadStarted, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('socketio'); const { base_model, model_name, model_type, submodel } = action.payload.data; @@ -39,7 +30,7 @@ export const addModelLoadEventListener = () => { startAppListening({ actionCreator: socketModelLoadCompleted, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('socketio'); const { base_model, model_name, model_type, submodel } = action.payload.data; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSubscribed.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSubscribed.ts index c01d6e915f..a05527790e 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSubscribed.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketSubscribed.ts @@ -5,7 +5,7 @@ import { startAppListening } from '../..'; export const addSocketSubscribedEventListener = () => { startAppListening({ actionCreator: socketSubscribed, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('socketio'); log.debug(action.payload, 'Subscribed'); dispatch(appSocketSubscribed(action.payload)); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketUnsubscribed.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketUnsubscribed.ts index d8baa2cf27..a8076ee1b7 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketUnsubscribed.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/socketio/socketUnsubscribed.ts @@ -8,7 +8,7 @@ import { startAppListening } from '../..'; export const addSocketUnsubscribedEventListener = () => { startAppListening({ actionCreator: socketUnsubscribed, - effect: (action, { dispatch, getState }) => { + effect: (action, { dispatch }) => { const log = logger('socketio'); log.debug(action.payload, 'Unsubscribed'); dispatch(appSocketUnsubscribed(action.payload)); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/stagingAreaImageSaved.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/stagingAreaImageSaved.ts index 5aea377624..a6818acbe0 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/stagingAreaImageSaved.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/stagingAreaImageSaved.ts @@ -1,4 +1,3 @@ -import { logger } from 'app/logging/logger'; import { stagingAreaImageSaved } from 'features/canvas/store/actions'; import { addToast } from 'features/system/store/systemSlice'; import { imagesApi } from 'services/api/endpoints/images'; @@ -7,8 +6,7 @@ import { startAppListening } from '..'; export const addStagingAreaImageSavedListener = () => { startAppListening({ actionCreator: stagingAreaImageSaved, - effect: async (action, { dispatch, getState, take }) => { - const log = logger('canvas'); + effect: async (action, { dispatch, getState }) => { const { imageDTO } = action.payload; try { diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts index df597a3b62..75980a65e4 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/upscaleRequested.ts @@ -11,10 +11,7 @@ export const upscaleRequested = createAction<{ image_name: string }>( export const addUpscaleRequestedListener = () => { startAppListening({ actionCreator: upscaleRequested, - effect: async ( - action, - { dispatch, getState, take, unsubscribe, subscribe } - ) => { + effect: async (action, { dispatch, getState, take }) => { const { image_name } = action.payload; const { esrganModelName } = getState().postprocessing; diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index ad128a0fec..dd80e1e378 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -4,7 +4,6 @@ import { autoBatchEnhancer, combineReducers, configureStore, - createAsyncThunk, } from '@reduxjs/toolkit'; import canvasReducer from 'features/canvas/store/canvasSlice'; import controlNetReducer from 'features/controlNet/store/controlNetSlice'; @@ -118,6 +117,7 @@ export const store = configureStore({ export type AppGetState = typeof store.getState; export type RootState = ReturnType; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type AppThunkDispatch = ThunkDispatch; export type AppDispatch = typeof store.dispatch; export const stateSelector = (state: RootState) => state; diff --git a/invokeai/frontend/web/src/common/components/IAIDroppable.tsx b/invokeai/frontend/web/src/common/components/IAIDroppable.tsx index 2e41e3d870..1038f36840 100644 --- a/invokeai/frontend/web/src/common/components/IAIDroppable.tsx +++ b/invokeai/frontend/web/src/common/components/IAIDroppable.tsx @@ -13,11 +13,10 @@ type IAIDroppableProps = { dropLabel?: ReactNode; disabled?: boolean; data?: TypesafeDroppableData; - hoverRef?: React.Ref; }; const IAIDroppable = (props: IAIDroppableProps) => { - const { dropLabel, data, disabled, hoverRef } = props; + const { dropLabel, data, disabled } = props; const dndId = useRef(uuidv4()); const { isOver, setNodeRef, active } = useDroppable({ diff --git a/invokeai/frontend/web/src/common/components/IAIMantineSelectItemWithTooltip.tsx b/invokeai/frontend/web/src/common/components/IAIMantineSelectItemWithTooltip.tsx index 6b56bdf9e9..056bd4a8fa 100644 --- a/invokeai/frontend/web/src/common/components/IAIMantineSelectItemWithTooltip.tsx +++ b/invokeai/frontend/web/src/common/components/IAIMantineSelectItemWithTooltip.tsx @@ -10,7 +10,10 @@ interface ItemProps extends React.ComponentPropsWithoutRef<'div'> { } const IAIMantineSelectItemWithTooltip = forwardRef( - ({ label, tooltip, description, disabled, ...others }: ItemProps, ref) => ( + ( + { label, tooltip, description, disabled: _disabled, ...others }: ItemProps, + ref + ) => ( diff --git a/invokeai/frontend/web/src/common/components/IAISlider.tsx b/invokeai/frontend/web/src/common/components/IAISlider.tsx index 3e7f38cf91..53a195c7b7 100644 --- a/invokeai/frontend/web/src/common/components/IAISlider.tsx +++ b/invokeai/frontend/web/src/common/components/IAISlider.tsx @@ -1,5 +1,4 @@ import { - ChakraProps, FormControl, FormControlProps, FormLabel, @@ -24,16 +23,15 @@ import { Tooltip, TooltipProps, } from '@chakra-ui/react'; -import { clamp } from 'lodash-es'; - import { useAppDispatch } from 'app/store/storeHooks'; import { roundDownToMultiple } from 'common/util/roundDownToMultiple'; import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice'; +import { clamp } from 'lodash-es'; import { FocusEvent, KeyboardEvent, - memo, MouseEvent, + memo, useCallback, useEffect, useMemo, diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx index aa785c379d..7a82e64270 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvas.tsx @@ -1,6 +1,7 @@ import { Box, chakra, Flex } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { canvasSelector, isStagingSelector, @@ -8,8 +9,6 @@ import { import Konva from 'konva'; import { KonvaEventObject } from 'konva/lib/Node'; import { Vector2d } from 'konva/lib/types'; -import { isEqual } from 'lodash-es'; - import { useCallback, useRef } from 'react'; import { Layer, Stage } from 'react-konva'; import useCanvasDragMove from '../hooks/useCanvasDragMove'; @@ -34,7 +33,6 @@ import IAICanvasStagingAreaToolbar from './IAICanvasStagingAreaToolbar'; import IAICanvasStatusText from './IAICanvasStatusText'; import IAICanvasBoundingBox from './IAICanvasToolbar/IAICanvasBoundingBox'; import IAICanvasToolPreview from './IAICanvasToolPreview'; -import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; const selector = createSelector( [canvasSelector, isStagingSelector], diff --git a/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts b/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts index 54ebfa2934..3163e513e9 100644 --- a/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts +++ b/invokeai/frontend/web/src/features/canvas/store/canvasSlice.ts @@ -713,7 +713,7 @@ export const canvasSlice = createSlice({ }, commitStagingAreaImage: ( state, - action: PayloadAction + _action: PayloadAction ) => { if (!state.layerState.stagingArea.images.length) { return; @@ -866,11 +866,11 @@ export const canvasSlice = createSlice({ } }); - builder.addCase(setShouldUseCanvasBetaLayout, (state, action) => { + builder.addCase(setShouldUseCanvasBetaLayout, (state) => { state.doesCanvasNeedScaling = true; }); - builder.addCase(setActiveTab, (state, action) => { + builder.addCase(setActiveTab, (state) => { state.doesCanvasNeedScaling = true; }); builder.addCase(setAspectRatio, (state, action) => { @@ -882,26 +882,6 @@ export const canvasSlice = createSlice({ ); } }); - - // builder.addCase(imageUrlsReceived.fulfilled, (state, action) => { - // const { image_name, image_url, thumbnail_url } = action.payload; - - // state.layerState.objects.forEach((object) => { - // if (object.kind === 'image') { - // if (object.image.image_name === image_name) { - // object.image.image_url = image_url; - // object.image.thumbnail_url = thumbnail_url; - // } - // } - // }); - - // state.layerState.stagingArea.images.forEach((stagedImage) => { - // if (stagedImage.image.image_name === image_name) { - // stagedImage.image.image_url = image_url; - // stagedImage.image.thumbnail_url = thumbnail_url; - // } - // }); - // }); }, }); diff --git a/invokeai/frontend/web/src/features/controlNet/components/ControlNetImagePreview.tsx b/invokeai/frontend/web/src/features/controlNet/components/ControlNetImagePreview.tsx index 1bdb2fd034..859495a941 100644 --- a/invokeai/frontend/web/src/features/controlNet/components/ControlNetImagePreview.tsx +++ b/invokeai/frontend/web/src/features/controlNet/components/ControlNetImagePreview.tsx @@ -11,8 +11,8 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import IAIDndImage from 'common/components/IAIDndImage'; import { memo, useCallback, useMemo, useState } from 'react'; import { useGetImageDTOQuery } from 'services/api/endpoints/images'; -import { controlNetImageChanged } from '../store/controlNetSlice'; import { PostUploadAction } from 'services/api/types'; +import { controlNetImageChanged } from '../store/controlNetSlice'; type Props = { controlNetId: string; @@ -59,19 +59,13 @@ const ControlNetImagePreview = (props: Props) => { const [isMouseOverImage, setIsMouseOverImage] = useState(false); - const { - currentData: controlImage, - isLoading: isLoadingControlImage, - isError: isErrorControlImage, - isSuccess: isSuccessControlImage, - } = useGetImageDTOQuery(controlImageName ?? skipToken); + const { currentData: controlImage } = useGetImageDTOQuery( + controlImageName ?? skipToken + ); - const { - currentData: processedControlImage, - isLoading: isLoadingProcessedControlImage, - isError: isErrorProcessedControlImage, - isSuccess: isSuccessProcessedControlImage, - } = useGetImageDTOQuery(processedControlImageName ?? skipToken); + const { currentData: processedControlImage } = useGetImageDTOQuery( + processedControlImageName ?? skipToken + ); const handleResetControlImage = useCallback(() => { dispatch(controlNetImageChanged({ controlNetId, controlImage: null })); diff --git a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetBeginEnd.tsx b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetBeginEnd.tsx index f2f8a8bef2..3dd420e7c9 100644 --- a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetBeginEnd.tsx +++ b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetBeginEnd.tsx @@ -55,11 +55,6 @@ const ParamControlNetBeginEnd = (props: Props) => { [controlNetId, dispatch] ); - const handleStepPctReset = useCallback(() => { - dispatch(controlNetBeginStepPctChanged({ controlNetId, beginStepPct: 0 })); - dispatch(controlNetEndStepPctChanged({ controlNetId, endStepPct: 1 })); - }, [controlNetId, dispatch]); - return ( Begin / End Step Percentage diff --git a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetControlMode.tsx b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetControlMode.tsx index e2995cf993..e644e24a02 100644 --- a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetControlMode.tsx +++ b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetControlMode.tsx @@ -8,7 +8,6 @@ import { controlNetControlModeChanged, } from 'features/controlNet/store/controlNetSlice'; import { useCallback, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; type ParamControlNetControlModeProps = { controlNetId: string; @@ -42,8 +41,6 @@ export default function ParamControlNetControlMode( const { controlMode, isEnabled } = useAppSelector(selector); - const { t } = useTranslation(); - const handleControlModeChange = useCallback( (controlMode: ControlModes) => { dispatch(controlNetControlModeChanged({ controlNetId, controlMode })); diff --git a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetProcessorSelect.tsx b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetProcessorSelect.tsx index 8bd28f813c..83c66363ac 100644 --- a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetProcessorSelect.tsx +++ b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetProcessorSelect.tsx @@ -13,7 +13,6 @@ import { memo, useCallback, useMemo } from 'react'; import { CONTROLNET_PROCESSORS } from '../../store/constants'; import { controlNetProcessorTypeChanged } from '../../store/controlNetSlice'; import { ControlNetProcessorType } from '../../store/types'; -import { FormControl, FormLabel } from '@chakra-ui/react'; type ParamControlNetProcessorSelectProps = { controlNetId: string; diff --git a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetResizeMode.tsx b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetResizeMode.tsx index 4b31ebfc64..ee04b8077f 100644 --- a/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetResizeMode.tsx +++ b/invokeai/frontend/web/src/features/controlNet/components/parameters/ParamControlNetResizeMode.tsx @@ -8,7 +8,6 @@ import { controlNetResizeModeChanged, } from 'features/controlNet/store/controlNetSlice'; import { useCallback, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; type ParamControlNetResizeModeProps = { controlNetId: string; @@ -41,8 +40,6 @@ export default function ParamControlNetResizeMode( const { resizeMode, isEnabled } = useAppSelector(selector); - const { t } = useTranslation(); - const handleResizeModeChange = useCallback( (resizeMode: ResizeModes) => { dispatch(controlNetResizeModeChanged({ controlNetId, resizeMode })); diff --git a/invokeai/frontend/web/src/features/controlNet/components/processors/ZoeDepthProcessor.tsx b/invokeai/frontend/web/src/features/controlNet/components/processors/ZoeDepthProcessor.tsx index b4b45025eb..1842f39e45 100644 --- a/invokeai/frontend/web/src/features/controlNet/components/processors/ZoeDepthProcessor.tsx +++ b/invokeai/frontend/web/src/features/controlNet/components/processors/ZoeDepthProcessor.tsx @@ -7,7 +7,7 @@ type Props = { isEnabled: boolean; }; -const ZoeDepthProcessor = (props: Props) => { +const ZoeDepthProcessor = (_props: Props) => { // Has no parameters? return null; }; diff --git a/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts b/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts index 196023491c..0df907d463 100644 --- a/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts +++ b/invokeai/frontend/web/src/features/controlNet/store/controlNetSlice.ts @@ -314,11 +314,11 @@ export const controlNetSlice = createSlice({ } }); - builder.addCase(appSocketInvocationError, (state, action) => { + builder.addCase(appSocketInvocationError, (state) => { state.pendingControlImages = []; }); - builder.addMatcher(isAnySessionRejected, (state, action) => { + builder.addMatcher(isAnySessionRejected, (state) => { state.pendingControlImages = []; }); diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx index 4ce85afb1a..35fcbd87f7 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx @@ -1,19 +1,16 @@ import { MenuGroup, MenuItem, MenuList } from '@chakra-ui/react'; +import { createSelector } from '@reduxjs/toolkit'; +import { stateSelector } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { ContextMenu, ContextMenuProps } from 'chakra-ui-contextmenu'; -import { - autoAddBoardIdChanged, - boardIdSelected, -} from 'features/gallery/store/gallerySlice'; +import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice'; import { MouseEvent, memo, useCallback, useMemo } from 'react'; -import { FaFolder, FaPlus } from 'react-icons/fa'; +import { FaPlus } from 'react-icons/fa'; +import { useBoardName } from 'services/api/hooks/useBoardName'; import { BoardDTO } from 'services/api/types'; import { menuListMotionProps } from 'theme/components/menu'; import GalleryBoardContextMenuItems from './GalleryBoardContextMenuItems'; import NoBoardContextMenuItems from './NoBoardContextMenuItems'; -import { useBoardName } from 'services/api/hooks/useBoardName'; -import { createSelector } from '@reduxjs/toolkit'; -import { stateSelector } from 'app/store/store'; type Props = { board?: BoardDTO; @@ -29,20 +26,15 @@ const BoardContextMenu = memo( const selector = useMemo( () => createSelector(stateSelector, ({ gallery }) => { - const isSelected = gallery.selectedBoardId === board_id; const isAutoAdd = gallery.autoAddBoardId === board_id; - return { isSelected, isAutoAdd }; + return { isAutoAdd }; }), [board_id] ); - const { isSelected, isAutoAdd } = useAppSelector(selector); + const { isAutoAdd } = useAppSelector(selector); const boardName = useBoardName(board_id); - const handleSelectBoard = useCallback(() => { - dispatch(boardIdSelected(board_id)); - }, [board_id, dispatch]); - const handleSetAutoAdd = useCallback(() => { dispatch(autoAddBoardIdChanged(board_id)); }, [board_id, dispatch]); diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx index f20bb5a245..512fced67c 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/BoardsList.tsx @@ -1,21 +1,16 @@ -import { ButtonGroup, Collapse, Flex, Grid, GridItem } from '@chakra-ui/react'; +import { Collapse, Flex, Grid, GridItem } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { stateSelector } from 'app/store/store'; import { useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; -import IAIIconButton from 'common/components/IAIIconButton'; -import { AnimatePresence, motion } from 'framer-motion'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; -import { memo, useCallback, useState } from 'react'; -import { FaSearch } from 'react-icons/fa'; +import { memo, useState } from 'react'; import { useListAllBoardsQuery } from 'services/api/endpoints/boards'; import { BoardDTO } from 'services/api/types'; -import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus'; import DeleteBoardModal from '../DeleteBoardModal'; import AddBoardButton from './AddBoardButton'; import BoardsSearch from './BoardsSearch'; import GalleryBoard from './GalleryBoard'; -import SystemBoardButton from './SystemBoardButton'; import NoBoardBoard from './NoBoardBoard'; const selector = createSelector( @@ -36,7 +31,6 @@ const BoardsList = (props: Props) => { const { isOpen } = props; const { selectedBoardId, searchText } = useAppSelector(selector); const { data: boards } = useListAllBoardsQuery(); - const isBatchEnabled = useFeatureStatus('batches').isFeatureEnabled; const filteredBoards = searchText ? boards?.filter((board) => board.board_name.toLowerCase().includes(searchText.toLowerCase()) diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx index dc484ec230..67c45c131b 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GalleryBoard.tsx @@ -1,7 +1,5 @@ import { - Badge, Box, - ChakraProps, Editable, EditableInput, EditablePreview, @@ -17,21 +15,16 @@ import { stateSelector } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import IAIDroppable from 'common/components/IAIDroppable'; +import SelectionOverlay from 'common/components/SelectionOverlay'; import { boardIdSelected } from 'features/gallery/store/gallerySlice'; import { memo, useCallback, useMemo, useState } from 'react'; import { FaUser } from 'react-icons/fa'; import { useUpdateBoardMutation } from 'services/api/endpoints/boards'; import { useGetImageDTOQuery } from 'services/api/endpoints/images'; -import { useBoardTotal } from 'services/api/hooks/useBoardTotal'; import { BoardDTO } from 'services/api/types'; import AutoAddIcon from '../AutoAddIcon'; import BoardContextMenu from '../BoardContextMenu'; -import SelectionOverlay from 'common/components/SelectionOverlay'; -const BASE_BADGE_STYLES: ChakraProps['sx'] = { - bg: 'base.500', - color: 'whiteAlpha.900', -}; interface GalleryBoardProps { board: BoardDTO; isSelected: boolean; @@ -68,8 +61,6 @@ const GalleryBoard = memo( board.cover_image_name ?? skipToken ); - const { totalImages, totalAssets } = useBoardTotal(board.board_id); - const { board_name, board_id } = board; const [localBoardName, setLocalBoardName] = useState(board_name); diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx index 2674eee6f3..ee1d8f6bea 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/NoBoardBoard.tsx @@ -1,4 +1,4 @@ -import { Box, ChakraProps, Flex, Image, Text } from '@chakra-ui/react'; +import { Box, Flex, Image, Text } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { MoveBoardDropData } from 'app/components/ImageDnd/typesafeDnd'; import { stateSelector } from 'app/store/store'; @@ -10,14 +10,8 @@ import SelectionOverlay from 'common/components/SelectionOverlay'; import { boardIdSelected } from 'features/gallery/store/gallerySlice'; import { memo, useCallback, useMemo, useState } from 'react'; import { useBoardName } from 'services/api/hooks/useBoardName'; -import { useBoardTotal } from 'services/api/hooks/useBoardTotal'; import AutoAddIcon from '../AutoAddIcon'; import BoardContextMenu from '../BoardContextMenu'; - -const BASE_BADGE_STYLES: ChakraProps['sx'] = { - bg: 'base.500', - color: 'whiteAlpha.900', -}; interface Props { isSelected: boolean; } @@ -33,7 +27,6 @@ const selector = createSelector( const NoBoardBoard = memo(({ isSelected }: Props) => { const dispatch = useAppDispatch(); - const { totalImages, totalAssets } = useBoardTotal(undefined); const { autoAddBoardId } = useAppSelector(selector); const boardName = useBoardName(undefined); const handleSelectBoard = useCallback(() => { diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx index 4b036bfe7c..9499e6be98 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/GalleryBoardContextMenuItems.tsx @@ -1,11 +1,6 @@ import { MenuItem } from '@chakra-ui/react'; -import { createSelector } from '@reduxjs/toolkit'; -import { stateSelector } from 'app/store/store'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; -import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice'; -import { memo, useCallback, useMemo } from 'react'; -import { FaPlus, FaTrash } from 'react-icons/fa'; +import { memo, useCallback } from 'react'; +import { FaTrash } from 'react-icons/fa'; import { BoardDTO } from 'services/api/types'; type Props = { @@ -14,25 +9,6 @@ type Props = { }; const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => { - const dispatch = useAppDispatch(); - - const selector = useMemo( - () => - createSelector( - stateSelector, - ({ gallery }) => { - const isSelectedForAutoAdd = - board.board_id === gallery.autoAddBoardId; - - return { isSelectedForAutoAdd }; - }, - defaultSelectorOptions - ), - [board.board_id] - ); - - const { isSelectedForAutoAdd } = useAppSelector(selector); - const handleDelete = useCallback(() => { if (!setBoardToDelete) { return; @@ -40,12 +16,6 @@ const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => { setBoardToDelete(board); }, [board, setBoardToDelete]); - const handleToggleAutoAdd = useCallback(() => { - dispatch( - autoAddBoardIdChanged(isSelectedForAutoAdd ? undefined : board.board_id) - ); - }, [board.board_id, dispatch, isSelectedForAutoAdd]); - return ( <> {board.image_count > 0 && ( @@ -59,11 +29,6 @@ const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => { */} )} - {/* {!isSelectedForAutoAdd && ( - } onClick={handleToggleAutoAdd}> - Auto-add to this Board - - )} */} } diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/NoBoardContextMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/NoBoardContextMenuItems.tsx index 31366f6e6a..dd7c7234ce 100644 --- a/invokeai/frontend/web/src/features/gallery/components/Boards/NoBoardContextMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/Boards/NoBoardContextMenuItems.tsx @@ -1,19 +1,6 @@ -import { MenuItem } from '@chakra-ui/react'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice'; -import { memo, useCallback } from 'react'; -import { FaPlus } from 'react-icons/fa'; +import { memo } from 'react'; const NoBoardContextMenuItems = () => { - const dispatch = useAppDispatch(); - - const autoAddBoardId = useAppSelector( - (state) => state.gallery.autoAddBoardId - ); - const handleDisableAutoAdd = useCallback(() => { - dispatch(autoAddBoardIdChanged(undefined)); - }, [dispatch]); - return ( <> {/* {autoAddBoardId && ( diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx index 0cf3671db0..870c6d8461 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx @@ -108,7 +108,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => { 500 ); - const { currentData: imageDTO, isFetching } = useGetImageDTOQuery( + const { currentData: imageDTO } = useGetImageDTOQuery( lastSelectedImage ?? skipToken ); diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx index 52e26c55e7..fd7eaef46a 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImagePreview.tsx @@ -8,17 +8,17 @@ import { import { stateSelector } from 'app/store/store'; import { useAppSelector } from 'app/store/storeHooks'; import IAIDndImage from 'common/components/IAIDndImage'; +import { IAINoContentFallback } from 'common/components/IAIImageFallback'; import { useNextPrevImage } from 'features/gallery/hooks/useNextPrevImage'; import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors'; import { AnimatePresence, motion } from 'framer-motion'; import { isEqual } from 'lodash-es'; import { memo, useCallback, useMemo, useRef, useState } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; +import { FaImage } from 'react-icons/fa'; import { useGetImageDTOQuery } from 'services/api/endpoints/images'; import ImageMetadataViewer from '../ImageMetadataViewer/ImageMetadataViewer'; import NextPrevImageButtons from '../NextPrevImageButtons'; -import { IAINoContentFallback } from 'common/components/IAIImageFallback'; -import { FaImage } from 'react-icons/fa'; export const imagesSelector = createSelector( [stateSelector, selectLastSelectedImage], @@ -93,12 +93,7 @@ const CurrentImagePreview = () => { ] ); - const { - currentData: imageDTO, - isLoading, - isError, - isSuccess, - } = useGetImageDTOQuery(imageName ?? skipToken); + const { currentData: imageDTO } = useGetImageDTOQuery(imageName ?? skipToken); const draggableData = useMemo(() => { if (imageDTO) { diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx index d384d66e58..5b2072bfc4 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx @@ -1,9 +1,7 @@ import { Box, - Button, ButtonGroup, Flex, - Spacer, Tab, TabList, Tabs, @@ -14,16 +12,16 @@ import { createSelector } from '@reduxjs/toolkit'; import { stateSelector } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import IAIButton from 'common/components/IAIButton'; import { memo, useCallback, useRef } from 'react'; +import { FaImages, FaServer } from 'react-icons/fa'; +import { galleryViewChanged } from '../store/gallerySlice'; import BoardsList from './Boards/BoardsList/BoardsList'; import GalleryBoardName from './GalleryBoardName'; import GalleryPinButton from './GalleryPinButton'; import GallerySettingsPopover from './GallerySettingsPopover'; import BatchImageGrid from './ImageGrid/BatchImageGrid'; import GalleryImageGrid from './ImageGrid/GalleryImageGrid'; -import IAIButton from 'common/components/IAIButton'; -import { FaImages, FaServer } from 'react-icons/fa'; -import { galleryViewChanged } from '../store/gallerySlice'; const selector = createSelector( [stateSelector], diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/BatchImage.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/BatchImage.tsx index a918682ccd..528e8cc06f 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/BatchImage.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/BatchImage.tsx @@ -8,13 +8,8 @@ import IAIDndImage from 'common/components/IAIDndImage'; import IAIErrorLoadingImageFallback from 'common/components/IAIErrorLoadingImageFallback'; import IAIFillSkeleton from 'common/components/IAIFillSkeleton'; import ImageContextMenu from 'features/gallery/components/ImageContextMenu/ImageContextMenu'; -import { - imageRangeEndSelected, - imageSelected, - imageSelectionToggled, - imagesRemovedFromBatch, -} from 'features/gallery/store/gallerySlice'; -import { MouseEvent, memo, useCallback, useMemo } from 'react'; +import { imagesRemovedFromBatch } from 'features/gallery/store/gallerySlice'; +import { memo, useCallback, useMemo } from 'react'; import { useGetImageDTOQuery } from 'services/api/endpoints/images'; const makeSelector = (image_name: string) => @@ -39,7 +34,6 @@ const BatchImage = (props: BatchImageProps) => { currentData: imageDTO, isLoading, isError, - isSuccess, } = useGetImageDTOQuery(imageName); const selector = useMemo(() => makeSelector(imageName), [imageName]); @@ -49,18 +43,18 @@ const BatchImage = (props: BatchImageProps) => { dispatch(imagesRemovedFromBatch([imageName])); }, [dispatch, imageName]); - const handleClick = useCallback( - (e: MouseEvent) => { - if (e.shiftKey) { - dispatch(imageRangeEndSelected(imageName)); - } else if (e.ctrlKey || e.metaKey) { - dispatch(imageSelectionToggled(imageName)); - } else { - dispatch(imageSelected(imageName)); - } - }, - [dispatch, imageName] - ); + // const handleClick = useCallback( + // (e: MouseEvent) => { + // if (e.shiftKey) { + // dispatch(imageRangeEndSelected(imageName)); + // } else if (e.ctrlKey || e.metaKey) { + // dispatch(imageSelectionToggled(imageName)); + // } else { + // dispatch(imageSelected(imageName)); + // } + // }, + // [dispatch, imageName] + // ); const draggableData = useMemo(() => { if (selectionCount > 1) { @@ -105,7 +99,7 @@ const BatchImage = (props: BatchImageProps) => { }} > { const { isSelected, selectionCount, selection } = useAppSelector(localSelector); - const handleClick = useCallback( - (e: MouseEvent) => { - // disable multiselect for now - // if (e.shiftKey) { - // dispatch(imageRangeEndSelected(imageName)); - // } else if (e.ctrlKey || e.metaKey) { - // dispatch(imageSelectionToggled(imageName)); - // } else { - // dispatch(imageSelected(imageName)); - // } - dispatch(imageSelected(imageName)); - }, - [dispatch, imageName] - ); + const handleClick = useCallback(() => { + // disable multiselect for now + // if (e.shiftKey) { + // dispatch(imageRangeEndSelected(imageName)); + // } else if (e.ctrlKey || e.metaKey) { + // dispatch(imageSelectionToggled(imageName)); + // } else { + // dispatch(imageSelected(imageName)); + // } + dispatch(imageSelected(imageName)); + }, [dispatch, imageName]); const handleDelete = useCallback( (e: MouseEvent) => { diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts index 125463ba94..5eabe5de26 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts @@ -19,40 +19,44 @@ export const gallerySlice = createSlice({ name: 'gallery', initialState: initialGalleryState, reducers: { - imageRangeEndSelected: (state, action: PayloadAction) => { - // TODO: multiselect - // const rangeEndImageName = action.payload; - // const lastSelectedImage = state.selection[state.selection.length - 1]; - // const filteredImages = selectFilteredImagesLocal(state); - // const lastClickedIndex = filteredImages.findIndex( - // (n) => n.image_name === lastSelectedImage - // ); - // const currentClickedIndex = filteredImages.findIndex( - // (n) => n.image_name === rangeEndImageName - // ); - // if (lastClickedIndex > -1 && currentClickedIndex > -1) { - // // We have a valid range! - // const start = Math.min(lastClickedIndex, currentClickedIndex); - // const end = Math.max(lastClickedIndex, currentClickedIndex); - // const imagesToSelect = filteredImages - // .slice(start, end + 1) - // .map((i) => i.image_name); - // state.selection = uniq(state.selection.concat(imagesToSelect)); - // } + imageRangeEndSelected: () => { + // TODO }, - imageSelectionToggled: (state, action: PayloadAction) => { - // TODO: multiselect - // if ( - // state.selection.includes(action.payload) && - // state.selection.length > 1 - // ) { - // state.selection = state.selection.filter( - // (imageName) => imageName !== action.payload - // ); - // } else { - // state.selection = uniq(state.selection.concat(action.payload)); - // } + // imageRangeEndSelected: (state, action: PayloadAction) => { + // const rangeEndImageName = action.payload; + // const lastSelectedImage = state.selection[state.selection.length - 1]; + // const filteredImages = selectFilteredImagesLocal(state); + // const lastClickedIndex = filteredImages.findIndex( + // (n) => n.image_name === lastSelectedImage + // ); + // const currentClickedIndex = filteredImages.findIndex( + // (n) => n.image_name === rangeEndImageName + // ); + // if (lastClickedIndex > -1 && currentClickedIndex > -1) { + // // We have a valid range! + // const start = Math.min(lastClickedIndex, currentClickedIndex); + // const end = Math.max(lastClickedIndex, currentClickedIndex); + // const imagesToSelect = filteredImages + // .slice(start, end + 1) + // .map((i) => i.image_name); + // state.selection = uniq(state.selection.concat(imagesToSelect)); + // } + // }, + imageSelectionToggled: () => { + // TODO }, + // imageSelectionToggled: (state, action: PayloadAction) => { + // TODO: multiselect + // if ( + // state.selection.includes(action.payload) && + // state.selection.length > 1 + // ) { + // state.selection = state.selection.filter( + // (imageName) => imageName !== action.payload + // ); + // } else { + // state.selection = uniq(state.selection.concat(action.payload)); + // } imageSelected: (state, action: PayloadAction) => { state.selection = action.payload ? [action.payload] : []; }, diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx index 6f437dfcd8..8e478c907c 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx @@ -7,10 +7,8 @@ import { FaList } from 'react-icons/fa'; import { FieldComponentProps } from './types'; const ArrayInputFieldComponent = ( - props: FieldComponentProps + _props: FieldComponentProps ) => { - const { nodeId, field } = props; - return ; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ClipInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ClipInputFieldComponent.tsx index 86359dc9b5..37c3db3d11 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/ClipInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/ClipInputFieldComponent.tsx @@ -6,10 +6,8 @@ import { memo } from 'react'; import { FieldComponentProps } from './types'; const ClipInputFieldComponent = ( - props: FieldComponentProps + _props: FieldComponentProps ) => { - const { nodeId, field } = props; - return null; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ConditioningInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ConditioningInputFieldComponent.tsx index 29ce1e8dae..e280251cd3 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/ConditioningInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/ConditioningInputFieldComponent.tsx @@ -6,13 +6,11 @@ import { memo } from 'react'; import { FieldComponentProps } from './types'; const ConditioningInputFieldComponent = ( - props: FieldComponentProps< + _props: FieldComponentProps< ConditioningInputFieldValue, ConditioningInputFieldTemplate > ) => { - const { nodeId, field } = props; - return null; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ControlInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ControlInputFieldComponent.tsx index dacfdf0703..6b2b3deafb 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/ControlInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/ControlInputFieldComponent.tsx @@ -6,10 +6,8 @@ import { memo } from 'react'; import { FieldComponentProps } from './types'; const ControlInputFieldComponent = ( - props: FieldComponentProps + _props: FieldComponentProps ) => { - const { nodeId, field } = props; - return null; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ControlNetModelInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ControlNetModelInputFieldComponent.tsx index b5d9fef312..7fe2373f66 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/ControlNetModelInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/ControlNetModelInputFieldComponent.tsx @@ -10,7 +10,6 @@ import { MODEL_TYPE_MAP } from 'features/parameters/types/constants'; import { modelIdToControlNetModelParam } from 'features/parameters/util/modelIdToControlNetModelParam'; import { forEach } from 'lodash-es'; import { memo, useCallback, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; import { useGetControlNetModelsQuery } from 'services/api/endpoints/models'; import { FieldComponentProps } from './types'; @@ -23,7 +22,6 @@ const ControlNetModelInputFieldComponent = ( const { nodeId, field } = props; const controlNetModel = field.value; const dispatch = useAppDispatch(); - const { t } = useTranslation(); const { data: controlNetModels } = useGetControlNetModelsQuery(); diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ImageCollectionInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ImageCollectionInputFieldComponent.tsx index 0ac1f7aa1c..8ecd6c8cd9 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/ImageCollectionInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/ImageCollectionInputFieldComponent.tsx @@ -1,25 +1,19 @@ -import { useAppDispatch } from 'app/store/storeHooks'; - -import { fieldValueChanged } from 'features/nodes/store/nodesSlice'; import { ImageCollectionInputFieldTemplate, ImageCollectionInputFieldValue, } from 'features/nodes/types/types'; -import { memo, useCallback } from 'react'; +import { memo } from 'react'; -import { FieldComponentProps } from './types'; -import IAIDndImage from 'common/components/IAIDndImage'; -import { ImageDTO } from 'services/api/types'; import { Flex } from '@chakra-ui/react'; -import { useGetImageDTOQuery } from 'services/api/endpoints/images'; -import { skipToken } from '@reduxjs/toolkit/dist/query'; -import { uniq, uniqBy } from 'lodash-es'; import { NodesMultiImageDropData, isValidDrop, useDroppable, } from 'app/components/ImageDnd/typesafeDnd'; +import IAIDndImage from 'common/components/IAIDndImage'; import IAIDropOverlay from 'common/components/IAIDropOverlay'; +import { useGetImageDTOQuery } from 'services/api/endpoints/images'; +import { FieldComponentProps } from './types'; const ImageCollectionInputFieldComponent = ( props: FieldComponentProps< @@ -29,20 +23,20 @@ const ImageCollectionInputFieldComponent = ( ) => { const { nodeId, field } = props; - const dispatch = useAppDispatch(); + // const dispatch = useAppDispatch(); - const handleDrop = useCallback( - ({ image_name }: ImageDTO) => { - dispatch( - fieldValueChanged({ - nodeId, - fieldName: field.name, - value: uniqBy([...(field.value ?? []), { image_name }], 'image_name'), - }) - ); - }, - [dispatch, field.name, field.value, nodeId] - ); + // const handleDrop = useCallback( + // ({ image_name }: ImageDTO) => { + // dispatch( + // fieldValueChanged({ + // nodeId, + // fieldName: field.name, + // value: uniqBy([...(field.value ?? []), { image_name }], 'image_name'), + // }) + // ); + // }, + // [dispatch, field.name, field.value, nodeId] + // ); const droppableData: NodesMultiImageDropData = { id: `node-${nodeId}-${field.name}`, @@ -54,21 +48,20 @@ const ImageCollectionInputFieldComponent = ( isOver, setNodeRef: setDroppableRef, active, - over, } = useDroppable({ id: `node_${nodeId}`, data: droppableData, }); - const handleReset = useCallback(() => { - dispatch( - fieldValueChanged({ - nodeId, - fieldName: field.name, - value: undefined, - }) - ); - }, [dispatch, field.name, nodeId]); + // const handleReset = useCallback(() => { + // dispatch( + // fieldValueChanged({ + // nodeId, + // fieldName: field.name, + // value: undefined, + // }) + // ); + // }, [dispatch, field.name, nodeId]); return ( @@ -25,12 +23,9 @@ const ImageInputFieldComponent = ( const dispatch = useAppDispatch(); - const { - currentData: imageDTO, - isLoading, - isError, - isSuccess, - } = useGetImageDTOQuery(field.value?.image_name ?? skipToken); + const { currentData: imageDTO } = useGetImageDTOQuery( + field.value?.image_name ?? skipToken + ); const handleReset = useCallback(() => { dispatch( diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ItemInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ItemInputFieldComponent.tsx index fa8eb5a26d..6fa89345bf 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/ItemInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/ItemInputFieldComponent.tsx @@ -7,10 +7,8 @@ import { FaAddressCard } from 'react-icons/fa'; import { FieldComponentProps } from './types'; const ItemInputFieldComponent = ( - props: FieldComponentProps + _props: FieldComponentProps ) => { - const { nodeId, field } = props; - return ; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx index 2de0a07eb5..5d5225582c 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx @@ -6,10 +6,8 @@ import { memo } from 'react'; import { FieldComponentProps } from './types'; const LatentsInputFieldComponent = ( - props: FieldComponentProps + _props: FieldComponentProps ) => { - const { nodeId, field } = props; - return null; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/UnetInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/UnetInputFieldComponent.tsx index 2b5438e802..eaf760d5d4 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/UnetInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/UnetInputFieldComponent.tsx @@ -6,9 +6,8 @@ import { memo } from 'react'; import { FieldComponentProps } from './types'; const UNetInputFieldComponent = ( - props: FieldComponentProps + _props: FieldComponentProps ) => { - const { nodeId, field } = props; return null; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/VaeInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/VaeInputFieldComponent.tsx index b76e43830e..16c59368f9 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/VaeInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/VaeInputFieldComponent.tsx @@ -6,9 +6,8 @@ import { memo } from 'react'; import { FieldComponentProps } from './types'; const VaeInputFieldComponent = ( - props: FieldComponentProps + _props: FieldComponentProps ) => { - const { nodeId, field } = props; return null; }; diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/VaeModelInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/VaeModelInputFieldComponent.tsx index e30532a92f..3fe04b6e29 100644 --- a/invokeai/frontend/web/src/features/nodes/components/fields/VaeModelInputFieldComponent.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/fields/VaeModelInputFieldComponent.tsx @@ -11,7 +11,6 @@ import { MODEL_TYPE_MAP } from 'features/parameters/types/constants'; import { modelIdToVAEModelParam } from 'features/parameters/util/modelIdToVAEModelParam'; import { forEach } from 'lodash-es'; import { memo, useCallback, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; import { useGetVaeModelsQuery } from 'services/api/endpoints/models'; import { FieldComponentProps } from './types'; @@ -24,7 +23,6 @@ const VaeModelInputFieldComponent = ( const { nodeId, field } = props; const vae = field.value; const dispatch = useAppDispatch(); - const { t } = useTranslation(); const { data: vaeModels } = useGetVaeModelsQuery(); const data = useMemo(() => { diff --git a/invokeai/frontend/web/src/features/nodes/components/search/NodeSearch.tsx b/invokeai/frontend/web/src/features/nodes/components/search/NodeSearch.tsx index c441297fe8..669110fa54 100644 --- a/invokeai/frontend/web/src/features/nodes/components/search/NodeSearch.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/search/NodeSearch.tsx @@ -1,26 +1,25 @@ import { Box, Flex } from '@chakra-ui/layout'; +import { Tooltip } from '@chakra-ui/tooltip'; +import { useAppToaster } from 'app/components/Toaster'; import { RootState } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAIInput from 'common/components/IAIInput'; +import { useBuildInvocation } from 'features/nodes/hooks/useBuildInvocation'; +import { InvocationTemplate } from 'features/nodes/types/types'; +import Fuse from 'fuse.js'; import { map } from 'lodash-es'; import { ChangeEvent, FocusEvent, KeyboardEvent, - memo, ReactNode, + memo, useCallback, useRef, useState, } from 'react'; -import { Tooltip } from '@chakra-ui/tooltip'; import { AnyInvocationType } from 'services/events/types'; -import { useBuildInvocation } from 'features/nodes/hooks/useBuildInvocation'; -import { addToast } from 'features/system/store/systemSlice'; import { nodeAdded } from '../../store/nodesSlice'; -import Fuse from 'fuse.js'; -import { InvocationTemplate } from 'features/nodes/types/types'; -import { useAppToaster } from 'app/components/Toaster'; interface NodeListItemProps { title: string; diff --git a/invokeai/frontend/web/src/features/nodes/hooks/useIsValidConnection.ts b/invokeai/frontend/web/src/features/nodes/hooks/useIsValidConnection.ts index a24267d9d9..e5bfa0a627 100644 --- a/invokeai/frontend/web/src/features/nodes/hooks/useIsValidConnection.ts +++ b/invokeai/frontend/web/src/features/nodes/hooks/useIsValidConnection.ts @@ -1,93 +1,94 @@ -import { useCallback } from 'react'; -import { Connection, Node, useReactFlow } from 'reactflow'; -import graphlib from '@dagrejs/graphlib'; -import { InvocationValue } from '../types/types'; +// TODO: enable this at some point +// import graphlib from '@dagrejs/graphlib'; +// import { useCallback } from 'react'; +// import { Connection, Node, useReactFlow } from 'reactflow'; +// import { InvocationValue } from '../types/types'; -export const useIsValidConnection = () => { - const flow = useReactFlow(); +// export const useIsValidConnection = () => { +// const flow = useReactFlow(); - // Check if an in-progress connection is valid - const isValidConnection = useCallback( - ({ source, sourceHandle, target, targetHandle }: Connection): boolean => { - const edges = flow.getEdges(); - const nodes = flow.getNodes(); +// // Check if an in-progress connection is valid +// const isValidConnection = useCallback( +// ({ source, sourceHandle, target, targetHandle }: Connection): boolean => { +// const edges = flow.getEdges(); +// const nodes = flow.getNodes(); - return true; +// // Connection must have valid targets +// if (!(source && sourceHandle && target && targetHandle)) { +// return false; +// } - // // Connection must have valid targets - // if (!(source && sourceHandle && target && targetHandle)) { - // return false; - // } +// // Connection is invalid if target already has a connection +// if ( +// edges.find((edge) => { +// return edge.target === target && edge.targetHandle === targetHandle; +// }) +// ) { +// return false; +// } - // // Connection is invalid if target already has a connection - // if ( - // edges.find((edge) => { - // return edge.target === target && edge.targetHandle === targetHandle; - // }) - // ) { - // return false; - // } +// // Find the source and target nodes +// const sourceNode = flow.getNode(source) as Node; - // // Find the source and target nodes - // const sourceNode = flow.getNode(source) as Node; +// const targetNode = flow.getNode(target) as Node; - // const targetNode = flow.getNode(target) as Node; +// // Conditional guards against undefined nodes/handles +// if (!(sourceNode && targetNode && sourceNode.data && targetNode.data)) { +// return false; +// } - // // Conditional guards against undefined nodes/handles - // if (!(sourceNode && targetNode && sourceNode.data && targetNode.data)) { - // return false; - // } +// // Connection types must be the same for a connection +// if ( +// sourceNode.data.outputs[sourceHandle].type !== +// targetNode.data.inputs[targetHandle].type +// ) { +// return false; +// } - // // Connection types must be the same for a connection - // if ( - // sourceNode.data.outputs[sourceHandle].type !== - // targetNode.data.inputs[targetHandle].type - // ) { - // return false; - // } +// // Graphs much be acyclic (no loops!) - // // Graphs much be acyclic (no loops!) +// /** +// * TODO: use `graphlib.alg.findCycles()` to identify strong connections +// * +// * this validation func only runs when the cursor hits the second handle of the connection, +// * and only on that second handle - so it cannot tell us exhaustively which connections +// * are valid. +// * +// * ideally, we check when the connection starts to calculate all invalid handles at once. +// * +// * requires making a new graphlib graph - and calling `findCycles()` - for each potential +// * handle. instead of using the `isValidConnection` prop, it would use the `onConnectStart` +// * prop. +// * +// * the strong connections should be stored in global state. +// * +// * then, `isValidConnection` would simple loop through the strong connections and if the +// * source and target are in a single strong connection, return false. +// * +// * and also, we can use this knowledge to style every handle when a connection starts, +// * which is otherwise not possible. +// */ - // /** - // * TODO: use `graphlib.alg.findCycles()` to identify strong connections - // * - // * this validation func only runs when the cursor hits the second handle of the connection, - // * and only on that second handle - so it cannot tell us exhaustively which connections - // * are valid. - // * - // * ideally, we check when the connection starts to calculate all invalid handles at once. - // * - // * requires making a new graphlib graph - and calling `findCycles()` - for each potential - // * handle. instead of using the `isValidConnection` prop, it would use the `onConnectStart` - // * prop. - // * - // * the strong connections should be stored in global state. - // * - // * then, `isValidConnection` would simple loop through the strong connections and if the - // * source and target are in a single strong connection, return false. - // * - // * and also, we can use this knowledge to style every handle when a connection starts, - // * which is otherwise not possible. - // */ +// // build a graphlib graph +// const g = new graphlib.Graph(); - // // build a graphlib graph - // const g = new graphlib.Graph(); +// nodes.forEach((n) => { +// g.setNode(n.id); +// }); - // nodes.forEach((n) => { - // g.setNode(n.id); - // }); +// edges.forEach((e) => { +// g.setEdge(e.source, e.target); +// }); - // edges.forEach((e) => { - // g.setEdge(e.source, e.target); - // }); +// // Add the candidate edge to the graph +// g.setEdge(source, target); - // // Add the candidate edge to the graph - // g.setEdge(source, target); +// return graphlib.alg.isAcyclic(g); +// }, +// [flow] +// ); - // return graphlib.alg.isAcyclic(g); - }, - [flow] - ); +// return isValidConnection; +// }; - return isValidConnection; -}; +export const useIsValidConnection = () => () => true; diff --git a/invokeai/frontend/web/src/features/nodes/util/fieldTemplateBuilders.ts b/invokeai/frontend/web/src/features/nodes/util/fieldTemplateBuilders.ts index eaa7fe66fc..9c01deded6 100644 --- a/invokeai/frontend/web/src/features/nodes/util/fieldTemplateBuilders.ts +++ b/invokeai/frontend/web/src/features/nodes/util/fieldTemplateBuilders.ts @@ -417,14 +417,17 @@ export const getFieldType = ( // if schemaObject has no type, then it should have one of allOf, anyOf, oneOf if (schemaObject.allOf) { rawFieldType = refObjectToFieldType( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion schemaObject.allOf![0] as OpenAPIV3.ReferenceObject ); } else if (schemaObject.anyOf) { rawFieldType = refObjectToFieldType( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion schemaObject.anyOf![0] as OpenAPIV3.ReferenceObject ); } else if (schemaObject.oneOf) { rawFieldType = refObjectToFieldType( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion schemaObject.oneOf![0] as OpenAPIV3.ReferenceObject ); } @@ -547,6 +550,7 @@ export const buildOutputFieldTemplates = ( const outputSchemaName = refObject.$ref.split('/').slice(-1)[0]; // get the output schema itself + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const outputSchema = openAPI.components!.schemas![outputSchemaName]; if (isSchemaObject(outputSchema)) { diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildNodesGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildNodesGraph.ts index 64d579ce8b..bae29ee3f5 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildNodesGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildNodesGraph.ts @@ -37,7 +37,7 @@ export const buildNodesGraph = (state: RootState): Graph => { // Reduce the node editor nodes into invocation graph nodes const parsedNodes = filteredNodes.reduce>( - (nodesAccumulator, node, nodeIndex) => { + (nodesAccumulator, node) => { const { id, data } = node; const { type, inputs } = data; @@ -50,7 +50,7 @@ export const buildNodesGraph = (state: RootState): Graph => { return inputsAccumulator; }, - {} as Record, any> + {} as Record, unknown> ); // Build this specific node @@ -72,7 +72,7 @@ export const buildNodesGraph = (state: RootState): Graph => { // Reduce the node editor edges into invocation graph edges const parsedEdges = edges.reduce>( - (edgesAccumulator, edge, edgeIndex) => { + (edgesAccumulator, edge) => { const { source, target, sourceHandle, targetHandle } = edge; // Format the edges and add to the edges array diff --git a/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts b/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts index ee751f0b16..bedf932b50 100644 --- a/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts +++ b/invokeai/frontend/web/src/features/nodes/util/parseSchema.ts @@ -24,6 +24,7 @@ const invocationDenylist = [ export const parseSchema = (openAPI: OpenAPIV3.Document) => { // filter out non-invocation schemas, plus some tricky invocations for now const filteredSchemas = filter( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion openAPI.components!.schemas, (schema, key) => key.includes('Invocation') && @@ -102,6 +103,7 @@ export const parseSchema = (openAPI: OpenAPIV3.Document) => { // some special handling is needed for collect, iterate and range nodes if (type === 'iterate') { // this is guaranteed to be a SchemaObject + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const iterationOutput = openAPI.components!.schemas![ 'IterateInvocationOutput' ] as OpenAPIV3.SchemaObject; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse.tsx index 99ab512948..418ed9278f 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse.tsx @@ -15,7 +15,6 @@ import { getValidControlNets } from 'features/controlNet/util/getValidControlNet import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { map } from 'lodash-es'; import { Fragment, memo, useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; import { FaPlus } from 'react-icons/fa'; import { useGetControlNetModelsQuery } from 'services/api/endpoints/models'; import { v4 as uuidv4 } from 'uuid'; @@ -38,7 +37,6 @@ const selector = createSelector( ); const ParamControlNetCollapse = () => { - const { t } = useTranslation(); const { controlNetsArray, activeLabel } = useAppSelector(selector); const isControlNetDisabled = useFeatureStatus('controlNet').isFeatureDisabled; const dispatch = useAppDispatch(); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamWidth.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamWidth.tsx index 55daadf9ea..895b6cedbf 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamWidth.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamWidth.tsx @@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next'; const selector = createSelector( [stateSelector], - ({ generation, hotkeys, config, ui }) => { + ({ generation, hotkeys, config }) => { const { initial, min, sliderMax, inputMax, fineStep, coarseStep } = config.sd.width; const { width, aspectRatio } = generation; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImage.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImage.tsx index c95149393e..0c5b2c68d0 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImage.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImage.tsx @@ -27,12 +27,9 @@ const selector = createSelector( const InitialImage = () => { const { initialImage } = useAppSelector(selector); - const { - currentData: imageDTO, - isLoading, - isError, - isSuccess, - } = useGetImageDTOQuery(initialImage?.imageName ?? skipToken); + const { currentData: imageDTO } = useGetImageDTOQuery( + initialImage?.imageName ?? skipToken + ); const draggableData = useMemo(() => { if (imageDTO) { diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamCpuNoise.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamCpuNoise.tsx index 5d0ea077c1..45fd7fcf57 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamCpuNoise.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamCpuNoise.tsx @@ -5,7 +5,6 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import IAISwitch from 'common/components/IAISwitch'; import { shouldUseCpuNoiseChanged } from 'features/parameters/store/generationSlice'; import { ChangeEvent } from 'react'; -import { useTranslation } from 'react-i18next'; const selector = createSelector( stateSelector, @@ -23,8 +22,6 @@ export const ParamCpuNoiseToggle = () => { const dispatch = useAppDispatch(); const { isDisabled, shouldUseCpuNoise } = useAppSelector(selector); - const { t } = useTranslation(); - const handleChange = (e: ChangeEvent) => dispatch(shouldUseCpuNoiseChanged(e.target.checked)); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseToggle.tsx index 9c8b96af65..c1c2fb5119 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseToggle.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseToggle.tsx @@ -3,7 +3,6 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAISwitch from 'common/components/IAISwitch'; import { setShouldUseNoiseSettings } from 'features/parameters/store/generationSlice'; import { ChangeEvent } from 'react'; -import { useTranslation } from 'react-i18next'; export const ParamNoiseToggle = () => { const dispatch = useAppDispatch(); @@ -12,8 +11,6 @@ export const ParamNoiseToggle = () => { (state: RootState) => state.generation.shouldUseNoiseSettings ); - const { t } = useTranslation(); - const handleChange = (e: ChangeEvent) => dispatch(setShouldUseNoiseSettings(e.target.checked)); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx index 563165105b..5c1bc09717 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx @@ -7,7 +7,6 @@ import { ESRGANModelName, esrganModelNameChanged, } from 'features/parameters/store/postprocessingSlice'; -import { useTranslation } from 'react-i18next'; export const ESRGAN_MODEL_NAMES: SelectItem[] = [ { diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx index 1c05468de0..96929ea00a 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx @@ -3,7 +3,6 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAISwitch from 'common/components/IAISwitch'; import { setShouldGenerateVariations } from 'features/parameters/store/generationSlice'; import { ChangeEvent } from 'react'; -import { useTranslation } from 'react-i18next'; export const ParamVariationToggle = () => { const dispatch = useAppDispatch(); @@ -12,8 +11,6 @@ export const ParamVariationToggle = () => { (state: RootState) => state.generation.shouldGenerateVariations ); - const { t } = useTranslation(); - const handleChange = (e: ChangeEvent) => dispatch(setShouldGenerateVariations(e.target.checked)); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/AspectRatioPreview.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/AspectRatioPreview.tsx deleted file mode 100644 index ecf4a6713e..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/AspectRatioPreview.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import { Flex, Text } from '@chakra-ui/react'; -import { memo, useMemo } from 'react'; - -export const ratioToCSSString = ( - ratio: AspectRatio, - orientation: Orientation -) => { - if (orientation === 'portrait') { - return `${ratio[0]}/${ratio[1]}`; - } - return `${ratio[1]}/${ratio[0]}`; -}; - -export const ratioToDisplayString = ( - ratio: AspectRatio, - orientation: Orientation -) => { - if (orientation === 'portrait') { - return `${ratio[0]}:${ratio[1]}`; - } - return `${ratio[1]}:${ratio[0]}`; -}; - -type AspectRatioPreviewProps = { - ratio: AspectRatio; - orientation: Orientation; - size: string; -}; - -export type AspectRatio = [number, number]; - -export type Orientation = 'portrait' | 'landscape'; - -const AspectRatioPreview = (props: AspectRatioPreviewProps) => { - const { ratio, size, orientation } = props; - - const ratioCSSString = useMemo(() => { - if (orientation === 'portrait') { - return `${ratio[0]}/${ratio[1]}`; - } - return `${ratio[1]}/${ratio[0]}`; - }, [ratio, orientation]); - - const ratioDisplayString = useMemo(() => `${ratio[0]}:${ratio[1]}`, [ratio]); - - return ( - - - - {ratioDisplayString} - - - - ); -}; - -export default memo(AspectRatioPreview); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/DimensionsSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/DimensionsSettings.tsx deleted file mode 100644 index a187eecd83..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/_ImageDimensions/DimensionsSettings.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { Box, Flex, FormControl, FormLabel, Select } from '@chakra-ui/react'; -import { createSelector } from '@reduxjs/toolkit'; -import { RootState } from 'app/store/store'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import IAISlider from 'common/components/IAISlider'; -import { setWidth } from 'features/parameters/store/generationSlice'; -import { memo, useState } from 'react'; -import AspectRatioPreview, { - AspectRatio, - Orientation, -} from './AspectRatioPreview'; - -const RATIOS: AspectRatio[] = [ - [1, 1], - [5, 4], - [3, 2], - [16, 10], - [16, 9], -]; - -RATIOS.forEach((r) => { - const float = r[0] / r[1]; - console.log((512 * float) / 8); -}); - -const dimensionsSettingsSelector = createSelector( - (state: RootState) => state.generation, - (generation) => { - const { width, height } = generation; - - return { width, height }; - } -); - -const DimensionsSettings = () => { - const { width, height } = useAppSelector(dimensionsSettingsSelector); - const dispatch = useAppDispatch(); - const [ratioIndex, setRatioIndex] = useState(4); - const [orientation, setOrientation] = useState('portrait'); - - return ( - - - - - - Aspect Ratio - - - { - dispatch(setWidth(v)); - }} - /> - - ); -}; - -export default memo(DimensionsSettings); diff --git a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts index a0522c2150..e19f4cd5f4 100644 --- a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts +++ b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts @@ -3,7 +3,6 @@ import { useAppDispatch } from 'app/store/storeHooks'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { UnsafeImageMetadata } from 'services/api/endpoints/images'; -import { isImageField } from 'services/api/guards'; import { ImageDTO } from 'services/api/types'; import { initialImageSelected, modelSelected } from '../store/actions'; import { diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 9a1d514a49..971558335b 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -266,7 +266,7 @@ export const generationSlice = createSlice({ const defaultModel = action.payload.sd?.defaultModel; if (defaultModel && !state.model) { - const [base_model, model_type, model_name] = defaultModel.split('/'); + const [base_model, _model_type, model_name] = defaultModel.split('/'); const result = zMainModel.safeParse({ model_name, diff --git a/invokeai/frontend/web/src/features/parameters/util/modelIdToControlNetModelParam.ts b/invokeai/frontend/web/src/features/parameters/util/modelIdToControlNetModelParam.ts index 1da3325c09..30e6fdcd3d 100644 --- a/invokeai/frontend/web/src/features/parameters/util/modelIdToControlNetModelParam.ts +++ b/invokeai/frontend/web/src/features/parameters/util/modelIdToControlNetModelParam.ts @@ -6,7 +6,7 @@ export const modelIdToControlNetModelParam = ( controlNetModelId: string ): ControlNetModelField | undefined => { const log = logger('models'); - const [base_model, model_type, model_name] = controlNetModelId.split('/'); + const [base_model, _model_type, model_name] = controlNetModelId.split('/'); const result = zControlNetModel.safeParse({ base_model, diff --git a/invokeai/frontend/web/src/features/parameters/util/modelIdToLoRAModelParam.ts b/invokeai/frontend/web/src/features/parameters/util/modelIdToLoRAModelParam.ts index ca8bd36e24..bf4c6454fb 100644 --- a/invokeai/frontend/web/src/features/parameters/util/modelIdToLoRAModelParam.ts +++ b/invokeai/frontend/web/src/features/parameters/util/modelIdToLoRAModelParam.ts @@ -6,7 +6,7 @@ export const modelIdToLoRAModelParam = ( ): LoRAModelParam | undefined => { const log = logger('models'); - const [base_model, model_type, model_name] = loraModelId.split('/'); + const [base_model, _model_type, model_name] = loraModelId.split('/'); const result = zLoRAModel.safeParse({ base_model, diff --git a/invokeai/frontend/web/src/features/parameters/util/modelIdToMainModelParam.ts b/invokeai/frontend/web/src/features/parameters/util/modelIdToMainModelParam.ts index 1468d9595e..1b8cbbfe72 100644 --- a/invokeai/frontend/web/src/features/parameters/util/modelIdToMainModelParam.ts +++ b/invokeai/frontend/web/src/features/parameters/util/modelIdToMainModelParam.ts @@ -8,7 +8,7 @@ export const modelIdToMainModelParam = ( mainModelId: string ): MainModelParam | undefined => { const log = logger('models'); - const [base_model, model_type, model_name] = mainModelId.split('/'); + const [base_model, _model_type, model_name] = mainModelId.split('/'); const result = zMainModel.safeParse({ base_model, diff --git a/invokeai/frontend/web/src/features/parameters/util/modelIdToVAEModelParam.ts b/invokeai/frontend/web/src/features/parameters/util/modelIdToVAEModelParam.ts index 1d60ab1c84..1f3908dd47 100644 --- a/invokeai/frontend/web/src/features/parameters/util/modelIdToVAEModelParam.ts +++ b/invokeai/frontend/web/src/features/parameters/util/modelIdToVAEModelParam.ts @@ -5,7 +5,7 @@ export const modelIdToVAEModelParam = ( vaeModelId: string ): VaeModelParam | undefined => { const log = logger('models'); - const [base_model, model_type, model_name] = vaeModelId.split('/'); + const [base_model, _model_type, model_name] = vaeModelId.split('/'); const result = zVaeModel.safeParse({ base_model, diff --git a/invokeai/frontend/web/src/features/system/components/StatusIndicator.tsx b/invokeai/frontend/web/src/features/system/components/StatusIndicator.tsx index c5945140c3..767b394ac1 100644 --- a/invokeai/frontend/web/src/features/system/components/StatusIndicator.tsx +++ b/invokeai/frontend/web/src/features/system/components/StatusIndicator.tsx @@ -1,15 +1,14 @@ import { Flex, Icon, Text } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { useAppSelector } from 'app/store/storeHooks'; -import { isEqual } from 'lodash-es'; -import { useTranslation } from 'react-i18next'; -import { systemSelector } from '../store/systemSelectors'; -import { ResourceKey } from 'i18next'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { AnimatePresence, motion } from 'framer-motion'; +import { ResourceKey } from 'i18next'; import { useMemo, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; import { FaCircle } from 'react-icons/fa'; import { useHoverDirty } from 'react-use'; -import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import { systemSelector } from '../store/systemSelectors'; const statusIndicatorSelector = createSelector( systemSelector, diff --git a/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx b/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx index f327e10efc..c7c1182d21 100644 --- a/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx +++ b/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx @@ -5,7 +5,6 @@ import { PropsWithChildren, memo } from 'react'; import { PARAMETERS_PANEL_WIDTH } from 'theme/util/constants'; import { uiSelector } from '../store/uiSelectors'; import PinParametersPanelButton from './PinParametersPanelButton'; -import OverlayScrollable from './common/OverlayScrollable'; const selector = createSelector(uiSelector, (ui) => { const { shouldPinParametersPanel, shouldShowParametersPanel } = ui; diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx index cda908da50..d343d17a47 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx @@ -19,18 +19,17 @@ const selector = createSelector( [uiSelector, generationSelector], (ui, generation) => { const { shouldUseSliders } = ui; - const { shouldFitToWidthHeight, shouldRandomizeSeed } = generation; + const { shouldRandomizeSeed } = generation; const activeLabel = !shouldRandomizeSeed ? 'Manual Seed' : undefined; - return { shouldUseSliders, shouldFitToWidthHeight, activeLabel }; + return { shouldUseSliders, activeLabel }; }, defaultSelectorOptions ); const ImageToImageTabCoreParameters = () => { - const { shouldUseSliders, shouldFitToWidthHeight, activeLabel } = - useAppSelector(selector); + const { shouldUseSliders, activeLabel } = useAppSelector(selector); return ( { socket.on('connect_error', (error) => { if (error && error.message) { - const data: string | undefined = (error as any).data; + const data: string | undefined = ( + error as unknown as { data: string | undefined } + ).data; if (data === 'ERR_UNAUTHENTICATED') { dispatch( addToast( diff --git a/invokeai/frontend/web/src/theme/components/button.ts b/invokeai/frontend/web/src/theme/components/button.ts index dd27a69a71..c01d564494 100644 --- a/invokeai/frontend/web/src/theme/components/button.ts +++ b/invokeai/frontend/web/src/theme/components/button.ts @@ -71,9 +71,13 @@ const invokeAIOutline = defineStyle((props) => { border: '1px solid', borderColor: c === 'gray' ? borderColor : 'currentColor', '.chakra-button__group[data-attached][data-orientation=horizontal] > &:not(:last-of-type)': - { marginEnd: '-1px' }, + { + marginEnd: '-1px', + }, '.chakra-button__group[data-attached][data-orientation=vertical] > &:not(:last-of-type)': - { marginBottom: '-1px' }, + { + marginBottom: '-1px', + }, }; }); diff --git a/invokeai/frontend/web/src/theme/components/modal.ts b/invokeai/frontend/web/src/theme/components/modal.ts index 8310d9d46c..54e3a347f4 100644 --- a/invokeai/frontend/web/src/theme/components/modal.ts +++ b/invokeai/frontend/web/src/theme/components/modal.ts @@ -14,14 +14,14 @@ const invokeAIOverlay = defineStyle((props) => ({ const invokeAIDialogContainer = defineStyle({}); -const invokeAIDialog = defineStyle((props) => { +const invokeAIDialog = defineStyle(() => { return { layerStyle: 'first', maxH: '80vh', }; }); -const invokeAIHeader = defineStyle((props) => { +const invokeAIHeader = defineStyle(() => { return { fontWeight: '600', fontSize: 'lg', @@ -42,8 +42,8 @@ const invokeAIFooter = defineStyle({}); export const invokeAI = definePartsStyle((props) => ({ overlay: invokeAIOverlay(props), dialogContainer: invokeAIDialogContainer, - dialog: invokeAIDialog(props), - header: invokeAIHeader(props), + dialog: invokeAIDialog(), + header: invokeAIHeader(), closeButton: invokeAICloseButton, body: invokeAIBody, footer: invokeAIFooter,