113 lines
2.6 KiB
TypeScript

import { ReactElement, useEffect, useState } from 'react';
import { Box, BoxProps, Flex, FlexProps } from '@chakra-ui/react';
import { Image } from '@chakra-ui/react';
import { ObjectId } from '@/back-api';
import { DataUrlAccess } from '@/utils/data-url-access';
import { Icon } from './Icon';
export type CoversProps = Omit<BoxProps, 'iconEmpty'> & {
data?: ObjectId[];
size?: BoxProps['width'];
iconEmpty?: ReactElement;
slideshow?: boolean;
};
export const Covers = ({
data,
iconEmpty,
size = '100px',
slideshow = false,
...rest
}: CoversProps) => {
const [currentImageIndex, setCurrentImageIndex] = useState(0);
const [previousImageIndex, setPreviousImageIndex] = useState(0);
const [topOpacity, setTopOpacity] = useState(0.0);
useEffect(() => {
if (!slideshow) {
return;
}
const interval = setInterval(() => {
setPreviousImageIndex(currentImageIndex);
setTopOpacity(0.0);
setTimeout(() => {
setCurrentImageIndex(
(prevIndex) => (prevIndex + 1) % (data?.length ?? 1)
);
setTopOpacity(1.0);
}, 1500);
}, 3000);
return () => clearInterval(interval);
}, [slideshow, data]);
if (!data || data.length < 1) {
if (iconEmpty) {
return <Icon children={iconEmpty} sizeIcon={size} />;
} else {
return (
<Box
width={size}
height={size}
minHeight={size}
minWidth={size}
borderColor="blue"
borderWidth="1px"
margin="auto"
{...rest}
></Box>
);
}
}
if (slideshow === false || data.length === 1) {
const url = DataUrlAccess.getThumbnailUrl(data[0]);
return (
<Image
loading="lazy"
src={url}
maxWidth={size}
boxSize={size} /*{...rest}*/
/>
);
}
const urlCurrent = DataUrlAccess.getThumbnailUrl(data[currentImageIndex]);
const urlPrevious = DataUrlAccess.getThumbnailUrl(data[previousImageIndex]);
return (
<Flex
position="relative"
// {...rest}
maxWidth={size}
width={size}
height={size}
overflow="hidden"
>
<Image
src={urlPrevious}
loading="lazy"
position="absolute"
top="0"
left="0"
width="100%"
height="100%"
zIndex={1}
boxSize={size}
/>
<Image
src={urlCurrent}
loading="lazy"
position="absolute"
top="0"
left="0"
width="100%"
height="100%"
boxSize={size}
transition="opacity 0.5s ease-in-out"
opacity={topOpacity}
zIndex={2}
/>
</Flex>
);
};