import React, { FC, useCallback, useEffect, useMemo, 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 pagination = { type: 'fraction' as const }; const NodeImageSwiperBlock: FC = observer(({ node }) => { const [controlledSwiper, setControlledSwiper] = useState(undefined); const showPhotoSwiper = useImageModal(); const { isOpened: isModalActive } = useModal(); const images = useNodeImages(node); const keyboard = useMemo( () => ({ enabled: !isModalActive, onlyInViewport: true, }), [isModalActive] ); 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] ); 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={pagination} centeredSlides observeSlideChildren observeParents observer resizeObserver watchOverflow updateOnImagesReady keyboard={keyboard} grabCursor autoHeight zoom navigation > {images.map((file, i) => ( onOpenPhotoSwipe(i)} className={styles.image} color={normalizeBrightColor(file?.metadata?.dominant_color)} /> ))}
); }); export { NodeImageSwiperBlock };