From 82e8b92ba079622533420b49db4120dc877bd656 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:16:19 +1100 Subject: [PATCH] feat(ui): display toast when enabling t2i/controlnet and disabling the other --- invokeai/frontend/web/public/locales/en.json | 3 + .../middleware/listenerMiddleware/index.ts | 5 ++ .../listeners/controlAdapterAddedOrEnabled.ts | 87 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterAddedOrEnabled.ts diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index e570f5beac..4816e0162b 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -139,6 +139,9 @@ "addControlNet": "Add $t(common.controlNet)", "addIPAdapter": "Add $t(common.ipAdapter)", "addT2IAdapter": "Add $t(common.t2iAdapter)", + "controlNetEnabledT2IDisabled": "$t(common.controlNet) enabled, $t(common.t2iAdapter)s disabled", + "t2iEnabledControlNetDisabled": "$t(common.t2iAdapter) enabled, $t(common.controlNet)s disabled", + "controlNetT2IMutexDesc": "$t(common.controlNet) and $t(common.t2iAdapter) at same time is currently unsupported.", "amult": "a_mult", "autoConfigure": "Auto configure processor", "balanced": "Balanced", diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts index 677b0fd20c..cbc88966a7 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts @@ -72,6 +72,7 @@ import { addTabChangedListener } from './listeners/tabChanged'; import { addUpscaleRequestedListener } from './listeners/upscaleRequested'; import { addWorkflowLoadedListener } from './listeners/workflowLoaded'; import { addBatchEnqueuedListener } from './listeners/batchEnqueued'; +import { addControlAdapterAddedOrEnabledListener } from './listeners/controlAdapterAddedOrEnabled'; export const listenerMiddleware = createListenerMiddleware(); @@ -199,3 +200,7 @@ addTabChangedListener(); // Dynamic prompts addDynamicPromptsListener(); + +// Display toast when controlnet or t2i adapter enabled +// TODO: Remove when they can both be enabled at same time +addControlAdapterAddedOrEnabledListener(); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterAddedOrEnabled.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterAddedOrEnabled.ts new file mode 100644 index 0000000000..bc5387c1fb --- /dev/null +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterAddedOrEnabled.ts @@ -0,0 +1,87 @@ +import { isAnyOf } from '@reduxjs/toolkit'; +import { + controlAdapterAdded, + controlAdapterAddedFromImage, + controlAdapterIsEnabledChanged, + controlAdapterRecalled, + selectControlAdapterAll, + selectControlAdapterById, +} from 'features/controlAdapters/store/controlAdaptersSlice'; +import { ControlAdapterType } from 'features/controlAdapters/store/types'; +import { addToast } from 'features/system/store/systemSlice'; +import i18n from 'i18n'; +import { startAppListening } from '..'; + +const isAnyControlAdapterAddedOrEnabled = isAnyOf( + controlAdapterAdded, + controlAdapterAddedFromImage, + controlAdapterRecalled, + controlAdapterIsEnabledChanged +); + +/** + * Until we can have both controlnet and t2i adapter enabled at once, they are mutually exclusive + * This displays a toast when one is enabled and the other is already enabled, or one is added + * with the other enabled + */ +export const addControlAdapterAddedOrEnabledListener = () => { + startAppListening({ + matcher: isAnyControlAdapterAddedOrEnabled, + effect: async (action, { dispatch, getOriginalState }) => { + const controlAdapters = getOriginalState().controlAdapters; + + const hasEnabledControlNets = selectControlAdapterAll( + controlAdapters + ).some((ca) => ca.isEnabled && ca.type === 'controlnet'); + + const hasEnabledT2IAdapters = selectControlAdapterAll( + controlAdapters + ).some((ca) => ca.isEnabled && ca.type === 't2i_adapter'); + + let caType: ControlAdapterType | null = null; + + if (controlAdapterAdded.match(action)) { + caType = action.payload.type; + } + + if (controlAdapterAddedFromImage.match(action)) { + caType = action.payload.type; + } + + if (controlAdapterRecalled.match(action)) { + caType = action.payload.type; + } + + if (controlAdapterIsEnabledChanged.match(action)) { + const _caType = selectControlAdapterById( + controlAdapters, + action.payload.id + )?.type; + if (!_caType) { + return; + } + caType = _caType; + } + + if ( + (caType === 'controlnet' && hasEnabledT2IAdapters) || + (caType === 't2i_adapter' && hasEnabledControlNets) + ) { + const title = + caType === 'controlnet' + ? i18n.t('controlnet.controlNetEnabledT2IDisabled') + : i18n.t('controlnet.t2iEnabledControlNetDisabled'); + + const description = i18n.t('controlnet.controlNetT2IMutexDesc'); + + dispatch( + addToast({ + title, + description, + status: 'warning', + }) + ); + } + }, + }); +};