mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
feat(ui): wip canvas migration, createListenerMiddleware
This commit is contained in:
@@ -5,9 +5,9 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import SelectImagePlaceholder from 'common/components/SelectImagePlaceholder';
|
||||
import { useGetUrl } from 'common/util/getUrl';
|
||||
import useGetImageByNameAndType from 'features/gallery/hooks/useGetImageByName';
|
||||
import {
|
||||
import generationSlice, {
|
||||
clearInitialImage,
|
||||
initialImageSelected,
|
||||
initialImageChanged,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { isEqual } from 'lodash-es';
|
||||
@@ -15,23 +15,26 @@ import { DragEvent, useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ImageType } from 'services/api';
|
||||
import ImageToImageOverlay from 'common/components/ImageToImageOverlay';
|
||||
import { initialImageSelector } from 'features/parameters/store/generationSelectors';
|
||||
import {
|
||||
generationSelector,
|
||||
initialImageSelector,
|
||||
} from 'features/parameters/store/generationSelectors';
|
||||
import { initialImageSelected } from 'features/parameters/store/actions';
|
||||
|
||||
const selector = createSelector(
|
||||
[initialImageSelector],
|
||||
(initialImage) => {
|
||||
[generationSelector],
|
||||
(generation) => {
|
||||
const { initialImage, isImageToImageEnabled } = generation;
|
||||
return {
|
||||
initialImage,
|
||||
isImageToImageEnabled,
|
||||
};
|
||||
},
|
||||
{ memoizeOptions: { resultEqualityCheck: isEqual } }
|
||||
);
|
||||
|
||||
const InitialImagePreview = () => {
|
||||
const isImageToImageEnabled = useAppSelector(
|
||||
(state: RootState) => state.generation.isImageToImageEnabled
|
||||
);
|
||||
const { initialImage } = useAppSelector(selector);
|
||||
const { initialImage, isImageToImageEnabled } = useAppSelector(selector);
|
||||
const { getUrl } = useGetUrl();
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
@@ -55,22 +58,13 @@ const InitialImagePreview = () => {
|
||||
const handleDrop = useCallback(
|
||||
(e: DragEvent<HTMLDivElement>) => {
|
||||
setIsLoaded(false);
|
||||
|
||||
const name = e.dataTransfer.getData('invokeai/imageName');
|
||||
const type = e.dataTransfer.getData('invokeai/imageType') as ImageType;
|
||||
|
||||
if (!name || !type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const image = getImageByNameAndType(name, type);
|
||||
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(initialImageSelected({ name, type }));
|
||||
},
|
||||
[getImageByNameAndType, dispatch]
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,9 +4,11 @@ import { isFinite, isString } from 'lodash-es';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useSetBothPrompts from './usePrompt';
|
||||
import { initialImageSelected, setSeed } from '../store/generationSlice';
|
||||
import { initialImageChanged, setSeed } from '../store/generationSlice';
|
||||
import { isImage, isImageField } from 'services/types/guards';
|
||||
import { NUMPY_RAND_MAX } from 'app/constants';
|
||||
import { initialImageSelected } from '../store/actions';
|
||||
import { Image } from 'app/types/invokeai';
|
||||
|
||||
export const useParameters = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -86,7 +88,7 @@ export const useParameters = () => {
|
||||
}
|
||||
|
||||
dispatch(
|
||||
initialImageSelected({ name: image.image_name, type: image.image_type })
|
||||
initialImageChanged({ name: image.image_name, type: image.image_type })
|
||||
);
|
||||
toast({
|
||||
title: t('toast.initialImageSet'),
|
||||
@@ -102,27 +104,10 @@ export const useParameters = () => {
|
||||
* Sets image as initial image with toast
|
||||
*/
|
||||
const sendToImageToImage = useCallback(
|
||||
(image: unknown) => {
|
||||
if (!isImage(image)) {
|
||||
toast({
|
||||
title: t('toast.imageNotLoaded'),
|
||||
description: t('toast.imageNotLoadedDesc'),
|
||||
status: 'warning',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
(image: Image) => {
|
||||
dispatch(initialImageSelected({ name: image.name, type: image.type }));
|
||||
toast({
|
||||
title: t('toast.sentToImageToImage'),
|
||||
status: 'info',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
},
|
||||
[t, toast, dispatch]
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
return { recallPrompt, recallSeed, recallInitialImage, sendToImageToImage };
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
import { Image } from 'app/types/invokeai';
|
||||
import { ImageType } from 'services/api';
|
||||
|
||||
export type SelectedImage = {
|
||||
name: string;
|
||||
type: ImageType;
|
||||
};
|
||||
|
||||
export const initialImageSelected = createAction<
|
||||
Image | SelectedImage | undefined
|
||||
>('generation/initialImageSelected');
|
||||
@@ -7,17 +7,12 @@ import { seedWeightsToString } from 'common/util/seedWeightPairs';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { ImageField, ImageType } from 'services/api';
|
||||
|
||||
export type SelectedImage = {
|
||||
name: string;
|
||||
type: ImageType;
|
||||
};
|
||||
|
||||
export interface GenerationState {
|
||||
cfgScale: number;
|
||||
height: number;
|
||||
img2imgStrength: number;
|
||||
infillMethod: string;
|
||||
initialImage?: SelectedImage; // can be an Image or url
|
||||
initialImage?: InvokeAI.Image; // can be an Image or url
|
||||
iterations: number;
|
||||
maskPath: string;
|
||||
perlin: number;
|
||||
@@ -351,7 +346,7 @@ export const generationSlice = createSlice({
|
||||
setVerticalSymmetrySteps: (state, action: PayloadAction<number>) => {
|
||||
state.verticalSymmetrySteps = action.payload;
|
||||
},
|
||||
initialImageSelected: (state, action: PayloadAction<SelectedImage>) => {
|
||||
initialImageChanged: (state, action: PayloadAction<InvokeAI.Image>) => {
|
||||
state.initialImage = action.payload;
|
||||
state.isImageToImageEnabled = true;
|
||||
},
|
||||
@@ -399,7 +394,7 @@ export const {
|
||||
setShouldUseSymmetry,
|
||||
setHorizontalSymmetrySteps,
|
||||
setVerticalSymmetrySteps,
|
||||
initialImageSelected,
|
||||
initialImageChanged,
|
||||
isImageToImageEnabledChanged,
|
||||
} = generationSlice.actions;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user