mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Fixes canvas toolbar upload button
This commit is contained in:
parent
83d8e69219
commit
0f6856b719
@ -13,6 +13,7 @@ import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
|||||||
import { tabDict } from 'features/tabs/components/InvokeTabs';
|
import { tabDict } from 'features/tabs/components/InvokeTabs';
|
||||||
import ImageUploadOverlay from './ImageUploadOverlay';
|
import ImageUploadOverlay from './ImageUploadOverlay';
|
||||||
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
|
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
|
||||||
|
import useImageUploader from 'common/hooks/useImageUploader';
|
||||||
|
|
||||||
type ImageUploaderProps = {
|
type ImageUploaderProps = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -24,6 +25,7 @@ const ImageUploader = (props: ImageUploaderProps) => {
|
|||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
const toast = useToast({});
|
const toast = useToast({});
|
||||||
const [isHandlingUpload, setIsHandlingUpload] = useState<boolean>(false);
|
const [isHandlingUpload, setIsHandlingUpload] = useState<boolean>(false);
|
||||||
|
const { setOpenUploader } = useImageUploader();
|
||||||
|
|
||||||
const fileRejectionCallback = useCallback(
|
const fileRejectionCallback = useCallback(
|
||||||
(rejection: FileRejection) => {
|
(rejection: FileRejection) => {
|
||||||
@ -77,6 +79,8 @@ const ImageUploader = (props: ImageUploaderProps) => {
|
|||||||
maxFiles: 1,
|
maxFiles: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setOpenUploader(open);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const pasteImageListener = (e: ClipboardEvent) => {
|
const pasteImageListener = (e: ClipboardEvent) => {
|
||||||
const dataTransferItemList = e.clipboardData?.items;
|
const dataTransferItemList = e.clipboardData?.items;
|
||||||
|
14
frontend/src/common/hooks/useImageUploader.ts
Normal file
14
frontend/src/common/hooks/useImageUploader.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
let openFunction: () => void;
|
||||||
|
|
||||||
|
const useImageUploader = () => {
|
||||||
|
return {
|
||||||
|
setOpenUploader: (open?: () => void) => {
|
||||||
|
if (open) {
|
||||||
|
openFunction = open;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openUploader: openFunction,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useImageUploader;
|
@ -1,115 +0,0 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import {
|
|
||||||
setBrushColor,
|
|
||||||
setBrushSize,
|
|
||||||
setTool,
|
|
||||||
} from 'features/canvas/store/canvasSlice';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
|
||||||
import { FaPaintBrush } from 'react-icons/fa';
|
|
||||||
import IAIPopover from 'common/components/IAIPopover';
|
|
||||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
|
||||||
import IAISlider from 'common/components/IAISlider';
|
|
||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import {
|
|
||||||
canvasSelector,
|
|
||||||
isStagingSelector,
|
|
||||||
} from 'features/canvas/store/canvasSelectors';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
|
||||||
|
|
||||||
export const selector = createSelector(
|
|
||||||
[canvasSelector, isStagingSelector],
|
|
||||||
(canvas, isStaging) => {
|
|
||||||
const { brushColor, brushSize, tool } = canvas;
|
|
||||||
|
|
||||||
return {
|
|
||||||
tool,
|
|
||||||
brushColor,
|
|
||||||
brushSize,
|
|
||||||
isStaging,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: _.isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const IAICanvasBrushButtonPopover = () => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { tool, brushColor, brushSize, isStaging } = useAppSelector(selector);
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
['b'],
|
|
||||||
() => {
|
|
||||||
handleSelectBrushTool();
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: () => true,
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
['['],
|
|
||||||
() => {
|
|
||||||
dispatch(setBrushSize(Math.max(brushSize - 5, 5)));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: () => true,
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
[brushSize]
|
|
||||||
);
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
[']'],
|
|
||||||
() => {
|
|
||||||
dispatch(setBrushSize(Math.min(brushSize + 5, 500)));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: () => true,
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
[brushSize]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSelectBrushTool = () => dispatch(setTool('brush'));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IAIPopover
|
|
||||||
trigger="hover"
|
|
||||||
triggerComponent={
|
|
||||||
<IAIIconButton
|
|
||||||
aria-label="Brush Tool (B)"
|
|
||||||
tooltip="Brush Tool (B)"
|
|
||||||
icon={<FaPaintBrush />}
|
|
||||||
data-selected={tool === 'brush' && !isStaging}
|
|
||||||
onClick={handleSelectBrushTool}
|
|
||||||
isDisabled={isStaging}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Flex minWidth={'15rem'} direction={'column'} gap={'1rem'} width={'100%'}>
|
|
||||||
<Flex gap={'1rem'} justifyContent="space-between">
|
|
||||||
<IAISlider
|
|
||||||
label="Size"
|
|
||||||
value={brushSize}
|
|
||||||
withInput
|
|
||||||
onChange={(newSize) => dispatch(setBrushSize(newSize))}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<IAIColorPicker
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
color={brushColor}
|
|
||||||
onChange={(newColor) => dispatch(setBrushColor(newColor))}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</IAIPopover>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default IAICanvasBrushButtonPopover;
|
|
@ -1,101 +0,0 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import { setBrushSize, setTool } from 'features/canvas/store/canvasSlice';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
|
||||||
import { FaEraser } from 'react-icons/fa';
|
|
||||||
import IAIPopover from 'common/components/IAIPopover';
|
|
||||||
import IAISlider from 'common/components/IAISlider';
|
|
||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
|
||||||
import {
|
|
||||||
canvasSelector,
|
|
||||||
isStagingSelector,
|
|
||||||
} from 'features/canvas/store/canvasSelectors';
|
|
||||||
|
|
||||||
export const selector = createSelector(
|
|
||||||
[canvasSelector, isStagingSelector],
|
|
||||||
(canvas, isStaging) => {
|
|
||||||
const { brushSize, tool } = canvas;
|
|
||||||
|
|
||||||
return {
|
|
||||||
tool,
|
|
||||||
brushSize,
|
|
||||||
isStaging,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: _.isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const IAICanvasEraserButtonPopover = () => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { tool, brushSize, isStaging } = useAppSelector(selector);
|
|
||||||
|
|
||||||
const handleSelectEraserTool = () => dispatch(setTool('eraser'));
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
['e'],
|
|
||||||
() => {
|
|
||||||
handleSelectEraserTool();
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: () => true,
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
[tool]
|
|
||||||
);
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
['['],
|
|
||||||
() => {
|
|
||||||
dispatch(setBrushSize(Math.max(brushSize - 5, 5)));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: () => true,
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
[brushSize]
|
|
||||||
);
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
[']'],
|
|
||||||
() => {
|
|
||||||
dispatch(setBrushSize(Math.min(brushSize + 5, 500)));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enabled: () => true,
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
[brushSize]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IAIPopover
|
|
||||||
trigger="hover"
|
|
||||||
triggerComponent={
|
|
||||||
<IAIIconButton
|
|
||||||
aria-label="Eraser Tool (E)"
|
|
||||||
tooltip="Eraser Tool (E)"
|
|
||||||
icon={<FaEraser />}
|
|
||||||
data-selected={tool === 'eraser' && !isStaging}
|
|
||||||
isDisabled={isStaging}
|
|
||||||
onClick={() => dispatch(setTool('eraser'))}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Flex minWidth={'15rem'} direction={'column'} gap={'1rem'}>
|
|
||||||
<IAISlider
|
|
||||||
label="Size"
|
|
||||||
value={brushSize}
|
|
||||||
withInput
|
|
||||||
onChange={(newSize) => dispatch(setBrushSize(newSize))}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</IAIPopover>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default IAICanvasEraserButtonPopover;
|
|
@ -4,47 +4,36 @@ import {
|
|||||||
resetCanvas,
|
resetCanvas,
|
||||||
resetCanvasView,
|
resetCanvasView,
|
||||||
resizeAndScaleCanvas,
|
resizeAndScaleCanvas,
|
||||||
setTool,
|
|
||||||
} from 'features/canvas/store/canvasSlice';
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
import {
|
import {
|
||||||
FaArrowsAlt,
|
|
||||||
FaCopy,
|
FaCopy,
|
||||||
FaCrosshairs,
|
FaCrosshairs,
|
||||||
FaDownload,
|
FaDownload,
|
||||||
FaLayerGroup,
|
FaLayerGroup,
|
||||||
FaSave,
|
FaSave,
|
||||||
FaSlidersH,
|
|
||||||
FaTrash,
|
FaTrash,
|
||||||
FaUpload,
|
FaUpload,
|
||||||
} from 'react-icons/fa';
|
} from 'react-icons/fa';
|
||||||
import IAICanvasUndoButton from './IAICanvasUndoButton';
|
import IAICanvasUndoButton from './IAICanvasUndoButton';
|
||||||
import IAICanvasRedoButton from './IAICanvasRedoButton';
|
import IAICanvasRedoButton from './IAICanvasRedoButton';
|
||||||
import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover';
|
import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover';
|
||||||
import IAICanvasEraserButtonPopover from './IAICanvasEraserButtonPopover';
|
|
||||||
import IAICanvasBrushButtonPopover from './IAICanvasBrushButtonPopover';
|
|
||||||
import IAICanvasMaskOptions from './IAICanvasMaskOptions';
|
import IAICanvasMaskOptions from './IAICanvasMaskOptions';
|
||||||
import { mergeAndUploadCanvas } from 'features/canvas/store/thunks/mergeAndUploadCanvas';
|
import { mergeAndUploadCanvas } from 'features/canvas/store/thunks/mergeAndUploadCanvas';
|
||||||
import {
|
|
||||||
canvasSelector,
|
|
||||||
isStagingSelector,
|
|
||||||
} from 'features/canvas/store/canvasSelectors';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions';
|
import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions';
|
||||||
|
import useImageUploader from 'common/hooks/useImageUploader';
|
||||||
|
|
||||||
export const selector = createSelector(
|
export const selector = createSelector(
|
||||||
[canvasSelector, isStagingSelector, systemSelector],
|
[systemSelector],
|
||||||
(canvas, isStaging, system) => {
|
(system) => {
|
||||||
const { isProcessing } = system;
|
const { isProcessing } = system;
|
||||||
const { tool } = canvas;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tool,
|
|
||||||
isStaging,
|
|
||||||
isProcessing,
|
isProcessing,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -57,9 +46,11 @@ export const selector = createSelector(
|
|||||||
|
|
||||||
const IAICanvasOutpaintingControls = () => {
|
const IAICanvasOutpaintingControls = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { tool, isStaging, isProcessing } = useAppSelector(selector);
|
const { isProcessing } = useAppSelector(selector);
|
||||||
const canvasBaseLayer = getCanvasBaseLayer();
|
const canvasBaseLayer = getCanvasBaseLayer();
|
||||||
|
|
||||||
|
const { openUploader } = useImageUploader();
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
['r'],
|
['r'],
|
||||||
() => {
|
() => {
|
||||||
@ -219,6 +210,7 @@ const IAICanvasOutpaintingControls = () => {
|
|||||||
aria-label="Upload"
|
aria-label="Upload"
|
||||||
tooltip="Upload"
|
tooltip="Upload"
|
||||||
icon={<FaUpload />}
|
icon={<FaUpload />}
|
||||||
|
onClick={openUploader}
|
||||||
/>
|
/>
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
aria-label="Reset View (R)"
|
aria-label="Reset View (R)"
|
||||||
|
Loading…
Reference in New Issue
Block a user