import React, { FC, useCallback, useEffect, useState } from 'react'; import { observer } from 'mobx-react-lite'; import SwiperCore, { Keyboard, Navigation, Pagination, SwiperOptions } from 'swiper'; import { Swiper, SwiperSlide } from 'swiper/react'; import SwiperClass from 'swiper/types/swiper-class'; import { ImagePreloader } from '~/components/media/ImagePreloader'; import { INodeComponentProps } from '~/constants/node'; import { useModal } from '~/hooks/modal/useModal'; import { useImageModal } from '~/hooks/navigation/useImageModal'; import { useNodeImages } from '~/hooks/node/useNodeImages'; import { normalizeBrightColor } from '~/utils/color'; import styles from './styles.module.scss'; SwiperCore.use([Navigation, Pagination, Keyboard]); interface IProps extends INodeComponentProps {} const breakpoints: SwiperOptions['breakpoints'] = { 599: { spaceBetween: 20, }, }; const NodeImageSwiperBlock: FC = observer(({ node }) => { const [controlledSwiper, setControlledSwiper] = useState(undefined); const showPhotoSwiper = useImageModal(); const { isOpened: isModalActive } = useModal(); const images = useNodeImages(node); const updateSwiper = useCallback(() => { if (!controlledSwiper) return; controlledSwiper.updateSlides(); controlledSwiper.updateSize(); controlledSwiper.update(); controlledSwiper.updateAutoHeight(); controlledSwiper.updateProgress(); }, [controlledSwiper]); const onOpenPhotoSwipe = useCallback( (index: number) => { if (index !== controlledSwiper?.activeIndex && controlledSwiper?.slideTo) { controlledSwiper.slideTo(index, 300); return; } showPhotoSwiper(images, index); }, [images, controlledSwiper, showPhotoSwiper] ); // TODO: remove it if swiper 8 fixed sliding to first slide on init // useEffect(() => { // controlledSwiper?.slideTo(0, 0); // return () => controlledSwiper?.slideTo(0, 0); // }, [images, node?.id]); useEffect(() => { if (isModalActive) { controlledSwiper?.keyboard.disable(); } else { controlledSwiper?.keyboard.enable(); } }, [isModalActive]); if (!images?.length) { return null; } if (images.length === 1) { return (
onOpenPhotoSwipe(0)} className={styles.image} />
); } return (
1} initialSlide={0} slidesPerView="auto" onSwiper={setControlledSwiper} breakpoints={breakpoints} pagination={{ type: 'fraction' }} centeredSlides observeSlideChildren observeParents observer resizeObserver watchOverflow updateOnImagesReady keyboard={{ enabled: !isModalActive, onlyInViewport: true, }} grabCursor autoHeight zoom navigation > {images.map((file, i) => ( onOpenPhotoSwipe(i)} className={styles.image} color={normalizeBrightColor(file?.metadata?.dominant_color)} /> ))}
); }); export { NodeImageSwiperBlock };