11import { Flex } from '@invoke-ai/ui-library' ;
22import { useStore } from '@nanostores/react' ;
33import { skipToken } from '@reduxjs/toolkit/query' ;
4+ import { useAppSelector , useAppStore } from 'app/store/storeHooks' ;
45import { UploadImageIconButton } from 'common/hooks/useImageUploadButton' ;
6+ import { bboxSizeOptimized , bboxSizeRecalled } from 'features/controlLayers/store/canvasSlice' ;
7+ import { useCanvasIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice' ;
8+ import { sizeOptimized , sizeRecalled } from 'features/controlLayers/store/paramsSlice' ;
59import type { ImageWithDims } from 'features/controlLayers/store/types' ;
610import type { setGlobalReferenceImageDndTarget , setRegionalGuidanceReferenceImageDndTarget } from 'features/dnd/dnd' ;
711import { DndDropTarget } from 'features/dnd/DndDropTarget' ;
812import { DndImage } from 'features/dnd/DndImage' ;
913import { DndImageIcon } from 'features/dnd/DndImageIcon' ;
14+ import { selectActiveTab } from 'features/ui/store/uiSelectors' ;
1015import { memo , useCallback , useEffect } from 'react' ;
1116import { useTranslation } from 'react-i18next' ;
12- import { PiArrowCounterClockwiseBold } from 'react-icons/pi' ;
17+ import { PiArrowCounterClockwiseBold , PiRulerBold } from 'react-icons/pi' ;
1318import { useGetImageDTOQuery } from 'services/api/endpoints/images' ;
1419import type { ImageDTO } from 'services/api/types' ;
1520import { $isConnected } from 'services/events/stores' ;
@@ -29,7 +34,10 @@ export const RefImageImage = memo(
2934 dndTargetData,
3035 } : Props < T > ) => {
3136 const { t } = useTranslation ( ) ;
37+ const store = useAppStore ( ) ;
3238 const isConnected = useStore ( $isConnected ) ;
39+ const tab = useAppSelector ( selectActiveTab ) ;
40+ const isStaging = useCanvasIsStaging ( ) ;
3341 const { currentData : imageDTO , isError } = useGetImageDTOQuery ( image ?. image_name ?? skipToken ) ;
3442 const handleResetControlImage = useCallback ( ( ) => {
3543 onChangeImage ( null ) ;
@@ -48,6 +56,20 @@ export const RefImageImage = memo(
4856 [ onChangeImage ]
4957 ) ;
5058
59+ const recallSizeAndOptimize = useCallback ( ( ) => {
60+ if ( ! imageDTO || ( tab === 'canvas' && isStaging ) ) {
61+ return ;
62+ }
63+ const { width, height } = imageDTO ;
64+ if ( tab === 'canvas' ) {
65+ store . dispatch ( bboxSizeRecalled ( { width, height } ) ) ;
66+ store . dispatch ( bboxSizeOptimized ( ) ) ;
67+ } else if ( tab === 'generate' ) {
68+ store . dispatch ( sizeRecalled ( { width, height } ) ) ;
69+ store . dispatch ( sizeOptimized ( ) ) ;
70+ }
71+ } , [ imageDTO , isStaging , store , tab ] ) ;
72+
5173 return (
5274 < Flex position = "relative" w = "full" h = "full" alignItems = "center" data-error = { ! imageDTO && ! image ?. image_name } >
5375 { ! imageDTO && (
@@ -69,6 +91,14 @@ export const RefImageImage = memo(
6991 tooltip = { t ( 'common.reset' ) }
7092 />
7193 </ Flex >
94+ < Flex position = "absolute" flexDir = "column" bottom = { 2 } insetInlineEnd = { 2 } gap = { 1 } >
95+ < DndImageIcon
96+ onClick = { recallSizeAndOptimize }
97+ icon = { < PiRulerBold size = { 16 } /> }
98+ tooltip = { t ( 'parameters.useSize' ) }
99+ isDisabled = { ! imageDTO || ( tab === 'canvas' && isStaging ) }
100+ />
101+ </ Flex >
72102 </ >
73103 ) }
74104 < DndDropTarget dndTarget = { dndTarget } dndTargetData = { dndTargetData } label = { t ( 'gallery.drop' ) } />
0 commit comments