diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx
index 392580e3a1..501ebe76fd 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageHeader.tsx
@@ -4,13 +4,17 @@ import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { useRefImageEntity } from 'features/controlLayers/components/RefImage/useRefImageEntity';
import { useRefImageIdContext } from 'features/controlLayers/contexts/RefImageIdContext';
+import { selectMainModelConfig } from 'features/controlLayers/store/paramsSlice';
import {
refImageDeleted,
refImageIsEnabledToggled,
selectRefImageEntityIds,
} from 'features/controlLayers/store/refImagesSlice';
+import { getGlobalReferenceImageWarnings } from 'features/controlLayers/store/validators';
import { memo, useCallback, useMemo } from 'react';
-import { PiCircleBold, PiCircleFill, PiTrashBold } from 'react-icons/pi';
+import { PiCircleBold, PiCircleFill, PiTrashBold, PiWarningBold } from 'react-icons/pi';
+
+import { RefImageWarningTooltipContent } from './RefImageWarningTooltipContent';
const textSx: SystemStyleObject = {
color: 'base.300',
@@ -28,6 +32,12 @@ export const RefImageHeader = memo(() => {
);
const refImageNumber = useAppSelector(selectRefImageNumber);
const entity = useRefImageEntity(id);
+ const mainModelConfig = useAppSelector(selectMainModelConfig);
+
+ const warnings = useMemo(() => {
+ return getGlobalReferenceImageWarnings(entity, mainModelConfig);
+ }, [entity, mainModelConfig]);
+
const deleteRefImage = useCallback(() => {
dispatch(refImageDeleted({ id }));
}, [dispatch, id]);
@@ -42,6 +52,18 @@ export const RefImageHeader = memo(() => {
Reference Image #{refImageNumber}
+ {warnings.length > 0 && (
+ }
+ icon={}
+ colorScheme="warning"
+ />
+ )}
{!entity.isEnabled && (
Disabled
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx
index 016384d058..01fcde269b 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImagePreview.tsx
@@ -1,5 +1,5 @@
import type { SystemStyleObject } from '@invoke-ai/ui-library';
-import { Flex, Icon, IconButton, Image, Skeleton, Text } from '@invoke-ai/ui-library';
+import { Flex, Icon, IconButton, Image, Skeleton, Text, Tooltip } from '@invoke-ai/ui-library';
import { skipToken } from '@reduxjs/toolkit/query';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { round } from 'es-toolkit/compat';
@@ -17,6 +17,8 @@ import { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { PiExclamationMarkBold, PiEyeSlashBold, PiImageBold } from 'react-icons/pi';
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
+import { RefImageWarningTooltipContent } from './RefImageWarningTooltipContent';
+
const baseSx: SystemStyleObject = {
'&[data-is-open="true"]': {
borderColor: 'invokeBlue.300',
@@ -51,9 +53,6 @@ const getImageSxWithWeight = (weight: number): SystemStyleObject => {
return {
...baseSx,
- '&[data-is-disabled="true"]': {
- opacity: 0.4,
- },
_after: {
content: '""',
position: 'absolute',
@@ -95,8 +94,8 @@ export const RefImagePreview = memo(() => {
};
}, [entity.config]);
- const isInvalid = useMemo(() => {
- return getGlobalReferenceImageWarnings(entity, mainModelConfig).length > 0;
+ const warnings = useMemo(() => {
+ return getGlobalReferenceImageWarnings(entity, mainModelConfig);
}, [entity, mainModelConfig]);
const onClick = useCallback(() => {
@@ -126,74 +125,76 @@ export const RefImagePreview = memo(() => {
);
}
return (
-
- 0 ? : undefined}>
+ }
maxW="full"
maxH="full"
- borderRadius="base"
- />
- {isIPAdapterConfig(entity.config) && (
-
-
- {`${round(entity.config.weight * 100, 2)}%`}
-
-
- )}
- {!entity.isEnabled && (
- 0}
+ data-is-disabled={!entity.isEnabled}
+ role="button"
+ onClick={onClick}
+ cursor="pointer"
+ >
+ }
+ maxW="full"
+ maxH="full"
+ borderRadius="base"
/>
- )}
- {entity.isEnabled && isInvalid && (
-
- )}
-
+ {isIPAdapterConfig(entity.config) && (
+
+
+ {`${round(entity.config.weight * 100, 2)}%`}
+
+
+ )}
+ {!entity.isEnabled && (
+
+ )}
+ {entity.isEnabled && warnings.length > 0 && (
+
+ )}
+
+
);
});
RefImagePreview.displayName = 'RefImagePreview';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageWarningTooltipContent.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageWarningTooltipContent.tsx
new file mode 100644
index 0000000000..6c9fdffe49
--- /dev/null
+++ b/invokeai/frontend/web/src/features/controlLayers/components/RefImage/RefImageWarningTooltipContent.tsx
@@ -0,0 +1,18 @@
+import { Flex, ListItem, Text, UnorderedList } from '@invoke-ai/ui-library';
+import { upperFirst } from 'es-toolkit/compat';
+import { useTranslation } from 'react-i18next';
+
+export const RefImageWarningTooltipContent = ({ warnings }: { warnings: string[] }) => {
+ const { t } = useTranslation();
+
+ return (
+
+ Invalid Reference Image:
+
+ {warnings.map((tKey) => (
+ {upperFirst(t(tKey))}
+ ))}
+
+
+ );
+};