feat(ui): tweak floating preview

This commit is contained in:
psychedelicious 2023-04-30 23:08:27 +10:00
parent d5e152b35e
commit 779671753d
4 changed files with 90 additions and 111 deletions

View File

@ -28,13 +28,7 @@ import { configChanged } from 'features/system/store/configSlice';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { useLogger } from 'app/logging/useLogger'; import { useLogger } from 'app/logging/useLogger';
import ProgressImagePreview from 'features/parameters/components/ProgressImagePreview'; import ProgressImagePreview from 'features/parameters/components/ProgressImagePreview';
import { import { DndContext, DragEndEvent } from '@dnd-kit/core';
DndContext,
DragEndEvent,
PointerSensor,
useSensor,
useSensors,
} from '@dnd-kit/core';
import { floatingProgressImageMoved } from 'features/ui/store/uiSlice'; import { floatingProgressImageMoved } from 'features/ui/store/uiSlice';
import { restrictToWindowEdges } from '@dnd-kit/modifiers'; import { restrictToWindowEdges } from '@dnd-kit/modifiers';
@ -50,9 +44,6 @@ const App = ({ config = DEFAULT_CONFIG, children }: Props) => {
const log = useLogger(); const log = useLogger();
const currentTheme = useAppSelector((state) => state.ui.currentTheme); const currentTheme = useAppSelector((state) => state.ui.currentTheme);
const shouldShowProgressImage = useAppSelector(
(state) => state.ui.shouldShowProgressImage
);
const isLightboxEnabled = useFeatureStatus('lightbox').isFeatureEnabled; const isLightboxEnabled = useFeatureStatus('lightbox').isFeatureEnabled;
@ -85,22 +76,8 @@ const App = ({ config = DEFAULT_CONFIG, children }: Props) => {
[dispatch] [dispatch]
); );
const pointer = useSensor(PointerSensor, {
// Delay the drag events (allow clicks on elements)
activationConstraint: {
delay: 100,
tolerance: 5,
},
});
const sensors = useSensors(pointer);
return ( return (
<DndContext <DndContext onDragEnd={handleDragEnd} modifiers={[restrictToWindowEdges]}>
onDragEnd={handleDragEnd}
sensors={sensors}
modifiers={[restrictToWindowEdges]}
>
<Grid w="100vw" h="100vh" position="relative" overflow="hidden"> <Grid w="100vw" h="100vh" position="relative" overflow="hidden">
{isLightboxEnabled && <Lightbox />} {isLightboxEnabled && <Lightbox />}
<ImageUploader> <ImageUploader>

View File

@ -1,52 +1,45 @@
import { import { Box, Flex, Icon, Image, Text } from '@chakra-ui/react';
Accordion,
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
Box,
Flex,
Icon,
Image,
Text,
} from '@chakra-ui/react';
import { useDraggable } from '@dnd-kit/core'; import { useDraggable } from '@dnd-kit/core';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { memo, useCallback, useRef, MouseEvent } from 'react'; import { memo, useCallback } from 'react';
import { CSS } from '@dnd-kit/utilities'; import { CSS } from '@dnd-kit/utilities';
import { FaEye, FaImage } from 'react-icons/fa'; import { FaEye, FaImage, FaStopwatch } from 'react-icons/fa';
import { uiSelector } from 'features/ui/store/uiSelectors'; import { uiSelector } from 'features/ui/store/uiSelectors';
import { Resizable } from 're-resizable'; import { Resizable } from 're-resizable';
import { useBoolean, useHoverDirty } from 'react-use';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import { CloseIcon } from '@chakra-ui/icons'; import { CloseIcon } from '@chakra-ui/icons';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { shouldShowProgressImagesToggled } from 'features/ui/store/uiSlice';
const selector = createSelector([systemSelector, uiSelector], (system, ui) => { const selector = createSelector([systemSelector, uiSelector], (system, ui) => {
const { progressImage } = system; const { progressImage } = system;
const { floatingProgressImageCoordinates, shouldShowProgressImage } = ui; const { floatingProgressImageCoordinates, shouldShowProgressImages } = ui;
return { return {
progressImage, progressImage,
coords: floatingProgressImageCoordinates, coords: floatingProgressImageCoordinates,
shouldShowProgressImage, shouldShowProgressImages,
}; };
}); });
const ProgressImagePreview = () => { const ProgressImagePreview = () => {
const { progressImage, coords, shouldShowProgressImage } = const dispatch = useAppDispatch();
const { progressImage, coords, shouldShowProgressImages } =
useAppSelector(selector); useAppSelector(selector);
const [shouldShowProgressImages, toggleShouldShowProgressImages] =
useBoolean(false);
const { t } = useTranslation(); const { t } = useTranslation();
const { attributes, listeners, setNodeRef, transform } = useDraggable({ const { attributes, listeners, setNodeRef, transform } = useDraggable({
id: 'progress-image', id: 'progress-image',
}); });
const toggleProgressImages = useCallback(() => {
dispatch(shouldShowProgressImagesToggled());
}, [dispatch]);
const transformStyles = transform const transformStyles = transform
? { ? {
transform: CSS.Translate.toString(transform), transform: CSS.Translate.toString(transform),
@ -75,19 +68,6 @@ const ProgressImagePreview = () => {
defaultSize={{ width: 300, height: 300 }} defaultSize={{ width: 300, height: 300 }}
minWidth={200} minWidth={200}
minHeight={200} minHeight={200}
boundsByDirection={true}
enable={{ bottomRight: true }}
>
<Flex
sx={{
cursor: 'move',
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
}}
{...listeners}
{...attributes}
> >
<Flex <Flex
sx={{ sx={{
@ -96,9 +76,42 @@ const ProgressImagePreview = () => {
h: 'full', h: 'full',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
p: 4, flexDir: 'column',
}} }}
> >
<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 ? ( {progressImage ? (
<Flex <Flex
sx={{ sx={{
@ -110,6 +123,7 @@ const ProgressImagePreview = () => {
}} }}
> >
<Image <Image
draggable={false}
src={progressImage.dataURL} src={progressImage.dataURL}
width={progressImage.width} width={progressImage.width}
height={progressImage.height} height={progressImage.height}
@ -121,6 +135,7 @@ const ProgressImagePreview = () => {
height: 'auto', height: 'auto',
imageRendering: 'pixelated', imageRendering: 'pixelated',
borderRadius: 'base', borderRadius: 'base',
p: 2,
}} }}
/> />
</Flex> </Flex>
@ -137,30 +152,17 @@ const ProgressImagePreview = () => {
</Flex> </Flex>
)} )}
</Flex> </Flex>
<IAIIconButton
onClick={toggleShouldShowProgressImages}
aria-label={t('ui.hideProgressImages')}
size="xs"
icon={<CloseIcon />}
sx={{
position: 'absolute',
top: 2,
insetInlineEnd: 2,
}}
variant="ghost"
/>
</Flex>
</Resizable> </Resizable>
</Box> </Box>
</Box> </Box>
</Box> </Box>
) : ( ) : (
<IAIIconButton <IAIIconButton
onClick={toggleShouldShowProgressImages} onClick={toggleProgressImages}
tooltip={t('ui.showProgressImages')} tooltip={t('ui.showProgressImages')}
sx={{ position: 'absolute', bottom: 4, insetInlineStart: 4 }} sx={{ position: 'absolute', bottom: 4, insetInlineStart: 4 }}
aria-label={t('ui.showProgressImages')} aria-label={t('ui.showProgressImages')}
icon={<FaEye />} icon={<FaStopwatch />}
/> />
); );
}; };

View File

@ -23,7 +23,7 @@ const initialUIState: UIState = {
openGenerateAccordionItems: [], openGenerateAccordionItems: [],
openUnifiedCanvasAccordionItems: [], openUnifiedCanvasAccordionItems: [],
floatingProgressImageCoordinates: { x: 0, y: 0 }, floatingProgressImageCoordinates: { x: 0, y: 0 },
shouldShowProgressImage: false, shouldShowProgressImages: false,
}; };
const initialState: UIState = initialUIState; const initialState: UIState = initialUIState;
@ -114,8 +114,8 @@ export const uiSlice = createSlice({
state.floatingProgressImageCoordinates = { x: x + _x, y: y + _y }; state.floatingProgressImageCoordinates = { x: x + _x, y: y + _y };
}, },
shouldShowProgressImageChanged: (state, action: PayloadAction<boolean>) => { shouldShowProgressImagesToggled: (state) => {
state.shouldShowProgressImage = action.payload; state.shouldShowProgressImages = !state.shouldShowProgressImages;
}, },
}, },
}); });
@ -141,7 +141,7 @@ export const {
toggleGalleryPanel, toggleGalleryPanel,
openAccordionItemsChanged, openAccordionItemsChanged,
floatingProgressImageMoved, floatingProgressImageMoved,
shouldShowProgressImageChanged, shouldShowProgressImagesToggled,
} = uiSlice.actions; } = uiSlice.actions;
export default uiSlice.reducer; export default uiSlice.reducer;

View File

@ -20,5 +20,5 @@ export interface UIState {
openGenerateAccordionItems: number[]; openGenerateAccordionItems: number[];
openUnifiedCanvasAccordionItems: number[]; openUnifiedCanvasAccordionItems: number[];
floatingProgressImageCoordinates: Coordinates; floatingProgressImageCoordinates: Coordinates;
shouldShowProgressImage: boolean; shouldShowProgressImages: boolean;
} }