mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): tweak floating preview
This commit is contained in:
parent
d5e152b35e
commit
779671753d
@ -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>
|
||||||
|
@ -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 />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -20,5 +20,5 @@ export interface UIState {
|
|||||||
openGenerateAccordionItems: number[];
|
openGenerateAccordionItems: number[];
|
||||||
openUnifiedCanvasAccordionItems: number[];
|
openUnifiedCanvasAccordionItems: number[];
|
||||||
floatingProgressImageCoordinates: Coordinates;
|
floatingProgressImageCoordinates: Coordinates;
|
||||||
shouldShowProgressImage: boolean;
|
shouldShowProgressImages: boolean;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user