feat(ui): support image dnd to canvas

This commit is contained in:
psychedelicious 2023-06-05 13:13:39 +10:00
parent 2c77563dcc
commit 7bd94eac0e
4 changed files with 92 additions and 109 deletions

View File

@ -30,6 +30,7 @@ import {
} from './canvasTypes';
import { ImageDTO } from 'services/api';
import { sessionCanceled } from 'services/thunks/session';
import { setShouldUseCanvasBetaLayout } from 'features/ui/store/uiSlice';
export const initialLayerState: CanvasLayerState = {
objects: [],
@ -851,6 +852,10 @@ export const canvasSlice = createSlice({
state.layerState.stagingArea = initialLayerState.stagingArea;
}
});
builder.addCase(setShouldUseCanvasBetaLayout, (state, action) => {
state.doesCanvasNeedScaling = true;
});
},
});

View File

@ -1,72 +0,0 @@
import { createSelector } from '@reduxjs/toolkit';
// import IAICanvas from 'features/canvas/components/IAICanvas';
import { Box, Flex } from '@chakra-ui/react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAICanvas from 'features/canvas/components/IAICanvas';
import IAICanvasResizer from 'features/canvas/components/IAICanvasResizer';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { isEqual } from 'lodash-es';
import { useLayoutEffect } from 'react';
import UnifiedCanvasToolbarBeta from './UnifiedCanvasToolbarBeta';
import UnifiedCanvasToolSettingsBeta from './UnifiedCanvasToolSettingsBeta';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
const selector = createSelector(
[canvasSelector],
(canvas) => {
const { doesCanvasNeedScaling } = canvas;
return {
doesCanvasNeedScaling,
};
},
{
memoizeOptions: {
resultEqualityCheck: isEqual,
},
}
);
const UnifiedCanvasContentBeta = () => {
const dispatch = useAppDispatch();
const { doesCanvasNeedScaling } = useAppSelector(selector);
useLayoutEffect(() => {
dispatch(requestCanvasRescale());
const resizeCallback = () => {
dispatch(requestCanvasRescale());
};
window.addEventListener('resize', resizeCallback);
return () => window.removeEventListener('resize', resizeCallback);
}, [dispatch]);
return (
<Box
sx={{
width: '100%',
height: '100%',
borderRadius: 'base',
bg: 'base.850',
}}
>
<Flex
flexDirection="row"
width="100%"
height="100%"
columnGap={4}
padding={4}
>
<UnifiedCanvasToolbarBeta />
<Flex width="100%" height="100%" flexDirection="column" rowGap={4}>
<UnifiedCanvasToolSettingsBeta />
{doesCanvasNeedScaling ? <IAICanvasResizer /> : <IAICanvas />}
</Flex>
</Flex>
</Box>
);
};
export default UnifiedCanvasContentBeta;

View File

