feat(ui): restore image post-upload actions

eg set init image if on img2img when uploading
This commit is contained in:
psychedelicious 2023-05-15 18:52:48 +10:00
parent 835922ea8f
commit d95fe5925a
6 changed files with 34 additions and 25 deletions

View File

@ -4,6 +4,8 @@ import { uploadAdded } from 'features/gallery/store/uploadsSlice';
import { imageSelected } from 'features/gallery/store/gallerySlice'; import { imageSelected } from 'features/gallery/store/gallerySlice';
import { imageUploaded } from 'services/thunks/image'; import { imageUploaded } from 'services/thunks/image';
import { addToast } from 'features/system/store/systemSlice'; import { addToast } from 'features/system/store/systemSlice';
import { initialImageSelected } from 'features/parameters/store/actions';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
export const addImageUploadedListener = () => { export const addImageUploadedListener = () => {
startAppListening({ startAppListening({
@ -23,6 +25,14 @@ export const addImageUploadedListener = () => {
if (state.gallery.shouldAutoSwitchToNewImages) { if (state.gallery.shouldAutoSwitchToNewImages) {
dispatch(imageSelected(image)); dispatch(imageSelected(image));
} }
if (action.meta.arg.activeTabName === 'img2img') {
dispatch(initialImageSelected(image));
}
if (action.meta.arg.activeTabName === 'unifiedCanvas') {
dispatch(setInitialCanvasImage(image));
}
}, },
}); });
}; };

View File

@ -66,9 +66,15 @@ const ImageUploader = (props: ImageUploaderProps) => {
const fileAcceptedCallback = useCallback( const fileAcceptedCallback = useCallback(
async (file: File) => { async (file: File) => {
dispatch(imageUploaded({ imageType: 'uploads', formData: { file } })); dispatch(
imageUploaded({
imageType: 'uploads',
formData: { file },
activeTabName,
})
);
}, },
[dispatch] [dispatch, activeTabName]
); );
const onDrop = useCallback( const onDrop = useCallback(
@ -111,18 +117,24 @@ const ImageUploader = (props: ImageUploaderProps) => {
}); });
useEffect(() => { useEffect(() => {
// This is a hack to allow pasting images into the uploader
const handlePaste = async (e: ClipboardEvent) => { const handlePaste = async (e: ClipboardEvent) => {
if (!inputRef.current) { if (!inputRef.current) {
return; return;
} }
if (e.clipboardData?.files) { if (e.clipboardData?.files) {
// Set the files on the inputRef
inputRef.current.files = e.clipboardData.files; inputRef.current.files = e.clipboardData.files;
// Dispatch the change event, dropzone catches this and we get to use its own validation
inputRef.current?.dispatchEvent(new Event('change', { bubbles: true })); inputRef.current?.dispatchEvent(new Event('change', { bubbles: true }));
} }
}; };
// Set the open function so we can open the uploader from anywhere
setOpenUploaderFunction(open); setOpenUploaderFunction(open);
// Add the paste event listener
document.addEventListener('paste', handlePaste); document.addEventListener('paste', handlePaste);
return () => { return () => {

View File

@ -1,20 +0,0 @@
import { VStack } from '@chakra-ui/react';
import ImageToImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageFit';
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
import { useTranslation } from 'react-i18next';
import InitialImagePreview from './InitialImagePreview';
import InitialImageButtons from 'common/components/ImageToImageButtons';
export default function ImageToImageSettings() {
const { t } = useTranslation();
return (
<VStack gap={2} w="full" alignItems="stretch">
<InitialImageButtons />
<InitialImagePreview />
<ImageToImageStrength />
<ImageToImageFit />
</VStack>
);
}

View File

@ -1,6 +1,6 @@
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import InitialImagePreview from './InitialImagePreview'; import InitialImagePreview from './InitialImagePreview';
import InitialImageButtons from 'common/components/ImageToImageButtons'; import InitialImageButtons from 'common/components/InitialImageButtons';
const InitialImageDisplay = () => { const InitialImageDisplay = () => {
return ( return (

View File

@ -1,5 +1,6 @@
import { log } from 'app/logging/useLogger'; import { log } from 'app/logging/useLogger';
import { createAppAsyncThunk } from 'app/store/storeUtils'; import { createAppAsyncThunk } from 'app/store/storeUtils';
import { InvokeTabName } from 'features/ui/store/tabMap';
import { ImagesService } from 'services/api'; import { ImagesService } from 'services/api';
import { getHeaders } from 'services/util/getHeaders'; import { getHeaders } from 'services/util/getHeaders';
@ -39,7 +40,11 @@ export const thumbnailReceived = createAppAsyncThunk(
} }
); );
type ImageUploadedArg = Parameters<(typeof ImagesService)['uploadImage']>[0]; type ImageUploadedArg = Parameters<(typeof ImagesService)['uploadImage']>[0] & {
// extra arg to determine post-upload actions - we check for this when the image is uploaded
// to determine if we should set the init image
activeTabName?: InvokeTabName;
};
/** /**
* `ImagesService.uploadImage()` thunk * `ImagesService.uploadImage()` thunk
@ -47,7 +52,9 @@ type ImageUploadedArg = Parameters<(typeof ImagesService)['uploadImage']>[0];
export const imageUploaded = createAppAsyncThunk( export const imageUploaded = createAppAsyncThunk(
'api/imageUploaded', 'api/imageUploaded',
async (arg: ImageUploadedArg) => { async (arg: ImageUploadedArg) => {
const response = await ImagesService.uploadImage(arg); // strip out `activeTabName` from arg - the route does not need it
const { activeTabName, ...rest } = arg;
const response = await ImagesService.uploadImage(rest);
const { location } = getHeaders(response); const { location } = getHeaders(response);
imagesLog.info( imagesLog.info(