diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index ed774f6189..74febf3ddc 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -968,10 +968,10 @@ "missingFieldTemplate": "Missing field template", "missingInputForField": "{{nodeLabel}} -> {{fieldLabel}} missing input", "missingNodeTemplate": "Missing node template", - "noControlImageForControlAdapter": "Control Adapter {{number}} has no control image", + "noControlImageForControlAdapter": "Control Adapter #{{number}} has no control image", "noInitialImageSelected": "No initial image selected", - "noModelForControlAdapter": "Control Adapter {{number}} has no model selected.", - "incompatibleBaseModelForControlAdapter": "Control Adapter {{number}} model is invalid with main model.", + "noModelForControlAdapter": "Control Adapter #{{number}} has no model selected.", + "incompatibleBaseModelForControlAdapter": "Control Adapter #{{number}} model is invalid with main model.", "noModelSelected": "No model selected", "noPrompts": "No prompts generated", "noNodesInGraph": "No nodes in graph", diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdaptersCollapse.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdaptersCollapse.tsx index 202222bed9..b2f9bcfe41 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdaptersCollapse.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdaptersCollapse.tsx @@ -11,31 +11,53 @@ import { selectAllIPAdapters, selectAllT2IAdapters, selectControlAdapterIds, + selectValidControlNets, + selectValidIPAdapters, + selectValidT2IAdapters, } from 'features/controlAdapters/store/controlAdaptersSlice'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { Fragment, memo } from 'react'; +import { useTranslation } from 'react-i18next'; import { FaPlus } from 'react-icons/fa'; import { useAddControlAdapter } from '../hooks/useAddControlAdapter'; -import { useTranslation } from 'react-i18next'; const selector = createSelector( [stateSelector], ({ controlAdapters }) => { const activeLabel: string[] = []; + let isError = false; - const ipAdapterCount = selectAllIPAdapters(controlAdapters).length; - if (ipAdapterCount > 0) { - activeLabel.push(`${ipAdapterCount} IP`); + const enabledIPAdapterCount = selectAllIPAdapters(controlAdapters).filter( + (ca) => ca.isEnabled + ).length; + const validIPAdapterCount = selectValidIPAdapters(controlAdapters).length; + if (enabledIPAdapterCount > 0) { + activeLabel.push(`${enabledIPAdapterCount} IP`); + } + if (enabledIPAdapterCount > validIPAdapterCount) { + isError = true; } - const controlNetCount = selectAllControlNets(controlAdapters).length; - if (controlNetCount > 0) { - activeLabel.push(`${controlNetCount} ControlNet`); + const enabledControlNetCount = selectAllControlNets(controlAdapters).filter( + (ca) => ca.isEnabled + ).length; + const validControlNetCount = selectValidControlNets(controlAdapters).length; + if (enabledControlNetCount > 0) { + activeLabel.push(`${enabledControlNetCount} ControlNet`); + } + if (enabledControlNetCount > validControlNetCount) { + isError = true; } - const t2iAdapterCount = selectAllT2IAdapters(controlAdapters).length; - if (t2iAdapterCount > 0) { - activeLabel.push(`${t2iAdapterCount} T2I`); + const enabledT2IAdapterCount = selectAllT2IAdapters(controlAdapters).filter( + (ca) => ca.isEnabled + ).length; + const validT2IAdapterCount = selectValidT2IAdapters(controlAdapters).length; + if (enabledT2IAdapterCount > 0) { + activeLabel.push(`${enabledT2IAdapterCount} T2I`); + } + if (enabledT2IAdapterCount > validT2IAdapterCount) { + isError = true; } const controlAdapterIds = @@ -44,6 +66,7 @@ const selector = createSelector( return { controlAdapterIds, activeLabel: activeLabel.join(', '), + isError, // TODO: Add some visual indicator that the control adapters are in an error state }; }, defaultSelectorOptions diff --git a/invokeai/frontend/web/src/theme/components/text.ts b/invokeai/frontend/web/src/theme/components/text.ts index cccbcf2391..2681fb1d67 100644 --- a/invokeai/frontend/web/src/theme/components/text.ts +++ b/invokeai/frontend/web/src/theme/components/text.ts @@ -1,6 +1,10 @@ import { defineStyle, defineStyleConfig } from '@chakra-ui/react'; import { mode } from '@chakra-ui/theme-tools'; +const error = defineStyle((props) => ({ + color: mode('error.500', 'error.400')(props), +})); + const subtext = defineStyle((props) => ({ color: mode('base.500', 'base.400')(props), })); @@ -8,5 +12,6 @@ const subtext = defineStyle((props) => ({ export const textTheme = defineStyleConfig({ variants: { subtext, + error, }, });