@ -1,34 +1,58 @@
import { Box, Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAICanvas from 'features/canvas/components/IAICanvas';
import IAICanvasResizer from 'features/canvas/components/IAICanvasResizer';
import IAICanvasToolbar from 'features/canvas/components/IAICanvasToolbar/IAICanvasToolbar';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
import { isEqual } from 'lodash-es';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo, useLayoutEffect } from 'react';
import { memo, useCallback, useLayoutEffect } from 'react';
import UnifiedCanvasToolbarBeta from './UnifiedCanvasBeta/UnifiedCanvasToolbarBeta';
import UnifiedCanvasToolSettingsBeta from './UnifiedCanvasBeta/UnifiedCanvasToolSettingsBeta';
import { ImageDTO } from 'services/api';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
import { useDroppable } from '@dnd-kit/core';
import IAIDropOverlay from 'common/components/IAIDropOverlay';
const selector = createSelector(
[canvasSelector],
(canvas) => {
[canvasSelector, uiSelector],
(canvas, ui) => {
const { doesCanvasNeedScaling } = canvas;
const { shouldUseCanvasBetaLayout } = ui;
return {
doesCanvasNeedScaling,
shouldUseCanvasBetaLayout,
};
},
{
memoizeOptions: {
resultEqualityCheck: isEqual,
},
}
defaultSelectorOptions
);
const UnifiedCanvasContent = () => {
const dispatch = useAppDispatch();
const { doesCanvasNeedScaling } = useAppSelector(selector);
const { doesCanvasNeedScaling, shouldUseCanvasBetaLayout } =
useAppSelector(selector);
const onDrop = useCallback(
(droppedImage: ImageDTO) => {
dispatch(setInitialCanvasImage(droppedImage));
},
[dispatch]
);
const {
isOver,
setNodeRef: setDroppableRef,
active,
} = useDroppable({
id: 'unifiedCanvas',
data: {
handleDrop: onDrop,
},
});
useLayoutEffect(() => {
dispatch(requestCanvasRescale());
@ -42,14 +66,55 @@ const UnifiedCanvasContent = () => {
return () => window.removeEventListener('resize', resizeCallback);
}, [dispatch]);
if (shouldUseCanvasBetaLayout) {
return (
<Box
ref={setDroppableRef}
sx={{
width: '100%',
height: '100%',
padding: 4,
w: 'full',
h: 'full',
borderRadius: 'base',
bg: 'base.850',
p: 4,
}}
>
<Flex
sx={{
w: 'full',
h: 'full',
gap: 4,
}}
>
<UnifiedCanvasToolbarBeta />
<Flex
sx={{
flexDir: 'column',
w: 'full',
h: 'full',
gap: 4,
position: 'relative',
}}
>
<UnifiedCanvasToolSettingsBeta />
<Box sx={{ w: 'full', h: 'full', position: 'relative' }}>
{doesCanvasNeedScaling ? <IAICanvasResizer /> : <IAICanvas />}
{active && <IAIDropOverlay isOver={isOver} />}
</Box>
</Flex>
</Flex>
</Box>
);
}
return (
<Box
ref={setDroppableRef}
sx={{
w: 'full',
h: 'full',
borderRadius: 'base',
bg: 'base.850',
p: 4,
}}
>
<Flex
@ -57,8 +122,8 @@ const UnifiedCanvasContent = () => {
flexDirection: 'column',
alignItems: 'center',
gap: 4,
width: '100%',
height: '100%',
w: 'full',
h: 'full',
}}
>
<IAICanvasToolbar />
@ -68,11 +133,14 @@ const UnifiedCanvasContent = () => {
alignItems: 'center',
justifyContent: 'center',
gap: 4,
width: '100%',
height: '100%',
w: 'full',
h: 'full',
}}
>
<Box sx={{ w: 'full', h: 'full', position: 'relative' }}>
{doesCanvasNeedScaling ? <IAICanvasResizer /> : <IAICanvas />}
{active && <IAIDropOverlay isOver={isOver} />}
</Box>
</Flex>
</Flex>
</Box>

View File

@ -1,34 +1,16 @@
import { Flex } from '@chakra-ui/react';
import { memo } from 'react';
import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { useAppSelector } from 'app/store/storeHooks';
import UnifiedCanvasContent from './UnifiedCanvasContent';
import UnifiedCanvasParameters from './UnifiedCanvasParameters';
import UnifiedCanvasContentBeta from './UnifiedCanvasBeta/UnifiedCanvasContentBeta';
import ParametersPinnedWrapper from '../../ParametersPinnedWrapper';
const selector = createSelector(uiSelector, (ui) => {
const { shouldUseCanvasBetaLayout } = ui;
return {
shouldUseCanvasBetaLayout,
};
});
const UnifiedCanvasTab = () => {
const { shouldUseCanvasBetaLayout } = useAppSelector(selector);
return (
<Flex sx={{ gap: 4, w: 'full', h: 'full' }}>
<ParametersPinnedWrapper>
<UnifiedCanvasParameters />
</ParametersPinnedWrapper>
{shouldUseCanvasBetaLayout ? (
<UnifiedCanvasContentBeta />
) : (
<UnifiedCanvasContent />
)}
</Flex>
);
};