diff --git a/frontend/src/common/components/ImageUploader.tsx b/frontend/src/common/components/ImageUploader.tsx index c6d9418ea3..04cce48b5d 100644 --- a/frontend/src/common/components/ImageUploader.tsx +++ b/frontend/src/common/components/ImageUploader.tsx @@ -13,6 +13,7 @@ import { activeTabNameSelector } from 'features/options/store/optionsSelectors'; import { tabDict } from 'features/tabs/components/InvokeTabs'; import ImageUploadOverlay from './ImageUploadOverlay'; import { uploadImage } from 'features/gallery/store/thunks/uploadImage'; +import useImageUploader from 'common/hooks/useImageUploader'; type ImageUploaderProps = { children: ReactNode; @@ -24,6 +25,7 @@ const ImageUploader = (props: ImageUploaderProps) => { const activeTabName = useAppSelector(activeTabNameSelector); const toast = useToast({}); const [isHandlingUpload, setIsHandlingUpload] = useState(false); + const { setOpenUploader } = useImageUploader(); const fileRejectionCallback = useCallback( (rejection: FileRejection) => { @@ -77,6 +79,8 @@ const ImageUploader = (props: ImageUploaderProps) => { maxFiles: 1, }); + setOpenUploader(open); + useEffect(() => { const pasteImageListener = (e: ClipboardEvent) => { const dataTransferItemList = e.clipboardData?.items; diff --git a/frontend/src/common/hooks/useImageUploader.ts b/frontend/src/common/hooks/useImageUploader.ts new file mode 100644 index 0000000000..10c81c4dfd --- /dev/null +++ b/frontend/src/common/hooks/useImageUploader.ts @@ -0,0 +1,14 @@ +let openFunction: () => void; + +const useImageUploader = () => { + return { + setOpenUploader: (open?: () => void) => { + if (open) { + openFunction = open; + } + }, + openUploader: openFunction, + }; +}; + +export default useImageUploader; diff --git a/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasBrushButtonPopover.tsx b/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasBrushButtonPopover.tsx deleted file mode 100644 index 7f2332a4dc..0000000000 --- a/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasBrushButtonPopover.tsx +++ /dev/null @@ -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 ( - } - data-selected={tool === 'brush' && !isStaging} - onClick={handleSelectBrushTool} - isDisabled={isStaging} - /> - } - > - - - dispatch(setBrushSize(newSize))} - /> - - dispatch(setBrushColor(newColor))} - /> - - - ); -}; - -export default IAICanvasBrushButtonPopover; diff --git a/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasEraserButtonPopover.tsx b/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasEraserButtonPopover.tsx deleted file mode 100644 index 643c2afb26..0000000000 --- a/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasEraserButtonPopover.tsx +++ /dev/null @@ -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 ( - } - data-selected={tool === 'eraser' && !isStaging} - isDisabled={isStaging} - onClick={() => dispatch(setTool('eraser'))} - /> - } - > - - dispatch(setBrushSize(newSize))} - /> - - - ); -}; - -export default IAICanvasEraserButtonPopover; diff --git a/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx b/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx index 19e88263ac..7b94a1e7b0 100644 --- a/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx +++ b/frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx @@ -4,47 +4,36 @@ import { resetCanvas, resetCanvasView, resizeAndScaleCanvas, - setTool, } from 'features/canvas/store/canvasSlice'; import { useAppDispatch, useAppSelector } from 'app/store'; import _ from 'lodash'; import IAIIconButton from 'common/components/IAIIconButton'; import { - FaArrowsAlt, FaCopy, FaCrosshairs, FaDownload, FaLayerGroup, FaSave, - FaSlidersH, FaTrash, FaUpload, } from 'react-icons/fa'; import IAICanvasUndoButton from './IAICanvasUndoButton'; import IAICanvasRedoButton from './IAICanvasRedoButton'; import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover'; -import IAICanvasEraserButtonPopover from './IAICanvasEraserButtonPopover'; -import IAICanvasBrushButtonPopover from './IAICanvasBrushButtonPopover'; import IAICanvasMaskOptions from './IAICanvasMaskOptions'; import { mergeAndUploadCanvas } from 'features/canvas/store/thunks/mergeAndUploadCanvas'; -import { - canvasSelector, - isStagingSelector, -} from 'features/canvas/store/canvasSelectors'; import { useHotkeys } from 'react-hotkeys-hook'; import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider'; import { systemSelector } from 'features/system/store/systemSelectors'; import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions'; +import useImageUploader from 'common/hooks/useImageUploader'; export const selector = createSelector( - [canvasSelector, isStagingSelector, systemSelector], - (canvas, isStaging, system) => { + [systemSelector], + (system) => { const { isProcessing } = system; - const { tool } = canvas; return { - tool, - isStaging, isProcessing, }; }, @@ -57,9 +46,11 @@ export const selector = createSelector( const IAICanvasOutpaintingControls = () => { const dispatch = useAppDispatch(); - const { tool, isStaging, isProcessing } = useAppSelector(selector); + const { isProcessing } = useAppSelector(selector); const canvasBaseLayer = getCanvasBaseLayer(); + const { openUploader } = useImageUploader(); + useHotkeys( ['r'], () => { @@ -219,6 +210,7 @@ const IAICanvasOutpaintingControls = () => { aria-label="Upload" tooltip="Upload" icon={} + onClick={openUploader} />