feat: "Remix Image" option on images (#5553)

* feat:  "Remix Image" option on images

Adds a new "remix image" option where applicable, recalls all metadata except the seed

* refactor: 🚨 lint code

* feat:  "Remix Image" option on images

Adds a new "remix image" option where applicable, recalls all metadata except the seed

* refactor: 🚨 lint code

* feat:  add new remix hotkey to hotkeys modal

---------

Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
This commit is contained in:
Josh Corbett 2024-01-23 17:45:30 -07:00 committed by GitHub
parent 9d20a2d5a3
commit 61cf4d4c70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 0 deletions

View File

@ -600,6 +600,10 @@
"desc": "Send current image to Image to Image", "desc": "Send current image to Image to Image",
"title": "Send To Image To Image" "title": "Send To Image To Image"
}, },
"remixImage": {
"desc": "Use all parameters except seed from the current image",
"title": "Remix image"
},
"setParameters": { "setParameters": {
"desc": "Use all parameters of the current image", "desc": "Use all parameters of the current image",
"title": "Set Parameters" "title": "Set Parameters"
@ -1216,6 +1220,7 @@
"useCpuNoise": "Use CPU Noise", "useCpuNoise": "Use CPU Noise",
"cpuNoise": "CPU Noise", "cpuNoise": "CPU Noise",
"gpuNoise": "GPU Noise", "gpuNoise": "GPU Noise",
"remixImage": "Remix Image",
"useInitImg": "Use Initial Image", "useInitImg": "Use Initial Image",
"usePrompt": "Use Prompt", "usePrompt": "Use Prompt",
"useSeed": "Use Seed", "useSeed": "Use Seed",

View File

@ -32,6 +32,7 @@ import { memo, useCallback } from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import {
PiArrowsCounterClockwiseBold,
PiAsteriskBold, PiAsteriskBold,
PiDotsThreeOutlineFill, PiDotsThreeOutlineFill,
PiFlowArrowBold, PiFlowArrowBold,
@ -129,6 +130,16 @@ const CurrentImageButtons = () => {
useHotkeys('p', handleUsePrompt, [metadata]); useHotkeys('p', handleUsePrompt, [metadata]);
const handleRemixImage = useCallback(() => {
// Recalls all metadata parameters except seed
recallAllParameters({
...metadata,
seed: undefined,
});
}, [metadata, recallAllParameters]);
useHotkeys('r', handleRemixImage, [metadata]);
const handleUseSize = useCallback(() => { const handleUseSize = useCallback(() => {
recallWidthAndHeight(metadata?.width, metadata?.height); recallWidthAndHeight(metadata?.width, metadata?.height);
}, [metadata?.width, metadata?.height, recallWidthAndHeight]); }, [metadata?.width, metadata?.height, recallWidthAndHeight]);
@ -231,6 +242,14 @@ const CurrentImageButtons = () => {
onClick={handleLoadWorkflow} onClick={handleLoadWorkflow}
isLoading={getAndLoadEmbeddedWorkflowResult.isLoading} isLoading={getAndLoadEmbeddedWorkflowResult.isLoading}
/> />
<IconButton
isLoading={isLoadingMetadata}
icon={<PiArrowsCounterClockwiseBold />}
tooltip={`${t('parameters.remixImage')} (R)`}
aria-label={`${t('parameters.remixImage')} (R)`}
isDisabled={!metadata?.positive_prompt}
onClick={handleRemixImage}
/>
<IconButton <IconButton
isLoading={isLoadingMetadata} isLoading={isLoadingMetadata}
icon={<PiQuotesBold />} icon={<PiQuotesBold />}

View File

@ -24,6 +24,7 @@ import { memo, useCallback } from 'react';
import { flushSync } from 'react-dom'; import { flushSync } from 'react-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import {
PiArrowsCounterClockwiseBold,
PiAsteriskBold, PiAsteriskBold,
PiCopyBold, PiCopyBold,
PiDownloadSimpleBold, PiDownloadSimpleBold,
@ -127,6 +128,14 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
recallAllParameters(metadata); recallAllParameters(metadata);
}, [metadata, recallAllParameters]); }, [metadata, recallAllParameters]);
const handleRemixImage = useCallback(() => {
// Recalls all metadata parameters except seed
recallAllParameters({
...metadata,
seed: undefined,
});
}, [metadata, recallAllParameters]);
const handleChangeBoard = useCallback(() => { const handleChangeBoard = useCallback(() => {
dispatch(imagesToChangeSelected([imageDTO])); dispatch(imagesToChangeSelected([imageDTO]));
dispatch(isModalOpenChanged(true)); dispatch(isModalOpenChanged(true));
@ -187,6 +196,19 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
> >
{t('nodes.loadWorkflow')} {t('nodes.loadWorkflow')}
</MenuItem> </MenuItem>
<MenuItem
icon={
isLoadingMetadata ? <SpinnerIcon /> : <PiArrowsCounterClockwiseBold />
}
onClickCapture={handleRemixImage}
isDisabled={
isLoadingMetadata ||
(metadata?.positive_prompt === undefined &&
metadata?.negative_prompt === undefined)
}
>
{t('parameters.remixImage')}
</MenuItem>
<MenuItem <MenuItem
icon={isLoadingMetadata ? <SpinnerIcon /> : <PiQuotesBold />} icon={isLoadingMetadata ? <SpinnerIcon /> : <PiQuotesBold />}
onClickCapture={handleRecallPrompt} onClickCapture={handleRecallPrompt}

View File

@ -81,6 +81,11 @@ export const useHotkeyData = (): HotkeyGroup[] => {
() => ({ () => ({
title: t('hotkeys.generalHotkeys'), title: t('hotkeys.generalHotkeys'),
hotkeyListItems: [ hotkeyListItems: [
{
title: t('hotkeys.remixImage.title'),
desc: t('hotkeys.remixImage.desc'),
hotkeys: [['R']],
},
{ {
title: t('hotkeys.setPrompt.title'), title: t('hotkeys.setPrompt.title'),
desc: t('hotkeys.setPrompt.desc'), desc: t('hotkeys.setPrompt.desc'),