Merge branch 'next' into chainchompa/add-all-scan

This commit is contained in:
chainchompa 2024-02-27 09:44:35 -05:00 committed by GitHub
commit 175cfe41a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
207 changed files with 2371 additions and 5367 deletions

View File

@ -36,8 +36,10 @@ jobs:
- name: Typescript
run: 'pnpm run lint:tsc'
- name: Madge
run: 'pnpm run lint:madge'
run: 'pnpm run lint:dpdm'
- name: ESLint
run: 'pnpm run lint:eslint'
- name: Prettier
run: 'pnpm run lint:prettier'
- name: Knip
run: 'pnpm run lint:knip'

View File

@ -13,7 +13,7 @@ from pydantic import BaseModel, ConfigDict, Field
from starlette.exceptions import HTTPException
from typing_extensions import Annotated
from invokeai.app.services.model_install import ModelInstallJob, ModelSource
from invokeai.app.services.model_install import ModelInstallJob
from invokeai.app.services.model_records import (
DuplicateModelException,
InvalidModelException,
@ -439,8 +439,8 @@ async def add_model_record(
@model_manager_router.post(
"/heuristic_install",
operation_id="heuristic_install_model",
"/install",
operation_id="install_model",
responses={
201: {"description": "The model imported successfully"},
415: {"description": "Unrecognized file/folder format"},
@ -449,8 +449,9 @@ async def add_model_record(
},
status_code=201,
)
async def heuristic_install(
source: str,
async def install_model(
source: str = Query(description="Model source to install, can be a local path, repo_id, or remote URL"),
# TODO(MM2): Can we type this?
config: Optional[Dict[str, Any]] = Body(
description="Dict of fields that override auto-probed values in the model config record, such as name, description and prediction_type ",
default=None,
@ -491,106 +492,7 @@ async def heuristic_install(
result: ModelInstallJob = installer.heuristic_import(
source=source,
config=config,
)
logger.info(f"Started installation of {source}")
except UnknownModelException as e:
logger.error(str(e))
raise HTTPException(status_code=424, detail=str(e))
except InvalidModelException as e:
logger.error(str(e))
raise HTTPException(status_code=415)
except ValueError as e:
logger.error(str(e))
raise HTTPException(status_code=409, detail=str(e))
return result
@model_manager_router.post(
"/install",
operation_id="import_model",
responses={
201: {"description": "The model imported successfully"},
415: {"description": "Unrecognized file/folder format"},
424: {"description": "The model appeared to import successfully, but could not be found in the model manager"},
409: {"description": "There is already a model corresponding to this path or repo_id"},
},
status_code=201,
)
async def import_model(
source: ModelSource,
config: Optional[Dict[str, Any]] = Body(
description="Dict of fields that override auto-probed values in the model config record, such as name, description and prediction_type ",
default=None,
),
) -> ModelInstallJob:
"""Install a model using its local path, repo_id, or remote URL.
Models will be downloaded, probed, configured and installed in a
series of background threads. The return object has `status` attribute
that can be used to monitor progress.
The source object is a discriminated Union of LocalModelSource,
HFModelSource and URLModelSource. Set the "type" field to the
appropriate value:
* To install a local path using LocalModelSource, pass a source of form:
```
{
"type": "local",
"path": "/path/to/model",
"inplace": false
}
```
The "inplace" flag, if true, will register the model in place in its
current filesystem location. Otherwise, the model will be copied
into the InvokeAI models directory.
* To install a HuggingFace repo_id using HFModelSource, pass a source of form:
```
{
"type": "hf",
"repo_id": "stabilityai/stable-diffusion-2.0",
"variant": "fp16",
"subfolder": "vae",
"access_token": "f5820a918aaf01"
}
```
The `variant`, `subfolder` and `access_token` fields are optional.
* To install a remote model using an arbitrary URL, pass:
```
{
"type": "url",
"url": "http://www.civitai.com/models/123456",
"access_token": "f5820a918aaf01"
}
```
The `access_token` field is optonal
The model's configuration record will be probed and filled in
automatically. To override the default guesses, pass "metadata"
with a Dict containing the attributes you wish to override.
Installation occurs in the background. Either use list_model_install_jobs()
to poll for completion, or listen on the event bus for the following events:
* "model_install_running"
* "model_install_completed"
* "model_install_error"
On successful completion, the event's payload will contain the field "key"
containing the installed ID of the model. On an error, the event's payload
will contain the fields "error_type" and "error" describing the nature of the
error and its traceback, respectively.
"""
logger = ApiDependencies.invoker.services.logger
try:
installer = ApiDependencies.invoker.services.model_manager.install
result: ModelInstallJob = installer.import_model(
source=source,
config=config,
access_token=access_token,
)
logger.info(f"Started installation of {source}")
except UnknownModelException as e:

View File

@ -743,6 +743,7 @@ class ModelInstallService(ModelInstallServiceBase):
self._signal_job_downloading(install_job)
def _download_complete_callback(self, download_job: DownloadJob) -> None:
self._logger.info(f"{download_job.source}: model download complete")
with self._lock:
install_job = self._download_cache[download_job.source]
self._download_cache.pop(download_job.source, None)
@ -775,7 +776,7 @@ class ModelInstallService(ModelInstallServiceBase):
if not install_job:
return
self._downloads_changed_event.set()
self._logger.warning(f"Download {download_job.source} cancelled.")
self._logger.warning(f"{download_job.source}: model download cancelled")
# if install job has already registered an error, then do not replace its status with cancelled
if not install_job.errored:
install_job.cancel()

View File

@ -234,37 +234,6 @@ class MainDiffusersConfig(_DiffusersConfig, _MainConfig):
type: Literal[ModelType.Main] = ModelType.Main
class ONNXSD1Config(_MainConfig):
"""Model config for ONNX format models based on sd-1."""
type: Literal[ModelType.ONNX] = ModelType.ONNX
format: Literal[ModelFormat.Onnx, ModelFormat.Olive]
base: Literal[BaseModelType.StableDiffusion1] = BaseModelType.StableDiffusion1
prediction_type: SchedulerPredictionType = SchedulerPredictionType.Epsilon
upcast_attention: bool = False
class ONNXSD2Config(_MainConfig):
"""Model config for ONNX format models based on sd-2."""
type: Literal[ModelType.ONNX] = ModelType.ONNX
format: Literal[ModelFormat.Onnx, ModelFormat.Olive]
# No yaml config file for ONNX, so these are part of config
base: Literal[BaseModelType.StableDiffusion2] = BaseModelType.StableDiffusion2
prediction_type: SchedulerPredictionType = SchedulerPredictionType.VPrediction
upcast_attention: bool = True
class ONNXSDXLConfig(_MainConfig):
"""Model config for ONNX format models based on sdxl."""
type: Literal[ModelType.ONNX] = ModelType.ONNX
format: Literal[ModelFormat.Onnx, ModelFormat.Olive]
# No yaml config file for ONNX, so these are part of config
base: Literal[BaseModelType.StableDiffusionXL] = BaseModelType.StableDiffusionXL
prediction_type: SchedulerPredictionType = SchedulerPredictionType.VPrediction
class IPAdapterConfig(ModelConfigBase):
"""Model config for IP Adaptor format models."""
@ -287,7 +256,6 @@ class T2IConfig(ModelConfigBase):
format: Literal[ModelFormat.Diffusers]
_ONNXConfig = Annotated[Union[ONNXSD1Config, ONNXSD2Config, ONNXSDXLConfig], Field(discriminator="base")]
_ControlNetConfig = Annotated[
Union[ControlNetDiffusersConfig, ControlNetCheckpointConfig],
Field(discriminator="format"),
@ -297,7 +265,6 @@ _MainModelConfig = Annotated[Union[MainDiffusersConfig, MainCheckpointConfig], F
AnyModelConfig = Union[
_MainModelConfig,
_ONNXConfig,
_VaeConfig,
_ControlNetConfig,
# ModelConfigBase,

View File

@ -1,9 +0,0 @@
{
"entry": ["src/main.tsx"],
"extensions": [".ts", ".tsx"],
"ignorePatterns": ["**/node_modules/**", "dist/**", "public/**", "**/*.stories.tsx", "config/**"],
"ignoreUnresolved": [],
"ignoreUnimported": ["src/i18.d.ts", "vite.config.ts", "src/vite-env.d.ts"],
"respectGitignore": true,
"ignoreUnused": []
}

View File

@ -0,0 +1,27 @@
import type { KnipConfig } from 'knip';
const config: KnipConfig = {
ignore: [
// This file is only used during debugging
'src/app/store/middleware/debugLoggerMiddleware.ts',
// Autogenerated types - shouldn't ever touch these
'src/services/api/schema.ts',
],
ignoreBinaries: ['only-allow'],
rules: {
files: 'warn',
dependencies: 'warn',
unlisted: 'warn',
binaries: 'warn',
unresolved: 'warn',
exports: 'warn',
types: 'warn',
nsExports: 'warn',
nsTypes: 'warn',
enumMembers: 'warn',
classMembers: 'warn',
duplicates: 'warn',
},
};
export default config;

View File

@ -24,16 +24,16 @@
"build": "pnpm run lint && vite build",
"typegen": "node scripts/typegen.js",
"preview": "vite preview",
"lint:madge": "madge --circular src/main.tsx",
"lint:knip": "knip",
"lint:dpdm": "dpdm --no-warning --no-tree --transform --exit-code circular:1 src/main.tsx",
"lint:eslint": "eslint --max-warnings=0 .",
"lint:prettier": "prettier --check .",
"lint:tsc": "tsc --noEmit",
"lint": "concurrently -g -n eslint,prettier,tsc,madge -c cyan,green,magenta,yellow \"pnpm run lint:eslint\" \"pnpm run lint:prettier\" \"pnpm run lint:tsc\" \"pnpm run lint:madge\"",
"fix": "eslint --fix . && prettier --log-level warn --write .",
"lint": "concurrently -g -c red,green,yellow,blue,magenta pnpm:lint:*",
"fix": "knip --fix && eslint --fix . && prettier --log-level warn --write .",
"preinstall": "npx only-allow pnpm",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"unimported": "npx unimported",
"test": "vitest",
"test:no-watch": "vitest --no-watch"
},
@ -58,16 +58,15 @@
"@dnd-kit/utilities": "^3.2.2",
"@fontsource-variable/inter": "^5.0.16",
"@invoke-ai/ui-library": "^0.0.21",
"@mantine/form": "6.0.21",
"@nanostores/react": "^0.7.2",
"@reduxjs/toolkit": "2.2.1",
"@roarr/browser-log-writer": "^1.3.0",
"chakra-react-select": "^4.7.6",
"compare-versions": "^6.1.0",
"dateformat": "^5.0.3",
"framer-motion": "^11.0.5",
"i18next": "^23.9.0",
"i18next-http-backend": "^2.4.3",
"framer-motion": "^11.0.6",
"i18next": "^23.10.0",
"i18next-http-backend": "^2.5.0",
"idb-keyval": "^6.2.1",
"jsondiffpatch": "^0.6.0",
"konva": "^9.3.3",
@ -76,7 +75,7 @@
"new-github-issue-url": "^1.0.0",
"overlayscrollbars": "^2.5.0",
"overlayscrollbars-react": "^0.5.4",
"query-string": "^8.2.0",
"query-string": "^9.0.0",
"react": "^18.2.0",
"react-colorful": "^5.6.1",
"react-dom": "^18.2.0",
@ -88,11 +87,10 @@
"react-icons": "^5.0.1",
"react-konva": "^18.2.10",
"react-redux": "9.1.0",
"react-resizable-panels": "^2.0.9",
"react-resizable-panels": "^2.0.11",
"react-select": "5.8.0",
"react-textarea-autosize": "^8.5.3",
"react-use": "^17.5.0",
"react-virtuoso": "^4.7.0",
"react-virtuoso": "^4.7.1",
"reactflow": "^11.10.4",
"redux-dynamic-middlewares": "^2.2.0",
"redux-remember": "^5.1.0",
@ -114,29 +112,27 @@
"devDependencies": {
"@invoke-ai/eslint-config-react": "^0.0.14",
"@invoke-ai/prettier-config-react": "^0.0.7",
"@storybook/addon-docs": "^7.6.17",
"@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-interactions": "^7.6.17",
"@storybook/addon-links": "^7.6.17",
"@storybook/addon-storysource": "^7.6.17",
"@storybook/blocks": "^7.6.17",
"@storybook/manager-api": "^7.6.17",
"@storybook/react": "^7.6.17",
"@storybook/react-vite": "^7.6.17",
"@storybook/test": "^7.6.17",
"@storybook/theming": "^7.6.17",
"@types/dateformat": "^5.0.2",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.11.19",
"@types/react": "^18.2.57",
"@types/node": "^20.11.20",
"@types/react": "^18.2.59",
"@types/react-dom": "^18.2.19",
"@types/uuid": "^9.0.8",
"@vitejs/plugin-react-swc": "^3.6.0",
"concurrently": "^8.2.2",
"eslint": "^8.56.0",
"dpdm": "^3.14.0",
"eslint": "^8.57.0",
"eslint-plugin-i18next": "^6.0.3",
"eslint-plugin-path": "^1.2.4",
"madge": "^6.1.0",
"knip": "^5.0.2",
"openapi-types": "^12.1.3",
"openapi-typescript": "^6.7.4",
"prettier": "^3.2.5",
@ -145,9 +141,9 @@
"ts-toolbelt": "^9.6.0",
"tsafe": "^1.6.6",
"typescript": "^5.3.3",
"vite": "^5.1.3",
"vite": "^5.1.4",
"vite-plugin-css-injected-by-js": "^3.4.0",
"vite-plugin-dts": "^3.7.2",
"vite-plugin-dts": "^3.7.3",
"vite-plugin-eslint": "^1.8.1",
"vite-tsconfig-paths": "^4.3.1",
"vitest": "^1.3.1"

File diff suppressed because it is too large Load Diff

View File

@ -674,6 +674,7 @@
"noMetaData": "No metadata found",
"noRecallParameters": "No parameters to recall found",
"parameterSet": "Parameter {{parameter}} set",
"parsingFailed": "Parsing Failed",
"perlin": "Perlin Noise",
"positivePrompt": "Positive Prompt",
"recallParameters": "Recall Parameters",
@ -1193,8 +1194,8 @@
"unableToInvoke": "Unable to Invoke"
},
"maskAdjustmentsHeader": "Mask Adjustments",
"maskBlur": "Blur",
"maskBlurMethod": "Blur Method",
"maskBlur": "Mask Blur",
"maskBlurMethod": "Mask Blur Method",
"maskEdge": "Mask Edge",
"negativePromptPlaceholder": "Negative Prompt",
"noiseSettings": "Noise",
@ -1480,8 +1481,8 @@
"Scheduler defines how to iteratively add noise to an image or how to update a sample based on a model's output."
]
},
"compositingBlur": {
"heading": "Blur",
"compositingMaskBlur": {
"heading": "Mask Blur",
"paragraphs": ["The blur radius of the mask."]
},
"compositingBlurMethod": {

View File

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

View File

@ -19,7 +19,7 @@ declare global {
}
export const $socketOptions = map<Partial<ManagerOptions & SocketOptions>>({});
export const $isSocketInitialized = atom<boolean>(false);
const $isSocketInitialized = atom<boolean>(false);
/**
* Initializes the socket.io connection and sets up event listeners.

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ import { atom } from 'nanostores';
import type { Driver } from 'redux-remember';
// Create a custom idb-keyval store (just needed to customize the name)
export const $idbKeyValStore = atom<UseStore>(createIDBKeyValStore('invoke', 'invoke-store'));
const $idbKeyValStore = atom<UseStore>(createIDBKeyValStore('invoke', 'invoke-store'));
export const clearIdbKeyValStore = () => {
clear($idbKeyValStore.get());

View File

@ -3,7 +3,7 @@ import { parseify } from 'common/util/serialize';
import { PersistError, RehydrateError } from 'redux-remember';
import { serializeError } from 'serialize-error';
export type StorageErrorArgs = {
type StorageErrorArgs = {
key: string;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ // any is correct
value?: any;

View File

@ -1,82 +1,65 @@
import type { ListenerEffect, TypedAddListener, TypedStartListening, UnknownAction } from '@reduxjs/toolkit';
import { addListener, createListenerMiddleware } from '@reduxjs/toolkit';
import type { TypedStartListening } from '@reduxjs/toolkit';
import { createListenerMiddleware } from '@reduxjs/toolkit';
import { addCommitStagingAreaImageListener } from 'app/store/middleware/listenerMiddleware/listeners/addCommitStagingAreaImageListener';
import { addFirstListImagesListener } from 'app/store/middleware/listenerMiddleware/listeners/addFirstListImagesListener.ts';
import { addAnyEnqueuedListener } from 'app/store/middleware/listenerMiddleware/listeners/anyEnqueued';
import { addAppConfigReceivedListener } from 'app/store/middleware/listenerMiddleware/listeners/appConfigReceived';
import { addAppStartedListener } from 'app/store/middleware/listenerMiddleware/listeners/appStarted';
import { addBatchEnqueuedListener } from 'app/store/middleware/listenerMiddleware/listeners/batchEnqueued';
import { addDeleteBoardAndImagesFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted';
import { addBoardIdSelectedListener } from 'app/store/middleware/listenerMiddleware/listeners/boardIdSelected';
import { addBulkDownloadListeners } from 'app/store/middleware/listenerMiddleware/listeners/bulkDownload';
import { addCanvasCopiedToClipboardListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard';
import { addCanvasDownloadedAsImageListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage';
import { addCanvasImageToControlNetListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasImageToControlNet';
import { addCanvasMaskSavedToGalleryListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasMaskSavedToGallery';
import { addCanvasMaskToControlNetListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasMaskToControlNet';
import { addCanvasMergedListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasMerged';
import { addCanvasSavedToGalleryListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery';
import { addControlNetAutoProcessListener } from 'app/store/middleware/listenerMiddleware/listeners/controlNetAutoProcess';
import { addControlNetImageProcessedListener } from 'app/store/middleware/listenerMiddleware/listeners/controlNetImageProcessed';
import { addEnqueueRequestedCanvasListener } from 'app/store/middleware/listenerMiddleware/listeners/enqueueRequestedCanvas';
import { addEnqueueRequestedLinear } from 'app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear';
import { addEnqueueRequestedNodes } from 'app/store/middleware/listenerMiddleware/listeners/enqueueRequestedNodes';
import { addGalleryImageClickedListener } from 'app/store/middleware/listenerMiddleware/listeners/galleryImageClicked';
import { addGetOpenAPISchemaListener } from 'app/store/middleware/listenerMiddleware/listeners/getOpenAPISchema';
import { addImageAddedToBoardFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/imageAddedToBoard';
import { addRequestedSingleImageDeletionListener } from 'app/store/middleware/listenerMiddleware/listeners/imageDeleted';
import { addImageDroppedListener } from 'app/store/middleware/listenerMiddleware/listeners/imageDropped';
import { addImageRemovedFromBoardFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/imageRemovedFromBoard';
import { addImagesStarredListener } from 'app/store/middleware/listenerMiddleware/listeners/imagesStarred';
import { addImagesUnstarredListener } from 'app/store/middleware/listenerMiddleware/listeners/imagesUnstarred';
import { addImageToDeleteSelectedListener } from 'app/store/middleware/listenerMiddleware/listeners/imageToDeleteSelected';
import { addImageUploadedFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/imageUploaded';
import { addInitialImageSelectedListener } from 'app/store/middleware/listenerMiddleware/listeners/initialImageSelected';
import { addModelSelectedListener } from 'app/store/middleware/listenerMiddleware/listeners/modelSelected';
import { addModelsLoadedListener } from 'app/store/middleware/listenerMiddleware/listeners/modelsLoaded';
import { addDynamicPromptsListener } from 'app/store/middleware/listenerMiddleware/listeners/promptChanged';
import { addSocketConnectedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketConnected';
import { addSocketDisconnectedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketDisconnected';
import { addGeneratorProgressEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketGeneratorProgress';
import { addGraphExecutionStateCompleteEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketGraphExecutionStateComplete';
import { addInvocationCompleteEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete';
import { addInvocationErrorEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError';
import { addInvocationRetrievalErrorEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationRetrievalError';
import { addInvocationStartedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationStarted';
import { addModelInstallEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketModelInstall';
import { addModelLoadEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad';
import { addSocketQueueItemStatusChangedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketQueueItemStatusChanged';
import { addSessionRetrievalErrorEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketSessionRetrievalError';
import { addSocketSubscribedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketSubscribed';
import { addSocketUnsubscribedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketUnsubscribed';
import { addStagingAreaImageSavedListener } from 'app/store/middleware/listenerMiddleware/listeners/stagingAreaImageSaved';
import { addUpdateAllNodesRequestedListener } from 'app/store/middleware/listenerMiddleware/listeners/updateAllNodesRequested';
import { addUpscaleRequestedListener } from 'app/store/middleware/listenerMiddleware/listeners/upscaleRequested';
import { addWorkflowLoadRequestedListener } from 'app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested';
import type { AppDispatch, RootState } from 'app/store/store';
import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener';
import { addFirstListImagesListener } from './listeners/addFirstListImagesListener.ts';
import { addAnyEnqueuedListener } from './listeners/anyEnqueued';
import { addAppConfigReceivedListener } from './listeners/appConfigReceived';
import { addAppStartedListener } from './listeners/appStarted';
import { addBatchEnqueuedListener } from './listeners/batchEnqueued';
import { addDeleteBoardAndImagesFulfilledListener } from './listeners/boardAndImagesDeleted';
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
import { addCanvasCopiedToClipboardListener } from './listeners/canvasCopiedToClipboard';
import { addCanvasDownloadedAsImageListener } from './listeners/canvasDownloadedAsImage';
import { addCanvasImageToControlNetListener } from './listeners/canvasImageToControlNet';
import { addCanvasMaskSavedToGalleryListener } from './listeners/canvasMaskSavedToGallery';
import { addCanvasMaskToControlNetListener } from './listeners/canvasMaskToControlNet';
import { addCanvasMergedListener } from './listeners/canvasMerged';
import { addCanvasSavedToGalleryListener } from './listeners/canvasSavedToGallery';
import { addControlNetAutoProcessListener } from './listeners/controlNetAutoProcess';
import { addControlNetImageProcessedListener } from './listeners/controlNetImageProcessed';
import { addEnqueueRequestedCanvasListener } from './listeners/enqueueRequestedCanvas';
import { addEnqueueRequestedLinear } from './listeners/enqueueRequestedLinear';
import { addEnqueueRequestedNodes } from './listeners/enqueueRequestedNodes';
import { addGetOpenAPISchemaListener } from './listeners/getOpenAPISchema';
import {
addImageAddedToBoardFulfilledListener,
addImageAddedToBoardRejectedListener,
} from './listeners/imageAddedToBoard';
import {
addImageDeletedFulfilledListener,
addImageDeletedPendingListener,
addImageDeletedRejectedListener,
addRequestedMultipleImageDeletionListener,
addRequestedSingleImageDeletionListener,
} from './listeners/imageDeleted';
import { addImageDroppedListener } from './listeners/imageDropped';
import {
addImageRemovedFromBoardFulfilledListener,
addImageRemovedFromBoardRejectedListener,
} from './listeners/imageRemovedFromBoard';
import { addImagesStarredListener } from './listeners/imagesStarred';
import { addImagesUnstarredListener } from './listeners/imagesUnstarred';
import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected';
import { addImageUploadedFulfilledListener, addImageUploadedRejectedListener } from './listeners/imageUploaded';
import { addInitialImageSelectedListener } from './listeners/initialImageSelected';
import { addModelSelectedListener } from './listeners/modelSelected';
import { addModelsLoadedListener } from './listeners/modelsLoaded';
import { addDynamicPromptsListener } from './listeners/promptChanged';
import { addSocketConnectedEventListener as addSocketConnectedListener } from './listeners/socketio/socketConnected';
import { addSocketDisconnectedEventListener as addSocketDisconnectedListener } from './listeners/socketio/socketDisconnected';
import { addGeneratorProgressEventListener as addGeneratorProgressListener } from './listeners/socketio/socketGeneratorProgress';
import { addGraphExecutionStateCompleteEventListener as addGraphExecutionStateCompleteListener } from './listeners/socketio/socketGraphExecutionStateComplete';
import { addInvocationCompleteEventListener as addInvocationCompleteListener } from './listeners/socketio/socketInvocationComplete';
import { addInvocationErrorEventListener as addInvocationErrorListener } from './listeners/socketio/socketInvocationError';
import { addInvocationRetrievalErrorEventListener } from './listeners/socketio/socketInvocationRetrievalError';
import { addInvocationStartedEventListener as addInvocationStartedListener } from './listeners/socketio/socketInvocationStarted';
import { addModelInstallEventListener } from './listeners/socketio/socketModelInstall';
import { addModelLoadEventListener } from './listeners/socketio/socketModelLoad';
import { addSocketQueueItemStatusChangedEventListener } from './listeners/socketio/socketQueueItemStatusChanged';
import { addSessionRetrievalErrorEventListener } from './listeners/socketio/socketSessionRetrievalError';
import { addSocketSubscribedEventListener as addSocketSubscribedListener } from './listeners/socketio/socketSubscribed';
import { addSocketUnsubscribedEventListener as addSocketUnsubscribedListener } from './listeners/socketio/socketUnsubscribed';
import { addStagingAreaImageSavedListener } from './listeners/stagingAreaImageSaved';
import { addUpdateAllNodesRequestedListener } from './listeners/updateAllNodesRequested';
import { addUpscaleRequestedListener } from './listeners/upscaleRequested';
import { addWorkflowLoadRequestedListener } from './listeners/workflowLoadRequested';
export const listenerMiddleware = createListenerMiddleware();
export type AppStartListening = TypedStartListening<RootState, AppDispatch>;
export const startAppListening = listenerMiddleware.startListening as AppStartListening;
export const addAppListener = addListener as TypedAddListener<RootState, AppDispatch>;
export type AppListenerEffect = ListenerEffect<UnknownAction, RootState, AppDispatch>;
const startAppListening = listenerMiddleware.startListening as AppStartListening;
/**
* The RTK listener middleware is a lightweight alternative sagas/observables.
@ -85,95 +68,88 @@ export type AppListenerEffect = ListenerEffect<UnknownAction, RootState, AppDisp
*/
// Image uploaded
addImageUploadedFulfilledListener();
addImageUploadedRejectedListener();
addImageUploadedFulfilledListener(startAppListening);
// Image selected
addInitialImageSelectedListener();
addInitialImageSelectedListener(startAppListening);
// Image deleted
addRequestedSingleImageDeletionListener();
addRequestedMultipleImageDeletionListener();
addImageDeletedPendingListener();
addImageDeletedFulfilledListener();
addImageDeletedRejectedListener();
addDeleteBoardAndImagesFulfilledListener();
addImageToDeleteSelectedListener();
addRequestedSingleImageDeletionListener(startAppListening);
addDeleteBoardAndImagesFulfilledListener(startAppListening);
addImageToDeleteSelectedListener(startAppListening);
// Image starred
addImagesStarredListener();
addImagesUnstarredListener();
addImagesStarredListener(startAppListening);
addImagesUnstarredListener(startAppListening);
// Gallery
addGalleryImageClickedListener();
addGalleryImageClickedListener(startAppListening);
// User Invoked
addEnqueueRequestedCanvasListener();
addEnqueueRequestedNodes();
addEnqueueRequestedLinear();
addAnyEnqueuedListener();
addBatchEnqueuedListener();
addEnqueueRequestedCanvasListener(startAppListening);
addEnqueueRequestedNodes(startAppListening);
addEnqueueRequestedLinear(startAppListening);
addAnyEnqueuedListener(startAppListening);
addBatchEnqueuedListener(startAppListening);
// Canvas actions
addCanvasSavedToGalleryListener();
addCanvasMaskSavedToGalleryListener();
addCanvasImageToControlNetListener();
addCanvasMaskToControlNetListener();
addCanvasDownloadedAsImageListener();
addCanvasCopiedToClipboardListener();
addCanvasMergedListener();
addStagingAreaImageSavedListener();
addCommitStagingAreaImageListener();
addCanvasSavedToGalleryListener(startAppListening);
addCanvasMaskSavedToGalleryListener(startAppListening);
addCanvasImageToControlNetListener(startAppListening);
addCanvasMaskToControlNetListener(startAppListening);
addCanvasDownloadedAsImageListener(startAppListening);
addCanvasCopiedToClipboardListener(startAppListening);
addCanvasMergedListener(startAppListening);
addStagingAreaImageSavedListener(startAppListening);
addCommitStagingAreaImageListener(startAppListening);
// Socket.IO
addGeneratorProgressListener();
addGraphExecutionStateCompleteListener();
addInvocationCompleteListener();
addInvocationErrorListener();
addInvocationStartedListener();
addSocketConnectedListener();
addSocketDisconnectedListener();
addSocketSubscribedListener();
addSocketUnsubscribedListener();
addModelLoadEventListener();
addModelInstallEventListener();
addSessionRetrievalErrorEventListener();
addInvocationRetrievalErrorEventListener();
addSocketQueueItemStatusChangedEventListener();
addBulkDownloadListeners();
addGeneratorProgressEventListener(startAppListening);
addGraphExecutionStateCompleteEventListener(startAppListening);
addInvocationCompleteEventListener(startAppListening);
addInvocationErrorEventListener(startAppListening);
addInvocationStartedEventListener(startAppListening);
addSocketConnectedEventListener(startAppListening);
addSocketDisconnectedEventListener(startAppListening);
addSocketSubscribedEventListener(startAppListening);
addSocketUnsubscribedEventListener(startAppListening);
addModelLoadEventListener(startAppListening);
addModelInstallEventListener(startAppListening);
addSessionRetrievalErrorEventListener(startAppListening);
addInvocationRetrievalErrorEventListener(startAppListening);
addSocketQueueItemStatusChangedEventListener(startAppListening);
addBulkDownloadListeners(startAppListening);
// ControlNet
addControlNetImageProcessedListener();
addControlNetAutoProcessListener();
addControlNetImageProcessedListener(startAppListening);
addControlNetAutoProcessListener(startAppListening);
// Boards
addImageAddedToBoardFulfilledListener();
addImageAddedToBoardRejectedListener();
addImageRemovedFromBoardFulfilledListener();
addImageRemovedFromBoardRejectedListener();
addBoardIdSelectedListener();
addImageAddedToBoardFulfilledListener(startAppListening);
addImageRemovedFromBoardFulfilledListener(startAppListening);
addBoardIdSelectedListener(startAppListening);
// Node schemas
addGetOpenAPISchemaListener();
addGetOpenAPISchemaListener(startAppListening);
// Workflows
addWorkflowLoadRequestedListener();
addUpdateAllNodesRequestedListener();
addWorkflowLoadRequestedListener(startAppListening);
addUpdateAllNodesRequestedListener(startAppListening);
// DND
addImageDroppedListener();
addImageDroppedListener(startAppListening);
// Models
addModelSelectedListener();
addModelSelectedListener(startAppListening);
// app startup
addAppStartedListener();
addModelsLoadedListener();
addAppConfigReceivedListener();
addFirstListImagesListener();
addAppStartedListener(startAppListening);
addModelsLoadedListener(startAppListening);
addAppConfigReceivedListener(startAppListening);
addFirstListImagesListener(startAppListening);
// Ad-hoc upscale workflwo
addUpscaleRequestedListener();
addUpscaleRequestedListener(startAppListening);
// Dynamic prompts
addDynamicPromptsListener();
addDynamicPromptsListener(startAppListening);

View File

@ -1,15 +1,14 @@
import { isAnyOf } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasBatchIdsReset, commitStagingAreaImage, discardStagedImages } from 'features/canvas/store/canvasSlice';
import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { queueApi } from 'services/api/endpoints/queue';
import { startAppListening } from '..';
const matcher = isAnyOf(commitStagingAreaImage, discardStagedImages);
export const addCommitStagingAreaImageListener = () => {
export const addCommitStagingAreaImageListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher,
effect: async (_, { dispatch, getState }) => {

View File

@ -1,15 +1,11 @@
import { createAction } from '@reduxjs/toolkit';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { imageSelected } from 'features/gallery/store/gallerySlice';
import { IMAGE_CATEGORIES } from 'features/gallery/store/types';
import { imagesApi } from 'services/api/endpoints/images';
import type { ImageCache } from 'services/api/types';
import { getListImagesUrl, imagesSelectors } from 'services/api/util';
import { startAppListening } from '..';
export const appStarted = createAction('app/appStarted');
export const addFirstListImagesListener = () => {
export const addFirstListImagesListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.listImages.matchFulfilled,
effect: async (action, { dispatch, unsubscribe, cancelActiveListeners }) => {

View File

@ -1,8 +1,7 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { queueApi, selectQueueStatus } from 'services/api/endpoints/queue';
import { startAppListening } from '..';
export const addAnyEnqueuedListener = () => {
export const addAnyEnqueuedListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: queueApi.endpoints.enqueueBatch.matchFulfilled,
effect: async (_, { dispatch, getState }) => {

View File

@ -1,10 +1,9 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { setInfillMethod } from 'features/parameters/store/generationSlice';
import { shouldUseNSFWCheckerChanged, shouldUseWatermarkerChanged } from 'features/system/store/systemSlice';
import { appInfoApi } from 'services/api/endpoints/appInfo';
import { startAppListening } from '..';
export const addAppConfigReceivedListener = () => {
export const addAppConfigReceivedListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled,
effect: async (action, { getState, dispatch }) => {

View File

@ -1,10 +1,9 @@
import { createAction } from '@reduxjs/toolkit';
import { startAppListening } from '..';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
export const appStarted = createAction('app/appStarted');
export const addAppStartedListener = () => {
export const addAppStartedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: appStarted,
effect: async (action, { unsubscribe, cancelActiveListeners }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { toast } from 'common/util/toast';
import { zPydanticValidationError } from 'features/system/store/zodSchemas';
@ -6,9 +7,7 @@ import { t } from 'i18next';
import { truncate, upperFirst } from 'lodash-es';
import { queueApi } from 'services/api/endpoints/queue';
import { startAppListening } from '..';
export const addBatchEnqueuedListener = () => {
export const addBatchEnqueuedListener = (startAppListening: AppStartListening) => {
// success
startAppListening({
matcher: queueApi.endpoints.enqueueBatch.matchFulfilled,

View File

@ -1,3 +1,4 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { resetCanvas } from 'features/canvas/store/canvasSlice';
import { controlAdaptersReset } from 'features/controlAdapters/store/controlAdaptersSlice';
import { getImageUsage } from 'features/deleteImageModal/store/selectors';
@ -5,9 +6,7 @@ import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
import { clearInitialImage } from 'features/parameters/store/generationSlice';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addDeleteBoardAndImagesFulfilledListener = () => {
export const addDeleteBoardAndImagesFulfilledListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.deleteBoardAndImages.matchFulfilled,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,12 +1,11 @@
import { isAnyOf } from '@reduxjs/toolkit';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { boardIdSelected, galleryViewChanged, imageSelected } from 'features/gallery/store/gallerySlice';
import { ASSETS_CATEGORIES, IMAGE_CATEGORIES } from 'features/gallery/store/types';
import { imagesApi } from 'services/api/endpoints/images';
import { imagesSelectors } from 'services/api/util';
import { startAppListening } from '..';
export const addBoardIdSelectedListener = () => {
export const addBoardIdSelectedListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: isAnyOf(boardIdSelected, galleryViewChanged),
effect: async (action, { getState, dispatch, condition, cancelActiveListeners }) => {

View File

@ -1,7 +1,7 @@
import type { UseToastOptions } from '@invoke-ai/ui-library';
import { ExternalLink } from '@invoke-ai/ui-library';
import { logger } from 'app/logging/logger';
import { startAppListening } from 'app/store/middleware/listenerMiddleware';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { toast } from 'common/util/toast';
import { t } from 'i18next';
import { imagesApi } from 'services/api/endpoints/images';
@ -13,7 +13,7 @@ import {
const log = logger('images');
export const addBulkDownloadListeners = () => {
export const addBulkDownloadListeners = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.bulkDownloadImages.matchFulfilled,
effect: async (action) => {

View File

@ -1,13 +1,12 @@
import { $logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasCopiedToClipboard } from 'features/canvas/store/actions';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice';
import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard';
import { t } from 'i18next';
import { startAppListening } from '..';
export const addCanvasCopiedToClipboardListener = () => {
export const addCanvasCopiedToClipboardListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: canvasCopiedToClipboard,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,13 +1,12 @@
import { $logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasDownloadedAsImage } from 'features/canvas/store/actions';
import { downloadBlob } from 'features/canvas/util/downloadBlob';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { startAppListening } from '..';
export const addCanvasDownloadedAsImageListener = () => {
export const addCanvasDownloadedAsImageListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: canvasDownloadedAsImage,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasImageToControlAdapter } from 'features/canvas/store/actions';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { controlAdapterImageChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
@ -6,9 +7,7 @@ import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addCanvasImageToControlNetListener = () => {
export const addCanvasImageToControlNetListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: canvasImageToControlAdapter,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,13 +1,12 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasMaskSavedToGallery } from 'features/canvas/store/actions';
import { getCanvasData } from 'features/canvas/util/getCanvasData';
import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addCanvasMaskSavedToGalleryListener = () => {
export const addCanvasMaskSavedToGalleryListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: canvasMaskSavedToGallery,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasMaskToControlAdapter } from 'features/canvas/store/actions';
import { getCanvasData } from 'features/canvas/util/getCanvasData';
import { controlAdapterImageChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
@ -6,9 +7,7 @@ import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addCanvasMaskToControlNetListener = () => {
export const addCanvasMaskToControlNetListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: canvasMaskToControlAdapter,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,4 +1,5 @@
import { $logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasMerged } from 'features/canvas/store/actions';
import { $canvasBaseLayer } from 'features/canvas/store/canvasNanostore';
import { setMergedCanvas } from 'features/canvas/store/canvasSlice';
@ -7,9 +8,7 @@ import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addCanvasMergedListener = () => {
export const addCanvasMergedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: canvasMerged,
effect: async (action, { dispatch }) => {

View File

@ -1,13 +1,12 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { canvasSavedToGallery } from 'features/canvas/store/actions';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addCanvasSavedToGalleryListener = () => {
export const addCanvasSavedToGalleryListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: canvasSavedToGallery,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,5 +1,6 @@
import type { AnyListenerPredicate } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import type { RootState } from 'app/store/store';
import { controlAdapterImageProcessed } from 'features/controlAdapters/store/actions';
import {
@ -12,8 +13,6 @@ import {
} from 'features/controlAdapters/store/controlAdaptersSlice';
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
import { startAppListening } from '..';
type AnyControlAdapterParamChangeAction =
| ReturnType<typeof controlAdapterProcessorParamsChanged>
| ReturnType<typeof controlAdapterModelChanged>
@ -67,7 +66,7 @@ const DEBOUNCE_MS = 300;
*
* The network request is debounced.
*/
export const addControlNetAutoProcessListener = () => {
export const addControlNetAutoProcessListener = (startAppListening: AppStartListening) => {
startAppListening({
predicate,
effect: async (action, { dispatch, cancelActiveListeners, delay }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { controlAdapterImageProcessed } from 'features/controlAdapters/store/actions';
import {
@ -16,9 +17,7 @@ import { queueApi } from 'services/api/endpoints/queue';
import type { BatchConfig, ImageDTO } from 'services/api/types';
import { socketInvocationComplete } from 'services/events/actions';
import { startAppListening } from '..';
export const addControlNetImageProcessedListener = () => {
export const addControlNetImageProcessedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: controlAdapterImageProcessed,
effect: async (action, { dispatch, getState, take }) => {

View File

@ -1,5 +1,6 @@
import { logger } from 'app/logging/logger';
import { enqueueRequested } from 'app/store/actions';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
import { parseify } from 'common/util/serialize';
import { canvasBatchIdAdded, stagingAreaInitialized } from 'features/canvas/store/canvasSlice';
@ -13,8 +14,6 @@ import { imagesApi } from 'services/api/endpoints/images';
import { queueApi } from 'services/api/endpoints/queue';
import type { ImageDTO } from 'services/api/types';
import { startAppListening } from '..';
/**
* This listener is responsible invoking the canvas. This involves a number of steps:
*
@ -28,7 +27,7 @@ import { startAppListening } from '..';
* 8. Initialize the staging area if not yet initialized
* 9. Dispatch the sessionReadyToInvoke action to invoke the session
*/
export const addEnqueueRequestedCanvasListener = () => {
export const addEnqueueRequestedCanvasListener = (startAppListening: AppStartListening) => {
startAppListening({
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
enqueueRequested.match(action) && action.payload.tabName === 'unifiedCanvas',

View File

@ -1,4 +1,5 @@
import { enqueueRequested } from 'app/store/actions';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { prepareLinearUIBatch } from 'features/nodes/util/graph/buildLinearBatchConfig';
import { buildLinearImageToImageGraph } from 'features/nodes/util/graph/buildLinearImageToImageGraph';
import { buildLinearSDXLImageToImageGraph } from 'features/nodes/util/graph/buildLinearSDXLImageToImageGraph';
@ -6,9 +7,7 @@ import { buildLinearSDXLTextToImageGraph } from 'features/nodes/util/graph/build
import { buildLinearTextToImageGraph } from 'features/nodes/util/graph/buildLinearTextToImageGraph';
import { queueApi } from 'services/api/endpoints/queue';
import { startAppListening } from '..';
export const addEnqueueRequestedLinear = () => {
export const addEnqueueRequestedLinear = (startAppListening: AppStartListening) => {
startAppListening({
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
enqueueRequested.match(action) && (action.payload.tabName === 'txt2img' || action.payload.tabName === 'img2img'),

View File

@ -1,12 +1,11 @@
import { enqueueRequested } from 'app/store/actions';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { buildNodesGraph } from 'features/nodes/util/graph/buildNodesGraph';
import { buildWorkflowWithValidation } from 'features/nodes/util/workflow/buildWorkflow';
import { queueApi } from 'services/api/endpoints/queue';
import type { BatchConfig } from 'services/api/types';
import { startAppListening } from '..';
export const addEnqueueRequestedNodes = () => {
export const addEnqueueRequestedNodes = (startAppListening: AppStartListening) => {
startAppListening({
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
enqueueRequested.match(action) && action.payload.tabName === 'nodes',

View File

@ -1,12 +1,11 @@
import { createAction } from '@reduxjs/toolkit';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors';
import { selectionChanged } from 'features/gallery/store/gallerySlice';
import { imagesApi } from 'services/api/endpoints/images';
import type { ImageDTO } from 'services/api/types';
import { imagesSelectors } from 'services/api/util';
import { startAppListening } from '..';
export const galleryImageClicked = createAction<{
imageDTO: ImageDTO;
shiftKey: boolean;
@ -25,7 +24,7 @@ export const galleryImageClicked = createAction<{
* is much more responsive.
*/
export const addGalleryImageClickedListener = () => {
export const addGalleryImageClickedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: galleryImageClicked,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,13 +1,12 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
import { parseSchema } from 'features/nodes/util/schema/parseSchema';
import { size } from 'lodash-es';
import { appInfoApi } from 'services/api/endpoints/appInfo';
import { startAppListening } from '..';
export const addGetOpenAPISchemaListener = () => {
export const addGetOpenAPISchemaListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: appInfoApi.endpoints.getOpenAPISchema.matchFulfilled,
effect: (action, { dispatch, getState }) => {

View File

@ -1,9 +1,8 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addImageAddedToBoardFulfilledListener = () => {
export const addImageAddedToBoardFulfilledListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.addImageToBoard.matchFulfilled,
effect: (action) => {
@ -15,9 +14,7 @@ export const addImageAddedToBoardFulfilledListener = () => {
log.debug({ board_id, imageDTO }, 'Image added to board');
},
});
};
export const addImageAddedToBoardRejectedListener = () => {
startAppListening({
matcher: imagesApi.endpoints.addImageToBoard.matchRejected,
effect: (action) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { resetCanvas } from 'features/canvas/store/canvasSlice';
import {
controlAdapterImageChanged,
@ -19,9 +20,7 @@ import { api } from 'services/api';
import { imagesApi } from 'services/api/endpoints/images';
import { imagesSelectors } from 'services/api/util';
import { startAppListening } from '..';
export const addRequestedSingleImageDeletionListener = () => {
export const addRequestedSingleImageDeletionListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: imageDeletionConfirmed,
effect: async (action, { dispatch, getState, condition }) => {
@ -134,12 +133,7 @@ export const addRequestedSingleImageDeletionListener = () => {
}
},
});
};
/**
* Called when the user requests an image deletion
*/
export const addRequestedMultipleImageDeletionListener = () => {
startAppListening({
actionCreator: imageDeletionConfirmed,
effect: async (action, { dispatch, getState }) => {
@ -224,24 +218,14 @@ export const addRequestedMultipleImageDeletionListener = () => {
}
},
});
};
/**
* Called when the actual delete request is sent to the server
*/
export const addImageDeletedPendingListener = () => {
startAppListening({
matcher: imagesApi.endpoints.deleteImage.matchPending,
effect: () => {
//
},
});
};
/**
* Called on successful delete
*/
export const addImageDeletedFulfilledListener = () => {
startAppListening({
matcher: imagesApi.endpoints.deleteImage.matchFulfilled,
effect: (action) => {
@ -249,12 +233,7 @@ export const addImageDeletedFulfilledListener = () => {
log.debug({ imageDTO: action.meta.arg.originalArgs }, 'Image deleted');
},
});
};
/**
* Called on failed delete
*/
export const addImageDeletedRejectedListener = () => {
startAppListening({
matcher: imagesApi.endpoints.deleteImage.matchRejected,
effect: (action) => {

View File

@ -1,5 +1,6 @@
import { createAction } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
import {
@ -12,14 +13,12 @@ import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice';
import { initialImageChanged, selectOptimalDimension } from 'features/parameters/store/generationSlice';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '../';
export const dndDropped = createAction<{
overData: TypesafeDroppableData;
activeData: TypesafeDraggableData;
}>('dnd/dndDropped');
export const addImageDroppedListener = () => {
export const addImageDroppedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: dndDropped,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,9 +1,8 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addImageRemovedFromBoardFulfilledListener = () => {
export const addImageRemovedFromBoardFulfilledListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.removeImageFromBoard.matchFulfilled,
effect: (action) => {
@ -13,9 +12,7 @@ export const addImageRemovedFromBoardFulfilledListener = () => {
log.debug({ imageDTO }, 'Image removed from board');
},
});
};
export const addImageRemovedFromBoardRejectedListener = () => {
startAppListening({
matcher: imagesApi.endpoints.removeImageFromBoard.matchRejected,
effect: (action) => {

View File

@ -1,10 +1,9 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { imageDeletionConfirmed } from 'features/deleteImageModal/store/actions';
import { selectImageUsage } from 'features/deleteImageModal/store/selectors';
import { imagesToDeleteSelected, isModalOpenChanged } from 'features/deleteImageModal/store/slice';
import { startAppListening } from '..';
export const addImageToDeleteSelectedListener = () => {
export const addImageToDeleteSelectedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: imagesToDeleteSelected,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,5 +1,6 @@
import type { UseToastOptions } from '@invoke-ai/ui-library';
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
import {
controlAdapterImageChanged,
@ -13,9 +14,7 @@ import { omit } from 'lodash-es';
import { boardsApi } from 'services/api/endpoints/boards';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addImageUploadedFulfilledListener = () => {
export const addImageUploadedFulfilledListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.uploadImage.matchFulfilled,
effect: (action, { dispatch, getState }) => {
@ -133,9 +132,7 @@ export const addImageUploadedFulfilledListener = () => {
}
},
});
};
export const addImageUploadedRejectedListener = () => {
startAppListening({
matcher: imagesApi.endpoints.uploadImage.matchRejected,
effect: (action, { dispatch }) => {

View File

@ -1,10 +1,9 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { selectionChanged } from 'features/gallery/store/gallerySlice';
import { imagesApi } from 'services/api/endpoints/images';
import type { ImageDTO } from 'services/api/types';
import { startAppListening } from '..';
export const addImagesStarredListener = () => {
export const addImagesStarredListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.starImages.matchFulfilled,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,10 +1,9 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { selectionChanged } from 'features/gallery/store/gallerySlice';
import { imagesApi } from 'services/api/endpoints/images';
import type { ImageDTO } from 'services/api/types';
import { startAppListening } from '..';
export const addImagesUnstarredListener = () => {
export const addImagesUnstarredListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher: imagesApi.endpoints.unstarImages.matchFulfilled,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,12 +1,11 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { initialImageSelected } from 'features/parameters/store/actions';
import { initialImageChanged } from 'features/parameters/store/generationSlice';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import { t } from 'i18next';
import { startAppListening } from '..';
export const addInitialImageSelectedListener = () => {
export const addInitialImageSelectedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: initialImageSelected,
effect: (action, { dispatch }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import {
controlAdapterIsEnabledChanged,
selectControlAdapterAll,
@ -12,9 +13,7 @@ import { makeToast } from 'features/system/util/makeToast';
import { t } from 'i18next';
import { forEach } from 'lodash-es';
import { startAppListening } from '..';
export const addModelSelectedListener = () => {
export const addModelSelectedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: modelSelected,
effect: (action, { getState, dispatch }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import {
controlAdapterModelCleared,
selectAllControlNets,
@ -13,9 +14,7 @@ import { forEach, some } from 'lodash-es';
import { mainModelsAdapterSelectors, modelsApi, vaeModelsAdapterSelectors } from 'services/api/endpoints/models';
import type { TypeGuardFor } from 'services/api/types';
import { startAppListening } from '..';
export const addModelsLoadedListener = () => {
export const addModelsLoadedListener = (startAppListening: AppStartListening) => {
startAppListening({
predicate: (action): action is TypeGuardFor<typeof modelsApi.endpoints.getMainModels.matchFulfilled> =>
modelsApi.endpoints.getMainModels.matchFulfilled(action) &&

View File

@ -1,4 +1,5 @@
import { isAnyOf } from '@reduxjs/toolkit';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import {
combinatorialToggled,
isErrorChanged,
@ -13,11 +14,9 @@ import { setPositivePrompt } from 'features/parameters/store/generationSlice';
import { utilitiesApi } from 'services/api/endpoints/utilities';
import { socketConnected } from 'services/events/actions';
import { startAppListening } from '..';
const matcher = isAnyOf(setPositivePrompt, combinatorialToggled, maxPromptsChanged, maxPromptsReset, socketConnected);
export const addDynamicPromptsListener = () => {
export const addDynamicPromptsListener = (startAppListening: AppStartListening) => {
startAppListening({
matcher,
effect: async (action, { dispatch, getState, cancelActiveListeners, delay }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { $baseUrl } from 'app/store/nanostores/baseUrl';
import { isEqual } from 'lodash-es';
import { atom } from 'nanostores';
@ -6,13 +7,11 @@ import { api } from 'services/api';
import { queueApi, selectQueueStatus } from 'services/api/endpoints/queue';
import { socketConnected } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
const $isFirstConnection = atom(true);
export const addSocketConnectedEventListener = () => {
export const addSocketConnectedEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketConnected,
effect: async (action, { dispatch, getState, cancelActiveListeners, delay }) => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketDisconnected } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addSocketDisconnectedEventListener = () => {
export const addSocketDisconnectedEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketDisconnected,
effect: () => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketGeneratorProgress } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addGeneratorProgressEventListener = () => {
export const addGeneratorProgressEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketGeneratorProgress,
effect: (action) => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketGraphExecutionStateComplete } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addGraphExecutionStateCompleteEventListener = () => {
export const addGraphExecutionStateCompleteEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketGraphExecutionStateComplete,
effect: (action) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
import { boardIdSelected, galleryViewChanged, imageSelected } from 'features/gallery/store/gallerySlice';
@ -10,14 +11,12 @@ import { imagesApi } from 'services/api/endpoints/images';
import { imagesAdapter } from 'services/api/util';
import { socketInvocationComplete } from 'services/events/actions';
import { startAppListening } from '../..';
// These nodes output an image, but do not actually *save* an image, so we don't want to handle the gallery logic on them
const nodeTypeDenylist = ['load_image', 'image'];
const log = logger('socketio');
export const addInvocationCompleteEventListener = () => {
export const addInvocationCompleteEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketInvocationComplete,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketInvocationError } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addInvocationErrorEventListener = () => {
export const addInvocationErrorEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketInvocationError,
effect: (action) => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketInvocationRetrievalError } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addInvocationRetrievalErrorEventListener = () => {
export const addInvocationRetrievalErrorEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketInvocationRetrievalError,
effect: (action) => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketInvocationStarted } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addInvocationStartedEventListener = () => {
export const addInvocationStartedEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketInvocationStarted,
effect: (action) => {

View File

@ -1,3 +1,4 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { api } from 'services/api';
import { modelsApi } from 'services/api/endpoints/models';
import {
@ -6,19 +7,18 @@ import {
socketModelInstallError,
} from 'services/events/actions';
import { startAppListening } from '../..';
export const addModelInstallEventListener = () => {
export const addModelInstallEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketModelInstallDownloading,
effect: async (action, { dispatch }) => {
const { bytes, id } = action.payload.data;
const { bytes, total_bytes, id } = action.payload.data;
dispatch(
modelsApi.util.updateQueryData('getModelImports', undefined, (draft) => {
const modelImport = draft.find((m) => m.id === id);
if (modelImport) {
modelImport.bytes = bytes;
modelImport.total_bytes = total_bytes;
modelImport.status = 'downloading';
}
return draft;
@ -48,7 +48,7 @@ export const addModelInstallEventListener = () => {
startAppListening({
actionCreator: socketModelInstallError,
effect: (action, { dispatch }) => {
const { id, error_type } = action.payload.data;
const { id, error, error_type } = action.payload.data;
dispatch(
modelsApi.util.updateQueryData('getModelImports', undefined, (draft) => {
@ -56,6 +56,7 @@ export const addModelInstallEventListener = () => {
if (modelImport) {
modelImport.status = 'error';
modelImport.error_reason = error_type;
modelImport.error = error;
}
return draft;
})

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketModelLoadCompleted, socketModelLoadStarted } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addModelLoadEventListener = () => {
export const addModelLoadEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketModelLoadStarted,
effect: (action) => {

View File

@ -1,12 +1,11 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { queueApi, queueItemsAdapter } from 'services/api/endpoints/queue';
import { socketQueueItemStatusChanged } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addSocketQueueItemStatusChangedEventListener = () => {
export const addSocketQueueItemStatusChangedEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketQueueItemStatusChanged,
effect: async (action, { dispatch }) => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketSessionRetrievalError } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addSessionRetrievalErrorEventListener = () => {
export const addSessionRetrievalErrorEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketSessionRetrievalError,
effect: (action) => {

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketSubscribedSession } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addSocketSubscribedEventListener = () => {
export const addSocketSubscribedEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketSubscribedSession,
effect: (action) => {

View File

@ -1,10 +1,9 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { socketUnsubscribedSession } from 'services/events/actions';
import { startAppListening } from '../..';
const log = logger('socketio');
export const addSocketUnsubscribedEventListener = () => {
export const addSocketUnsubscribedEventListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: socketUnsubscribedSession,
effect: (action) => {

View File

@ -1,11 +1,10 @@
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { stagingAreaImageSaved } from 'features/canvas/store/actions';
import { addToast } from 'features/system/store/systemSlice';
import { t } from 'i18next';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
export const addStagingAreaImageSavedListener = () => {
export const addStagingAreaImageSavedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: stagingAreaImageSaved,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { updateAllNodesRequested } from 'features/nodes/store/actions';
import { nodeReplaced } from 'features/nodes/store/nodesSlice';
import { NodeUpdateError } from 'features/nodes/types/error';
@ -8,9 +9,7 @@ import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import { t } from 'i18next';
import { startAppListening } from '..';
export const addUpdateAllNodesRequestedListener = () => {
export const addUpdateAllNodesRequestedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: updateAllNodesRequested,
effect: (action, { dispatch, getState }) => {

View File

@ -1,5 +1,6 @@
import { createAction } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { buildAdHocUpscaleGraph } from 'features/nodes/util/graph/buildAdHocUpscaleGraph';
import { createIsAllowedToUpscaleSelector } from 'features/parameters/hooks/useIsAllowedToUpscale';
@ -8,11 +9,9 @@ import { t } from 'i18next';
import { queueApi } from 'services/api/endpoints/queue';
import type { BatchConfig, ImageDTO } from 'services/api/types';
import { startAppListening } from '..';
export const upscaleRequested = createAction<{ imageDTO: ImageDTO }>(`upscale/upscaleRequested`);
export const addUpscaleRequestedListener = () => {
export const addUpscaleRequestedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: upscaleRequested,
effect: async (action, { dispatch, getState }) => {

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { workflowLoaded, workflowLoadRequested } from 'features/nodes/store/actions';
import { $flow } from 'features/nodes/store/reactFlowInstance';
@ -10,9 +11,7 @@ import { t } from 'i18next';
import { z } from 'zod';
import { fromZodError } from 'zod-validation-error';
import { startAppListening } from '..';
export const addWorkflowLoadRequestedListener = () => {
export const addWorkflowLoadRequestedListener = (startAppListening: AppStartListening) => {
startAppListening({
actionCreator: workflowLoadRequested,
effect: (action, { dispatch, getState }) => {

View File

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

View File

@ -11,7 +11,7 @@ declare global {
/**
* Raised when the redux store is unable to be retrieved.
*/
export class ReduxStoreNotInitialized extends Error {
class ReduxStoreNotInitialized extends Error {
/**
* Create ReduxStoreNotInitialized
* @param {String} message

View File

@ -136,7 +136,7 @@ const unserialize: UnserializeFunction = (data, key) => {
}
};
export const serialize: SerializeFunction = (data, key) => {
const serialize: SerializeFunction = (data, key) => {
const persistConfig = persistConfigs[key as keyof typeof persistConfigs];
if (!persistConfig) {
throw new Error(`No persist config for slice "${key}"`);
@ -185,7 +185,6 @@ export const createStore = (uniqueStoreKey?: string, persist = true) =>
},
});
export type AppGetState = ReturnType<ReturnType<typeof createStore>['getState']>;
export type RootState = ReturnType<ReturnType<typeof createStore>['getState']>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type AppThunkDispatch = ThunkDispatch<RootState, any, UnknownAction>;

View File

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

View File

@ -6,7 +6,7 @@ export type Feature =
| 'paramNegativeConditioning'
| 'paramPositiveConditioning'
| 'paramScheduler'
| 'compositingBlur'
| 'compositingMaskBlur'
| 'compositingBlurMethod'
| 'compositingCoherencePass'
| 'compositingCoherenceMode'

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
// https://stackoverflow.com/a/73731908
import { useCallback, useEffect, useState } from 'react';
export type UseSingleAndDoubleClickOptions = {
type UseSingleAndDoubleClickOptions = {
onSingleClick: () => void;
onDoubleClick: () => void;
latency?: number;

View File

@ -1,7 +1,5 @@
export type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };
type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };
export interface JSONObject {
[k: string]: JSONValue;
}
export interface JSONArray extends Array<JSONValue> {}

View File

@ -1,7 +1,7 @@
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
import { random } from 'lodash-es';
export type GenerateSeedsArg = {
type GenerateSeedsArg = {
count: number;
start?: number;
min?: number;
@ -16,5 +16,3 @@ export const generateSeeds = ({ count, start, min = NUMPY_RAND_MIN, max = NUMPY_
}
return seeds;
};
export const generateOneSeed = (min: number = NUMPY_RAND_MIN, max: number = NUMPY_RAND_MAX) => random(min, max);

View File

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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ export const $tool = atom<CanvasTool>('move');
export const $toolStash = atom<CanvasTool | null>(null);
export const $isDrawing = atom<boolean>(false);
export const $isMouseOverBoundingBox = atom<boolean>(false);
export const $isMoveBoundingBoxKeyHeld = atom<boolean>(false);
const $isMoveBoundingBoxKeyHeld = atom<boolean>(false);
export const $isMoveStageKeyHeld = atom<boolean>(false);
export const $isMovingBoundingBox = atom<boolean>(false);
export const $isMovingStage = atom<boolean>(false);

View File

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

View File

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

View File

@ -10,14 +10,12 @@ export const LAYER_NAMES_DICT: { label: string; value: CanvasLayer }[] = [
{ label: 'Mask', value: 'mask' },
];
export const LAYER_NAMES = ['base', 'mask'] as const;
export const zBoundingBoxScaleMethod = z.enum(['none', 'auto', 'manual']);
const zBoundingBoxScaleMethod = z.enum(['none', 'auto', 'manual']);
export type BoundingBoxScaleMethod = z.infer<typeof zBoundingBoxScaleMethod>;
export const isBoundingBoxScaleMethod = (v: unknown): v is BoundingBoxScaleMethod =>
zBoundingBoxScaleMethod.safeParse(v).success;
export type CanvasDrawingTool = 'brush' | 'eraser';
type CanvasDrawingTool = 'brush' | 'eraser';
export type CanvasTool = CanvasDrawingTool | 'move' | 'colorPicker';
@ -55,7 +53,7 @@ export type CanvasBaseLine = {
clip?: IRect;
};
export type CanvasFillRect = {
type CanvasFillRect = {
kind: 'fillRect';
layer: 'base';
x: number;
@ -65,7 +63,7 @@ export type CanvasFillRect = {
color: RgbaColor;
};
export type CanvasEraseRect = {
type CanvasEraseRect = {
kind: 'eraseRect';
layer: 'base';
x: number;
@ -74,7 +72,7 @@ export type CanvasEraseRect = {
height: number;
};
export type CanvasObject = CanvasImage | CanvasBaseLine | CanvasMaskLine | CanvasFillRect | CanvasEraseRect;
type CanvasObject = CanvasImage | CanvasBaseLine | CanvasMaskLine | CanvasFillRect | CanvasEraseRect;
export type CanvasLayerState = {
objects: CanvasObject[];
@ -85,11 +83,6 @@ export type CanvasLayerState = {
};
};
export type CanvasSession = {
sessionId: string;
boundingBox: IRect;
};
// type guards
export const isCanvasMaskLine = (obj: CanvasObject): obj is CanvasMaskLine =>
obj.kind === 'line' && obj.layer === 'mask';
@ -112,7 +105,6 @@ export interface CanvasState {
_version: 1;
boundingBoxCoordinates: Vector2d;
boundingBoxDimensions: Dimensions;
boundingBoxPreviewFill: RgbaColor;
boundingBoxScaleMethod: BoundingBoxScaleMethod;
brushColor: RgbaColor;
brushSize: number;

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import { Box, Flex, FormControl, FormLabel, Icon, IconButton, Switch } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import ParamControlAdapterModel from 'features/controlAdapters/components/parameters/ParamControlAdapterModel';
import { useControlAdapterIsEnabled } from 'features/controlAdapters/hooks/useControlAdapterIsEnabled';
import { useControlAdapterType } from 'features/controlAdapters/hooks/useControlAdapterType';
import {

View File

@ -17,7 +17,7 @@ import NormalBaeProcessor from './processors/NormalBaeProcessor';
import PidiProcessor from './processors/PidiProcessor';
import ZoeDepthProcessor from './processors/ZoeDepthProcessor';
export type Props = {
type Props = {
id: string;
};

View File

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

View File

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

View File

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

View File

@ -18,30 +18,26 @@ type BaseDropData = {
id: string;
};
export type CurrentImageDropData = BaseDropData & {
type CurrentImageDropData = BaseDropData & {
actionType: 'SET_CURRENT_IMAGE';
};
export type InitialImageDropData = BaseDropData & {
type InitialImageDropData = BaseDropData & {
actionType: 'SET_INITIAL_IMAGE';
};
export type ControlAdapterDropData = BaseDropData & {
type ControlAdapterDropData = BaseDropData & {
actionType: 'SET_CONTROL_ADAPTER_IMAGE';
context: {
id: string;
};
};
export type IPAdapterImageDropData = BaseDropData & {
actionType: 'SET_IP_ADAPTER_IMAGE';
};
export type CanvasInitialImageDropData = BaseDropData & {
actionType: 'SET_CANVAS_INITIAL_IMAGE';
};
export type NodesImageDropData = BaseDropData & {
type NodesImageDropData = BaseDropData & {
actionType: 'SET_NODES_IMAGE';
context: {
nodeId: string;
@ -71,7 +67,7 @@ type BaseDragData = {
id: string;
};
export type NodeFieldDraggableData = BaseDragData & {
type NodeFieldDraggableData = BaseDragData & {
payloadType: 'NODE_FIELD';
payload: {
nodeId: string;
@ -114,7 +110,7 @@ export interface TypesafeActive extends Omit<Active, 'data'> {
data: React.MutableRefObject<TypesafeDraggableData | undefined>;
}
export interface TypesafeOver extends Omit<Over, 'data'> {
interface TypesafeOver extends Omit<Over, 'data'> {
data: React.MutableRefObject<TypesafeDroppableData | undefined>;
}
@ -127,10 +123,10 @@ interface DragEvent {
}
export interface DragStartEvent extends Pick<DragEvent, 'active'> {}
export interface DragMoveEvent extends DragEvent {}
export interface DragOverEvent extends DragMoveEvent {}
interface DragMoveEvent extends DragEvent {}
interface DragOverEvent extends DragMoveEvent {}
export interface DragEndEvent extends DragEvent {}
export interface DragCancelEvent extends DragEndEvent {}
interface DragCancelEvent extends DragEndEvent {}
export interface DndContextTypesafeProps
extends Omit<DndContextProps, 'onDragStart' | 'onDragMove' | 'onDragOver' | 'onDragEnd' | 'onDragCancel'> {

View File

@ -1,24 +0,0 @@
import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { combinatorialToggled } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const ParamDynamicPromptsCombinatorial = () => {
const combinatorial = useAppSelector((s) => s.dynamicPrompts.combinatorial);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const handleChange = useCallback(() => {
dispatch(combinatorialToggled());
}, [dispatch]);
return (
<FormControl>
<FormLabel>{t('dynamicPrompts.combinatorial')}</FormLabel>
<Switch isChecked={combinatorial} onChange={handleChange} />
</FormControl>
);
};
export default memo(ParamDynamicPromptsCombinatorial);

Some files were not shown because too many files have changed in this diff Show More