feat(ui): remove shouldShowDeleteButton

- remove this state entirely
- use `state.hotkeys.shift` directly to hide and show the icon on gallery
- also formatting
This commit is contained in:
psychedelicious 2023-08-16 11:50:57 +10:00
parent 5b1099193d
commit 0f8606914e
8 changed files with 51 additions and 70 deletions

View File

@ -1,4 +1,11 @@
import { ChakraProps, Flex, Icon, Image, useColorMode } from '@chakra-ui/react';
import {
ChakraProps,
Flex,
FlexProps,
Icon,
Image,
useColorMode,
} from '@chakra-ui/react';
import {
IAILoadingImageFallback,
IAINoContentFallback,
@ -25,7 +32,7 @@ import {
TypesafeDroppableData,
} from 'features/dnd/types';
type IAIDndImageProps = {
type IAIDndImageProps = FlexProps & {
imageDTO: ImageDTO | undefined;
onError?: (event: SyntheticEvent<HTMLImageElement>) => void;
onLoad?: (event: SyntheticEvent<HTMLImageElement>) => void;
@ -47,8 +54,6 @@ type IAIDndImageProps = {
useThumbailFallback?: boolean;
withHoverOverlay?: boolean;
children?: JSX.Element;
onMouseOver?: () => void;
onMouseOut?: () => void;
};
const IAIDndImage = (props: IAIDndImageProps) => {
@ -79,14 +84,20 @@ const IAIDndImage = (props: IAIDndImageProps) => {
const { colorMode } = useColorMode();
const [isHovered, setIsHovered] = useState(false);
const handleMouseOver = useCallback(() => {
if (onMouseOver) onMouseOver();
setIsHovered(true);
}, [onMouseOver]);
const handleMouseOut = useCallback(() => {
if (onMouseOut) onMouseOut();
setIsHovered(false);
}, [onMouseOut]);
const handleMouseOver = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
if (onMouseOver) onMouseOver(e);
setIsHovered(true);
},
[onMouseOver]
);
const handleMouseOut = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
if (onMouseOut) onMouseOut(e);
setIsHovered(false);
},
[onMouseOut]
);
const { getUploadButtonProps, getUploadInputProps } = useImageUploadButton({
postUploadAction,

View File

@ -1,6 +1,6 @@
import { JSXElementConstructor, ReactElement, memo, MouseEvent } from 'react';
import IAIIconButton from './IAIIconButton';
import { SystemStyleObject, useColorModeValue } from '@chakra-ui/react';
import { JSXElementConstructor, MouseEvent, ReactElement, memo } from 'react';
import IAIIconButton from './IAIIconButton';
type Props = {
onClick: (event: MouseEvent<HTMLButtonElement>) => void;

View File

@ -1,10 +1,4 @@
import {
Box,
Flex,
Spinner,
SystemStyleObject,
useColorModeValue,
} from '@chakra-ui/react';
import { Box, Flex, Spinner, SystemStyleObject } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { skipToken } from '@reduxjs/toolkit/dist/query';
import {
@ -16,14 +10,14 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIDndImage from 'common/components/IAIDndImage';
import { memo, useCallback, useMemo, useState } from 'react';
import { FaUndo } from 'react-icons/fa';
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
import { PostUploadAction } from 'services/api/types';
import IAIDndImageIcon from '../../../common/components/IAIDndImageIcon';
import {
ControlNetConfig,
controlNetImageChanged,
} from '../store/controlNetSlice';
import { FaUndo } from 'react-icons/fa';
import IAIDndImageIcon from '../../../common/components/IAIDndImageIcon';
type Props = {
controlNet: ControlNetConfig;
@ -101,11 +95,6 @@ const ControlNetImagePreview = (props: Props) => {
[controlNetId]
);
const resetIconShadow = useColorModeValue(
`drop-shadow(0px 0px 0.1rem var(--invokeai-colors-base-600))`,
`drop-shadow(0px 0px 0.1rem var(--invokeai-colors-base-800))`
);
const shouldShowProcessedImage =
controlImage &&
processedControlImage &&

View File

@ -27,9 +27,7 @@ const GalleryImage = (props: HoverableImageProps) => {
const dispatch = useAppDispatch();
const { imageName } = props;
const { currentData: imageDTO } = useGetImageDTOQuery(imageName);
const shouldShowDeleteButton = useAppSelector(
(state) => state.gallery.shouldShowDeleteButton
);
const shift = useAppSelector((state) => state.hotkeys.shift);
const { handleClick, isSelected, selection, selectionCount } =
useMultiselect(imageDTO);
@ -81,6 +79,14 @@ const GalleryImage = (props: HoverableImageProps) => {
const [isHovered, setIsHovered] = useState(false);
const handleMouseOver = useCallback(() => {
setIsHovered(true);
}, []);
const handleMouseOut = useCallback(() => {
setIsHovered(false);
}, []);
const starIcon = useMemo(() => {
if (imageDTO?.starred) return <MdStar size="20" />;
if (!imageDTO?.starred && isHovered) return <MdStarBorder size="20" />;
@ -112,8 +118,8 @@ const GalleryImage = (props: HoverableImageProps) => {
isUploadDisabled={true}
thumbnail={true}
withHoverOverlay
onMouseOver={() => setIsHovered(true)}
onMouseOut={() => setIsHovered(false)}
onMouseOver={handleMouseOver}
onMouseOut={handleMouseOut}
>
<>
<IAIDndImageIcon
@ -122,13 +128,13 @@ const GalleryImage = (props: HoverableImageProps) => {
tooltip={imageDTO.starred ? 'Unstar' : 'Star'}
/>
{isHovered && shouldShowDeleteButton && (
{isHovered && shift && (
<IAIDndImageIcon
onClick={handleDelete}
icon={<FaTrash />}
tooltip={'Delete'}
tooltip="Delete"
styleOverrides={{
bottom: 1,
bottom: 2,
top: 'auto',
}}
/>

View File

@ -1,5 +1,5 @@
import { Box, Flex } from '@chakra-ui/react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import { selectListImagesBaseQueryArgs } from 'features/gallery/store/gallerySelectors';
@ -20,8 +20,6 @@ import { useBoardTotal } from 'services/api/hooks/useBoardTotal';
import GalleryImage from './GalleryImage';
import ImageGridItemContainer from './ImageGridItemContainer';
import ImageGridListContainer from './ImageGridListContainer';
import { useHotkeys } from 'react-hotkeys-hook';
import { shouldShowDeleteButtonChanged } from '../../store/gallerySlice';
const overlayScrollbarsConfig: UseOverlayScrollbarsParams = {
defer: true,
@ -38,7 +36,6 @@ const overlayScrollbarsConfig: UseOverlayScrollbarsParams = {
const GalleryImageGrid = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const rootRef = useRef<HTMLDivElement>(null);
const [scroller, setScroller] = useState<HTMLElement | null>(null);
const [initialize, osInstance] = useOverlayScrollbars(
@ -88,23 +85,6 @@ const GalleryImageGrid = () => {
return () => osInstance()?.destroy();
}, [scroller, initialize, osInstance]);
useHotkeys(
'shift',
() => {
dispatch(shouldShowDeleteButtonChanged(true));
},
[shouldShowDeleteButtonChanged]
);
useHotkeys(
'shift',
() => {
dispatch(shouldShowDeleteButtonChanged(false));
},
{ keyup: true },
[shouldShowDeleteButtonChanged]
);
if (!currentData) {
return (
<Flex

View File

@ -13,7 +13,6 @@ export const initialGalleryState: GalleryState = {
galleryImageMinimumWidth: 96,
selectedBoardId: 'none',
galleryView: 'images',
shouldShowDeleteButton: false,
boardSearchText: '',
};
@ -50,9 +49,6 @@ export const gallerySlice = createSlice({
galleryViewChanged: (state, action: PayloadAction<GalleryView>) => {
state.galleryView = action.payload;
},
shouldShowDeleteButtonChanged: (state, action: PayloadAction<boolean>) => {
state.shouldShowDeleteButton = action.payload;
},
boardSearchTextChanged: (state, action: PayloadAction<string>) => {
state.boardSearchText = action.payload;
},
@ -93,7 +89,6 @@ export const {
autoAddBoardIdChanged,
galleryViewChanged,
selectionChanged,
shouldShowDeleteButtonChanged,
boardSearchTextChanged,
} = gallerySlice.actions;

View File

@ -21,6 +21,5 @@ export type GalleryState = {
galleryImageMinimumWidth: number;
selectedBoardId: BoardId;
galleryView: GalleryView;
shouldShowDeleteButton: boolean;
boardSearchText: string;
};

View File

@ -26,26 +26,27 @@ export const getIsImageInDateRange = (
for (let index = 0; index < totalCachedImageDtos.length; index++) {
const image = totalCachedImageDtos[index];
if (image?.starred) cachedStarredImages.push(image)
if (!image?.starred) cachedUnstarredImages.push(image)
if (image?.starred) cachedStarredImages.push(image);
if (!image?.starred) cachedUnstarredImages.push(image);
}
if (imageDTO.starred) {
const lastStarredImage = cachedStarredImages[cachedStarredImages.length - 1];
// if starring or already starred, want to look in list of starred images
const lastStarredImage =
cachedStarredImages[cachedStarredImages.length - 1];
// if starring or already starred, want to look in list of starred images
if (!lastStarredImage) return true; // no starred images showing, so always show this one
const createdDate = new Date(imageDTO.created_at);
const oldestDate = new Date(lastStarredImage.created_at);
return createdDate >= oldestDate;
} else {
const lastUnstarredImage = cachedUnstarredImages[cachedUnstarredImages.length - 1];
const lastUnstarredImage =
cachedUnstarredImages[cachedUnstarredImages.length - 1];
// if unstarring or already unstarred, want to look in list of unstarred images
if (!lastUnstarredImage) return false; // no unstarred images showing, so don't show this one
const createdDate = new Date(imageDTO.created_at);
const oldestDate = new Date(lastUnstarredImage.created_at);
return createdDate >= oldestDate;
}
};
export const getCategories = (imageDTO: ImageDTO) => {
@ -67,7 +68,7 @@ export const imagesAdapter = createEntityAdapter<ImageDTO>({
if (!a.starred && b.starred) {
return 1;
}
return dateComparator(b.created_at, a.created_at)
return dateComparator(b.created_at, a.created_at);
},
});