mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Fixes invoke button working when only eraser strokes
This commit is contained in:
parent
47106eeeea
commit
219da47576
@ -1,9 +1,8 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { isEqual } from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useAppSelector } from '../../app/store';
|
import { useAppSelector } from '../../app/store';
|
||||||
import { RootState } from '../../app/store';
|
import { RootState } from '../../app/store';
|
||||||
import { GalleryState } from '../../features/gallery/gallerySlice';
|
|
||||||
import { OptionsState } from '../../features/options/optionsSlice';
|
import { OptionsState } from '../../features/options/optionsSlice';
|
||||||
|
|
||||||
import { SystemState } from '../../features/system/systemSlice';
|
import { SystemState } from '../../features/system/systemSlice';
|
||||||
@ -11,10 +10,15 @@ import { InpaintingState } from '../../features/tabs/Inpainting/inpaintingSlice'
|
|||||||
import { tabMap } from '../../features/tabs/InvokeTabs';
|
import { tabMap } from '../../features/tabs/InvokeTabs';
|
||||||
import { validateSeedWeights } from '../util/seedWeightPairs';
|
import { validateSeedWeights } from '../util/seedWeightPairs';
|
||||||
|
|
||||||
export const optionsSelector = createSelector(
|
export const useCheckParametersSelector = createSelector(
|
||||||
|
[
|
||||||
(state: RootState) => state.options,
|
(state: RootState) => state.options,
|
||||||
(options: OptionsState) => {
|
(state: RootState) => state.system,
|
||||||
|
(state: RootState) => state.inpainting,
|
||||||
|
],
|
||||||
|
(options: OptionsState, system: SystemState, inpainting: InpaintingState) => {
|
||||||
return {
|
return {
|
||||||
|
// options
|
||||||
prompt: options.prompt,
|
prompt: options.prompt,
|
||||||
shouldGenerateVariations: options.shouldGenerateVariations,
|
shouldGenerateVariations: options.shouldGenerateVariations,
|
||||||
seedWeights: options.seedWeights,
|
seedWeights: options.seedWeights,
|
||||||
@ -22,58 +26,21 @@ export const optionsSelector = createSelector(
|
|||||||
initialImagePath: options.initialImagePath,
|
initialImagePath: options.initialImagePath,
|
||||||
seed: options.seed,
|
seed: options.seed,
|
||||||
activeTabName: tabMap[options.activeTab],
|
activeTabName: tabMap[options.activeTab],
|
||||||
};
|
// system
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const systemSelector = createSelector(
|
|
||||||
(state: RootState) => state.system,
|
|
||||||
(system: SystemState) => {
|
|
||||||
return {
|
|
||||||
isProcessing: system.isProcessing,
|
isProcessing: system.isProcessing,
|
||||||
isConnected: system.isConnected,
|
isConnected: system.isConnected,
|
||||||
|
// inpainting
|
||||||
|
isMaskEmpty:
|
||||||
|
inpainting.lines.filter((line) => line.tool === 'brush').length === 0,
|
||||||
|
hasInpaintingImage: Boolean(inpainting.imageToInpaint),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
memoizeOptions: {
|
memoizeOptions: {
|
||||||
resultEqualityCheck: isEqual,
|
resultEqualityCheck: _.isEqual,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const inpaintingSelector = createSelector(
|
|
||||||
(state: RootState) => state.inpainting,
|
|
||||||
(inpainting: InpaintingState) => {
|
|
||||||
return {
|
|
||||||
isMaskEmpty: inpainting.lines.length === 0,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const gallerySelector = createSelector(
|
|
||||||
(state: RootState) => state.gallery,
|
|
||||||
(gallery: GalleryState) => {
|
|
||||||
return {
|
|
||||||
hasCurrentImage: Boolean(gallery.currentImage),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks relevant pieces of state to confirm generation will not deterministically fail.
|
* Checks relevant pieces of state to confirm generation will not deterministically fail.
|
||||||
* This is used to prevent the 'Generate' button from being clicked.
|
* This is used to prevent the 'Generate' button from being clicked.
|
||||||
@ -87,13 +54,11 @@ const useCheckParameters = (): boolean => {
|
|||||||
initialImagePath,
|
initialImagePath,
|
||||||
seed,
|
seed,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
} = useAppSelector(optionsSelector);
|
isProcessing,
|
||||||
|
isConnected,
|
||||||
const { isProcessing, isConnected } = useAppSelector(systemSelector);
|
isMaskEmpty,
|
||||||
|
hasInpaintingImage,
|
||||||
const { isMaskEmpty } = useAppSelector(inpaintingSelector);
|
} = useAppSelector(useCheckParametersSelector);
|
||||||
|
|
||||||
const { hasCurrentImage } = useAppSelector(gallerySelector);
|
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
// Cannot generate without a prompt
|
// Cannot generate without a prompt
|
||||||
@ -105,7 +70,10 @@ const useCheckParameters = (): boolean => {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'inpainting' && (!hasCurrentImage || isMaskEmpty)) {
|
if (
|
||||||
|
activeTabName === 'inpainting' &&
|
||||||
|
(!hasInpaintingImage || isMaskEmpty)
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +113,8 @@ const useCheckParameters = (): boolean => {
|
|||||||
seedWeights,
|
seedWeights,
|
||||||
seed,
|
seed,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
hasCurrentImage,
|
|
||||||
isMaskEmpty,
|
isMaskEmpty,
|
||||||
|
hasInpaintingImage,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,14 +1,30 @@
|
|||||||
import React from 'react';
|
|
||||||
import { MdCancel } from 'react-icons/md';
|
import { MdCancel } from 'react-icons/md';
|
||||||
import { cancelProcessing } from '../../../app/socketio/actions';
|
import { cancelProcessing } from '../../../app/socketio/actions';
|
||||||
import { useAppDispatch, useAppSelector } from '../../../app/store';
|
import { RootState, useAppDispatch, useAppSelector } from '../../../app/store';
|
||||||
import IAIIconButton from '../../../common/components/IAIIconButton';
|
import IAIIconButton from '../../../common/components/IAIIconButton';
|
||||||
import { systemSelector } from '../../../common/hooks/useCheckParameters';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { SystemState } from '../../system/systemSlice';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
const cancelButtonSelector = createSelector(
|
||||||
|
(state: RootState) => state.system,
|
||||||
|
(system: SystemState) => {
|
||||||
|
return {
|
||||||
|
isProcessing: system.isProcessing,
|
||||||
|
isConnected: system.isConnected,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
memoizeOptions: {
|
||||||
|
resultEqualityCheck: _.isEqual,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default function CancelButton() {
|
export default function CancelButton() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { isProcessing, isConnected } = useAppSelector(systemSelector);
|
const { isProcessing, isConnected } = useAppSelector(cancelButtonSelector);
|
||||||
const handleClickCancel = () => dispatch(cancelProcessing());
|
const handleClickCancel = () => dispatch(cancelProcessing());
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
|
@ -5,25 +5,22 @@ import { generateImage } from '../../../app/socketio/actions';
|
|||||||
|
|
||||||
import { OptionsState, setPrompt } from '../optionsSlice';
|
import { OptionsState, setPrompt } from '../optionsSlice';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { isEqual } from 'lodash';
|
import _ from 'lodash';
|
||||||
import useCheckParameters, {
|
import useCheckParameters from '../../../common/hooks/useCheckParameters';
|
||||||
systemSelector,
|
|
||||||
} from '../../../common/hooks/useCheckParameters';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { tabMap } from '../../tabs/InvokeTabs';
|
import { tabMap } from '../../tabs/InvokeTabs';
|
||||||
|
|
||||||
export const optionsSelector = createSelector(
|
const promptInputSelector = createSelector(
|
||||||
(state: RootState) => state.options,
|
(state: RootState) => state.options,
|
||||||
(options: OptionsState) => {
|
(options: OptionsState) => {
|
||||||
const { prompt, activeTab } = options;
|
|
||||||
return {
|
return {
|
||||||
prompt,
|
prompt: options.prompt,
|
||||||
activeTabName: tabMap[activeTab],
|
activeTabName: tabMap[options.activeTab],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
memoizeOptions: {
|
memoizeOptions: {
|
||||||
resultEqualityCheck: isEqual,
|
resultEqualityCheck: _.isEqual,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -33,8 +30,7 @@ export const optionsSelector = createSelector(
|
|||||||
*/
|
*/
|
||||||
const PromptInput = () => {
|
const PromptInput = () => {
|
||||||
const promptRef = useRef<HTMLTextAreaElement>(null);
|
const promptRef = useRef<HTMLTextAreaElement>(null);
|
||||||
const { prompt, activeTabName } = useAppSelector(optionsSelector);
|
const { prompt, activeTabName } = useAppSelector(promptInputSelector);
|
||||||
const { isProcessing } = useAppSelector(systemSelector);
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isReady = useCheckParameters();
|
const isReady = useCheckParameters();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user