feat(ui): add recall Height/Width button to img2img initial image and current image displays in linear flow (#5161)

* working on recall height/width

* working on adding resize

* working on feature

* fix(ui): move added translation from dist/ to public/

* fix(ui): use `metadata` as hotkey cb dependency

Using `imageDTO` may result in stale data being used

---------

Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
This commit is contained in:
Paul Curry 2023-11-24 19:58:11 -08:00 committed by GitHub
parent 6e6d903f99
commit 4fe93e521e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 8 deletions

View File

@ -1111,6 +1111,7 @@
"upscaling": "Upscaling", "upscaling": "Upscaling",
"unmasked": "Unmasked", "unmasked": "Unmasked",
"useAll": "Use All", "useAll": "Use All",
"useSize": "Use Size",
"useCpuNoise": "Use CPU Noise", "useCpuNoise": "Use CPU Noise",
"cpuNoise": "CPU Noise", "cpuNoise": "CPU Noise",
"gpuNoise": "GPU Noise", "gpuNoise": "GPU Noise",

View File

@ -35,6 +35,7 @@ import {
FaCode, FaCode,
FaHourglassHalf, FaHourglassHalf,
FaQuoteRight, FaQuoteRight,
FaRulerVertical,
FaSeedling, FaSeedling,
} from 'react-icons/fa'; } from 'react-icons/fa';
import { FaCircleNodes, FaEllipsis } from 'react-icons/fa6'; import { FaCircleNodes, FaEllipsis } from 'react-icons/fa6';
@ -95,8 +96,12 @@ const CurrentImageButtons = () => {
const toaster = useAppToaster(); const toaster = useAppToaster();
const { t } = useTranslation(); const { t } = useTranslation();
const { recallBothPrompts, recallSeed, recallAllParameters } = const {
useRecallParameters(); recallBothPrompts,
recallSeed,
recallWidthAndHeight,
recallAllParameters,
} = useRecallParameters();
const { currentData: imageDTO } = useGetImageDTOQuery( const { currentData: imageDTO } = useGetImageDTOQuery(
lastSelectedImage?.image_name ?? skipToken lastSelectedImage?.image_name ?? skipToken
@ -117,6 +122,8 @@ const CurrentImageButtons = () => {
dispatch(workflowLoadRequested(workflow)); dispatch(workflowLoadRequested(workflow));
}, [dispatch, workflow]); }, [dispatch, workflow]);
useHotkeys('w', handleLoadWorkflow, [workflow]);
const handleClickUseAllParameters = useCallback(() => { const handleClickUseAllParameters = useCallback(() => {
recallAllParameters(metadata); recallAllParameters(metadata);
}, [metadata, recallAllParameters]); }, [metadata, recallAllParameters]);
@ -146,7 +153,11 @@ const CurrentImageButtons = () => {
useHotkeys('p', handleUsePrompt, [metadata]); useHotkeys('p', handleUsePrompt, [metadata]);
useHotkeys('w', handleLoadWorkflow, [workflow]); const handleUseSize = useCallback(() => {
recallWidthAndHeight(metadata?.width, metadata?.height);
}, [metadata?.width, metadata?.height, recallWidthAndHeight]);
useHotkeys('d', handleUseSize, [metadata]);
const handleSendToImageToImage = useCallback(() => { const handleSendToImageToImage = useCallback(() => {
dispatch(sentImageToImg2Img()); dispatch(sentImageToImg2Img());
@ -267,6 +278,19 @@ const CurrentImageButtons = () => {
isDisabled={metadata?.seed === null || metadata?.seed === undefined} isDisabled={metadata?.seed === null || metadata?.seed === undefined}
onClick={handleUseSeed} onClick={handleUseSeed}
/> />
<IAIIconButton
isLoading={isLoadingMetadata}
icon={<FaRulerVertical />}
tooltip={`${t('parameters.useSize')} (D)`}
aria-label={`${t('parameters.useSize')} (D)`}
isDisabled={
metadata?.height === null ||
metadata?.height === undefined ||
metadata?.width === null ||
metadata?.width === undefined
}
onClick={handleUseSize}
/>
<IAIIconButton <IAIIconButton
isLoading={isLoadingMetadata} isLoading={isLoadingMetadata}
icon={<FaAsterisk />} icon={<FaAsterisk />}

View File

@ -5,12 +5,14 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import { useImageUploadButton } from 'common/hooks/useImageUploadButton'; import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
import { clearInitialImage } from 'features/parameters/store/generationSlice'; import { clearInitialImage } from 'features/parameters/store/generationSlice';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { FaUndo, FaUpload } from 'react-icons/fa'; import { useHotkeys } from 'react-hotkeys-hook';
import InitialImage from './InitialImage';
import { PostUploadAction } from 'services/api/types';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FaRulerVertical, FaUndo, FaUpload } from 'react-icons/fa';
import { PostUploadAction } from 'services/api/types';
import InitialImage from './InitialImage';
const selector = createSelector( const selector = createSelector(
[stateSelector], [stateSelector],
@ -18,6 +20,7 @@ const selector = createSelector(
const { initialImage } = state.generation; const { initialImage } = state.generation;
return { return {
isResetButtonDisabled: !initialImage, isResetButtonDisabled: !initialImage,
initialImage,
}; };
}, },
defaultSelectorOptions defaultSelectorOptions
@ -28,7 +31,9 @@ const postUploadAction: PostUploadAction = {
}; };
const InitialImageDisplay = () => { const InitialImageDisplay = () => {
const { isResetButtonDisabled } = useAppSelector(selector); const { recallWidthAndHeight } = useRecallParameters();
const { t } = useTranslation();
const { isResetButtonDisabled, initialImage } = useAppSelector(selector);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { getUploadButtonProps, getUploadInputProps } = useImageUploadButton({ const { getUploadButtonProps, getUploadInputProps } = useImageUploadButton({
@ -39,7 +44,13 @@ const InitialImageDisplay = () => {
dispatch(clearInitialImage()); dispatch(clearInitialImage());
}, [dispatch]); }, [dispatch]);
const { t } = useTranslation(); const handleUseSizeInitialImage = useCallback(() => {
if (initialImage) {
recallWidthAndHeight(initialImage.width, initialImage.height);
}
}, [initialImage, recallWidthAndHeight]);
useHotkeys('shift+d', handleUseSizeInitialImage, [initialImage]);
return ( return (
<Flex <Flex
@ -85,6 +96,13 @@ const InitialImageDisplay = () => {
icon={<FaUpload />} icon={<FaUpload />}
{...getUploadButtonProps()} {...getUploadButtonProps()}
/> />
<IAIIconButton
tooltip={`${t('parameters.useSize')} (Shift+D)`}
aria-label={`${t('parameters.useSize')} (Shift+D)`}
icon={<FaRulerVertical />}
onClick={handleUseSizeInitialImage}
isDisabled={isResetButtonDisabled}
/>
<IAIIconButton <IAIIconButton
tooltip="Reset Initial Image" tooltip="Reset Initial Image"
aria-label="Reset Initial Image" aria-label="Reset Initial Image"

View File

@ -373,6 +373,26 @@ export const useRecallParameters = () => {
[dispatch, parameterSetToast, parameterNotSetToast] [dispatch, parameterSetToast, parameterNotSetToast]
); );
/**
* Recall width and height with toast
*/
const recallWidthAndHeight = useCallback(
(width: unknown, height: unknown) => {
if (!isValidWidth(width)) {
allParameterNotSetToast();
return;
}
if (!isValidHeight(height)) {
allParameterNotSetToast();
return;
}
dispatch(setHeight(height));
dispatch(setWidth(width));
allParameterSetToast();
},
[dispatch, allParameterSetToast, allParameterNotSetToast]
);
/** /**
* Recall strength with toast * Recall strength with toast
*/ */
@ -966,6 +986,7 @@ export const useRecallParameters = () => {
recallSteps, recallSteps,
recallWidth, recallWidth,
recallHeight, recallHeight,
recallWidthAndHeight,
recallStrength, recallStrength,
recallHrfEnabled, recallHrfEnabled,
recallHrfStrength, recallHrfStrength,