feat(ui): dndkit --> rnd for draggable

This commit is contained in:
psychedelicious
2023-04-30 23:39:42 +10:00
parent 779671753d
commit fecb77e344
6 changed files with 194 additions and 163 deletions

View File

@@ -1,25 +1,28 @@
import { Box, Flex, Icon, Image, Text } from '@chakra-ui/react';
import { useDraggable } from '@dnd-kit/core';
import { Flex, Icon, Image, Text } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors';
import { memo, useCallback } from 'react';
import { CSS } from '@dnd-kit/utilities';
import { FaEye, FaImage, FaStopwatch } from 'react-icons/fa';
import { FaImage, FaStopwatch } from 'react-icons/fa';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { Resizable } from 're-resizable';
import IAIIconButton from 'common/components/IAIIconButton';
import { CloseIcon } from '@chakra-ui/icons';
import { useTranslation } from 'react-i18next';
import { shouldShowProgressImagesToggled } from 'features/ui/store/uiSlice';
import {
floatingProgressImageMoved,
floatingProgressImageResized,
shouldShowProgressImagesToggled,
} from 'features/ui/store/uiSlice';
import { Rnd } from 'react-rnd';
import { Rect } from 'features/ui/store/uiTypes';
const selector = createSelector([systemSelector, uiSelector], (system, ui) => {
const { progressImage } = system;
const { floatingProgressImageCoordinates, shouldShowProgressImages } = ui;
const { floatingProgressImageRect, shouldShowProgressImages } = ui;
return {
progressImage,
coords: floatingProgressImageCoordinates,
floatingProgressImageRect,
shouldShowProgressImages,
};
});
@@ -27,135 +30,137 @@ const selector = createSelector([systemSelector, uiSelector], (system, ui) => {
const ProgressImagePreview = () => {
const dispatch = useAppDispatch();
const { progressImage, coords, shouldShowProgressImages } =
const { progressImage, floatingProgressImageRect, shouldShowProgressImages } =
useAppSelector(selector);
const { t } = useTranslation();
const { attributes, listeners, setNodeRef, transform } = useDraggable({
id: 'progress-image',
});
const toggleProgressImages = useCallback(() => {
dispatch(shouldShowProgressImagesToggled());
}, [dispatch]);
const transformStyles = transform
? {
transform: CSS.Translate.toString(transform),
}
: {};
return shouldShowProgressImages ? (
<Box
sx={{
position: 'absolute',
left: `${coords.x}px`,
top: `${coords.y}px`,
<Rnd
bounds="window"
minHeight={200}
minWidth={200}
size={{
width: floatingProgressImageRect.width,
height: floatingProgressImageRect.height,
}}
position={{
x: floatingProgressImageRect.x,
y: floatingProgressImageRect.y,
}}
onDragStop={(e, d) => {
dispatch(floatingProgressImageMoved({ x: d.x, y: d.y }));
}}
onResizeStop={(e, direction, ref, delta, position) => {
const newRect: Partial<Rect> = {};
console.log(ref.style.width, ref.style.height, position.x, position.y);
if (ref.style.width) {
newRect.width = ref.style.width;
}
if (ref.style.height) {
newRect.height = ref.style.height;
}
if (position.x) {
newRect.x = position.x;
}
if (position.x) {
newRect.y = position.y;
}
dispatch(floatingProgressImageResized(newRect));
}}
>
<Box ref={setNodeRef} sx={transformStyles}>
<Box
<Flex
sx={{
position: 'relative',
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
flexDir: 'column',
boxShadow: 'dark-lg',
bg: 'base.800',
borderRadius: 'base',
}}
>
<Flex
sx={{
boxShadow: 'dark-lg',
w: 'full',
h: 'full',
bg: 'base.800',
borderRadius: 'base',
alignItems: 'center',
justifyContent: 'center',
p: 1.5,
pl: 4,
pr: 3,
bg: 'base.700',
borderTopRadius: 'base',
}}
>
<Resizable
defaultSize={{ width: 300, height: 300 }}
minWidth={200}
minHeight={200}
<Flex
sx={{
flexGrow: 1,
userSelect: 'none',
cursor: 'move',
}}
>
<Flex
<Text fontSize="sm" fontWeight={500}>
Progress Images
</Text>
</Flex>
<IAIIconButton
onClick={toggleProgressImages}
aria-label={t('ui.hideProgressImages')}
size="xs"
icon={<CloseIcon />}
variant="ghost"
/>
</Flex>
{progressImage ? (
<Flex
sx={{
position: 'relative',
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Image
draggable={false}
src={progressImage.dataURL}
width={progressImage.width}
height={progressImage.height}
sx={{
position: 'relative',
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
flexDir: 'column',
position: 'absolute',
objectFit: 'contain',
maxWidth: '100%',
maxHeight: '100%',
height: 'auto',
imageRendering: 'pixelated',
borderRadius: 'base',
p: 2,
}}
>
<Flex
sx={{
w: 'full',
alignItems: 'center',
justifyContent: 'center',
p: 1.5,
pl: 4,
pr: 3,
bg: 'base.700',
borderTopRadius: 'base',
}}
>
<Flex
sx={{
flexGrow: 1,
userSelect: 'none',
cursor: 'move',
}}
{...listeners}
{...attributes}
>
<Text fontSize="sm" fontWeight={500}>
Progress Images
</Text>
</Flex>
<IAIIconButton
onClick={toggleProgressImages}
aria-label={t('ui.hideProgressImages')}
size="xs"
icon={<CloseIcon />}
variant="ghost"
/>
</Flex>
{progressImage ? (
<Flex
sx={{
position: 'relative',
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Image
draggable={false}
src={progressImage.dataURL}
width={progressImage.width}
height={progressImage.height}
sx={{
position: 'absolute',
objectFit: 'contain',
maxWidth: '100%',
maxHeight: '100%',
height: 'auto',
imageRendering: 'pixelated',
borderRadius: 'base',
p: 2,
}}
/>
</Flex>
) : (
<Flex
sx={{
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Icon color="base.400" boxSize={32} as={FaImage}></Icon>
</Flex>
)}
</Flex>
</Resizable>
</Box>
</Box>
</Box>
/>
</Flex>
) : (
<Flex
sx={{
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Icon color="base.400" boxSize={32} as={FaImage}></Icon>
</Flex>
)}
</Flex>
</Rnd>
) : (
<IAIIconButton
onClick={toggleProgressImages}