94 lines
2.4 KiB
TypeScript

import { ReactElement, useEffect, useState } from 'react';
import { As, Box, BoxProps, Flex, StyleProps } from '@chakra-ui/react';
import { Image } from '@chakra-ui/react';
import { DataUrlAccess } from '@/utils/data-url-access';
import { Icon } from './Icon';
import { ObjectId } from '@/back-api';
export type CoversProps = BoxProps & {
data?: ObjectId[];
size?: StyleProps["width"];
iconEmpty?: As;
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 icon={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>
};