mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Revert "feat(ui): remove special handling for t2i vs controlnet"
This reverts commit b146993553
.
This commit is contained in:
parent
b146993553
commit
bdf4c4944c
@ -12,7 +12,6 @@ import { addFirstListImagesListener } from './listeners/addFirstListImagesListen
|
|||||||
import { addAnyEnqueuedListener } from './listeners/anyEnqueued';
|
import { addAnyEnqueuedListener } from './listeners/anyEnqueued';
|
||||||
import { addAppConfigReceivedListener } from './listeners/appConfigReceived';
|
import { addAppConfigReceivedListener } from './listeners/appConfigReceived';
|
||||||
import { addAppStartedListener } from './listeners/appStarted';
|
import { addAppStartedListener } from './listeners/appStarted';
|
||||||
import { addBatchEnqueuedListener } from './listeners/batchEnqueued';
|
|
||||||
import { addDeleteBoardAndImagesFulfilledListener } from './listeners/boardAndImagesDeleted';
|
import { addDeleteBoardAndImagesFulfilledListener } from './listeners/boardAndImagesDeleted';
|
||||||
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
|
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
|
||||||
import { addCanvasCopiedToClipboardListener } from './listeners/canvasCopiedToClipboard';
|
import { addCanvasCopiedToClipboardListener } from './listeners/canvasCopiedToClipboard';
|
||||||
@ -72,6 +71,8 @@ import { addStagingAreaImageSavedListener } from './listeners/stagingAreaImageSa
|
|||||||
import { addTabChangedListener } from './listeners/tabChanged';
|
import { addTabChangedListener } from './listeners/tabChanged';
|
||||||
import { addUpscaleRequestedListener } from './listeners/upscaleRequested';
|
import { addUpscaleRequestedListener } from './listeners/upscaleRequested';
|
||||||
import { addWorkflowLoadedListener } from './listeners/workflowLoaded';
|
import { addWorkflowLoadedListener } from './listeners/workflowLoaded';
|
||||||
|
import { addBatchEnqueuedListener } from './listeners/batchEnqueued';
|
||||||
|
import { addControlAdapterAddedOrEnabledListener } from './listeners/controlAdapterAddedOrEnabled';
|
||||||
|
|
||||||
export const listenerMiddleware = createListenerMiddleware();
|
export const listenerMiddleware = createListenerMiddleware();
|
||||||
|
|
||||||
@ -199,3 +200,7 @@ addTabChangedListener();
|
|||||||
|
|
||||||
// Dynamic prompts
|
// Dynamic prompts
|
||||||
addDynamicPromptsListener();
|
addDynamicPromptsListener();
|
||||||
|
|
||||||
|
// Display toast when controlnet or t2i adapter enabled
|
||||||
|
// TODO: Remove when they can both be enabled at same time
|
||||||
|
addControlAdapterAddedOrEnabledListener();
|
||||||
|
@ -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',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@ -88,6 +88,61 @@ export const selectValidT2IAdapters = (controlAdapters: ControlAdaptersState) =>
|
|||||||
(ca.processorType === 'none' && Boolean(ca.controlImage)))
|
(ca.processorType === 'none' && Boolean(ca.controlImage)))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: I think we can safely remove this?
|
||||||
|
// const disableAllIPAdapters = (
|
||||||
|
// state: ControlAdaptersState,
|
||||||
|
// exclude?: string
|
||||||
|
// ) => {
|
||||||
|
// const updates: Update<ControlAdapterConfig>[] = selectAllIPAdapters(state)
|
||||||
|
// .filter((ca) => ca.id !== exclude)
|
||||||
|
// .map((ca) => ({
|
||||||
|
// id: ca.id,
|
||||||
|
// changes: { isEnabled: false },
|
||||||
|
// }));
|
||||||
|
// caAdapter.updateMany(state, updates);
|
||||||
|
// };
|
||||||
|
|
||||||
|
const disableAllControlNets = (
|
||||||
|
state: ControlAdaptersState,
|
||||||
|
exclude?: string
|
||||||
|
) => {
|
||||||
|
const updates: Update<ControlAdapterConfig>[] = selectAllControlNets(state)
|
||||||
|
.filter((ca) => ca.id !== exclude)
|
||||||
|
.map((ca) => ({
|
||||||
|
id: ca.id,
|
||||||
|
changes: { isEnabled: false },
|
||||||
|
}));
|
||||||
|
caAdapter.updateMany(state, updates);
|
||||||
|
};
|
||||||
|
|
||||||
|
const disableAllT2IAdapters = (
|
||||||
|
state: ControlAdaptersState,
|
||||||
|
exclude?: string
|
||||||
|
) => {
|
||||||
|
const updates: Update<ControlAdapterConfig>[] = selectAllT2IAdapters(state)
|
||||||
|
.filter((ca) => ca.id !== exclude)
|
||||||
|
.map((ca) => ({
|
||||||
|
id: ca.id,
|
||||||
|
changes: { isEnabled: false },
|
||||||
|
}));
|
||||||
|
caAdapter.updateMany(state, updates);
|
||||||
|
};
|
||||||
|
|
||||||
|
const disableIncompatibleControlAdapters = (
|
||||||
|
state: ControlAdaptersState,
|
||||||
|
type: ControlAdapterType,
|
||||||
|
exclude?: string
|
||||||
|
) => {
|
||||||
|
if (type === 'controlnet') {
|
||||||
|
// we cannot do controlnet + t2i adapter, if we are enabled a controlnet, disable all t2is
|
||||||
|
disableAllT2IAdapters(state, exclude);
|
||||||
|
}
|
||||||
|
if (type === 't2i_adapter') {
|
||||||
|
// we cannot do controlnet + t2i adapter, if we are enabled a t2i, disable controlnets
|
||||||
|
disableAllControlNets(state, exclude);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const controlAdaptersSlice = createSlice({
|
export const controlAdaptersSlice = createSlice({
|
||||||
name: 'controlAdapters',
|
name: 'controlAdapters',
|
||||||
initialState: initialControlAdapterState,
|
initialState: initialControlAdapterState,
|
||||||
@ -103,6 +158,7 @@ export const controlAdaptersSlice = createSlice({
|
|||||||
) => {
|
) => {
|
||||||
const { id, type, overrides } = action.payload;
|
const { id, type, overrides } = action.payload;
|
||||||
caAdapter.addOne(state, buildControlAdapter(id, type, overrides));
|
caAdapter.addOne(state, buildControlAdapter(id, type, overrides));
|
||||||
|
disableIncompatibleControlAdapters(state, type, id);
|
||||||
},
|
},
|
||||||
prepare: ({
|
prepare: ({
|
||||||
type,
|
type,
|
||||||
@ -119,6 +175,8 @@ export const controlAdaptersSlice = createSlice({
|
|||||||
action: PayloadAction<ControlAdapterConfig>
|
action: PayloadAction<ControlAdapterConfig>
|
||||||
) => {
|
) => {
|
||||||
caAdapter.addOne(state, action.payload);
|
caAdapter.addOne(state, action.payload);
|
||||||
|
const { type, id } = action.payload;
|
||||||
|
disableIncompatibleControlAdapters(state, type, id);
|
||||||
},
|
},
|
||||||
controlAdapterDuplicated: {
|
controlAdapterDuplicated: {
|
||||||
reducer: (
|
reducer: (
|
||||||
@ -138,6 +196,8 @@ export const controlAdaptersSlice = createSlice({
|
|||||||
isEnabled: true,
|
isEnabled: true,
|
||||||
});
|
});
|
||||||
caAdapter.addOne(state, newControlAdapter);
|
caAdapter.addOne(state, newControlAdapter);
|
||||||
|
const { type } = newControlAdapter;
|
||||||
|
disableIncompatibleControlAdapters(state, type, newId);
|
||||||
},
|
},
|
||||||
prepare: (id: string) => {
|
prepare: (id: string) => {
|
||||||
return { payload: { id, newId: uuidv4() } };
|
return { payload: { id, newId: uuidv4() } };
|
||||||
@ -157,6 +217,7 @@ export const controlAdaptersSlice = createSlice({
|
|||||||
state,
|
state,
|
||||||
buildControlAdapter(id, type, { controlImage })
|
buildControlAdapter(id, type, { controlImage })
|
||||||
);
|
);
|
||||||
|
disableIncompatibleControlAdapters(state, type, id);
|
||||||
},
|
},
|
||||||
prepare: (payload: {
|
prepare: (payload: {
|
||||||
type: ControlAdapterType;
|
type: ControlAdapterType;
|
||||||
@ -174,6 +235,12 @@ export const controlAdaptersSlice = createSlice({
|
|||||||
) => {
|
) => {
|
||||||
const { id, isEnabled } = action.payload;
|
const { id, isEnabled } = action.payload;
|
||||||
caAdapter.updateOne(state, { id, changes: { isEnabled } });
|
caAdapter.updateOne(state, { id, changes: { isEnabled } });
|
||||||
|
if (isEnabled) {
|
||||||
|
// we are enabling a control adapter. due to limitations in the current system, we may need to disable other adapters
|
||||||
|
// TODO: disable when multiple IP adapters are supported
|
||||||
|
const ca = selectControlAdapterById(state, id);
|
||||||
|
ca && disableIncompatibleControlAdapters(state, ca.type, id);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
controlAdapterImageChanged: (
|
controlAdapterImageChanged: (
|
||||||
state,
|
state,
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user