Files
InvokeAI/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadEditImageButton.tsx
2025-06-30 23:42:53 +10:00

44 lines
1.9 KiB
TypeScript

import { Flex, Heading, Icon, Text } from '@invoke-ai/ui-library';
import { useAppStore } from 'app/store/storeHooks';
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
import { LaunchpadButton } from 'features/controlLayers/components/SimpleSession/LaunchpadButton';
import { newCanvasFromImageDndTarget } from 'features/dnd/dnd';
import { DndDropTarget } from 'features/dnd/DndDropTarget';
import { newCanvasFromImage } from 'features/imageActions/actions';
import { memo, useCallback } from 'react';
import { PiPencilBold, PiUploadBold } from 'react-icons/pi';
import type { ImageDTO } from 'services/api/types';
const NEW_CANVAS_OPTIONS = { type: 'raster_layer', withInpaintMask: true } as const;
const dndTargetData = newCanvasFromImageDndTarget.getData(NEW_CANVAS_OPTIONS);
export const LaunchpadEditImageButton = memo((props: { extraAction?: () => void }) => {
const { getState, dispatch } = useAppStore();
const onUpload = useCallback(
(imageDTO: ImageDTO) => {
newCanvasFromImage({ imageDTO, getState, dispatch, ...NEW_CANVAS_OPTIONS });
props.extraAction?.();
},
[dispatch, getState, props]
);
const uploadApi = useImageUploadButton({ allowMultiple: false, onUpload });
return (
<LaunchpadButton {...uploadApi.getUploadButtonProps()} position="relative" gap={8}>
<Icon as={PiPencilBold} boxSize={8} color="base.500" />
<Flex flexDir="column" alignItems="flex-start" gap={2}>
<Heading size="sm">Edit Image</Heading>
<Text color="base.300">Add an image to refine.</Text>
</Flex>
<Flex position="absolute" right={3} bottom={3}>
<PiUploadBold />
<input {...uploadApi.getUploadInputProps()} />
</Flex>
<DndDropTarget dndTarget={newCanvasFromImageDndTarget} dndTargetData={dndTargetData} label="Drop" />
</LaunchpadButton>
);
});
LaunchpadEditImageButton.displayName = 'LaunchpadEditImageButton';