diff --git a/package.json b/package.json index ca720cff..133af634 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "mobx-persist-store": "^1.0.4", "mobx-react-lite": "^3.2.3", "next": "^12.3.0", - "photoswipe": "^5.4.4", + "photoswipe": "^4.1.3", "raleway-cyrillic": "^4.0.2", "ramda": "^0.26.1", "react": "^17.0.2", @@ -41,7 +41,7 @@ "react-sticky-box": "^1.0.2", "sass": "^1.49.0", "sharp": "^0.32.6", - "swiper": "^11.2.2", + "swiper": "^11.0.3", "swr": "^1.0.1", "throttle-debounce": "^2.1.0", "typescript": "^4.0.5", diff --git a/src/components/common/Columns/index.tsx b/src/components/common/Columns/index.tsx index e491e77c..6901c609 100644 --- a/src/components/common/Columns/index.tsx +++ b/src/components/common/Columns/index.tsx @@ -31,7 +31,7 @@ const Columns: FC = ({ if (!childs) return; - const timeout = setTimeout(() => setColumns([...childs.values()]), 150); + const timeout = setTimeout(() => setColumns([...childs]), 150); return () => clearTimeout(timeout); // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/components/node/NodeImageSwiperBlock/index.tsx b/src/components/node/NodeImageSwiperBlock/index.tsx index c3c778d3..9e5d8082 100644 --- a/src/components/node/NodeImageSwiperBlock/index.tsx +++ b/src/components/node/NodeImageSwiperBlock/index.tsx @@ -57,9 +57,7 @@ const NodeImageSwiperBlock: FC = observer(({ node }) => { useEffect(() => { controlledSwiper?.slideTo(0, 0); - return () => { - controlledSwiper?.slideTo(0, 0); - }; + return () => controlledSwiper?.slideTo(0, 0); }, [controlledSwiper, images, node.id]); useEffect(() => { diff --git a/src/containers/dialogs/PhotoSwipe/index.tsx b/src/containers/dialogs/PhotoSwipe/index.tsx index b5baccb7..3a285696 100644 --- a/src/containers/dialogs/PhotoSwipe/index.tsx +++ b/src/containers/dialogs/PhotoSwipe/index.tsx @@ -1,12 +1,10 @@ -import { useEffect } from 'react'; - -import 'photoswipe/style.css'; +import { useEffect, useRef, VFC } from 'react'; +import classNames from 'classnames'; import { observer } from 'mobx-react-lite'; -import { SlideData } from 'photoswipe/dist/types/slide/slide'; -import { renderToStaticMarkup } from 'react-dom/server'; +import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default.js'; +import PhotoSwipeJs from 'photoswipe/dist/photoswipe.js'; -import { Icon } from '~/components/common/Icon'; import { imagePresets } from '~/constants/urls'; import { useWindowSize } from '~/hooks/dom/useWindowSize'; import { useModal } from '~/hooks/modal/useModal'; @@ -15,83 +13,125 @@ import { DialogComponentProps } from '~/types/modal'; import { getURL } from '~/utils/dom'; import styles from './styles.module.scss'; -export interface Props extends DialogComponentProps { + +export interface PhotoSwipeProps extends DialogComponentProps { items: IFile[]; index: number; } -const arrowNextSVG = renderToStaticMarkup(); -const arrowPrevSVG = renderToStaticMarkup(); -const closeSVG = renderToStaticMarkup(); - -const padding = { top: 10, left: 10, right: 10, bottom: 10 } as const; - -const PhotoSwipe = observer(({ index, items }: Props) => { +const PhotoSwipe: VFC = observer(({ index, items }) => { + let ref = useRef(null); const { hideModal } = useModal(); const { isTablet } = useWindowSize(); useEffect(() => { - Promise.all( - items.map( - (file): Promise => - new Promise((resolve) => { - const src = getURL( - file, - isTablet ? imagePresets[900] : imagePresets[1600], - ); + new Promise(async (resolve) => { + const images = await Promise.all( + items.map( + (file) => + new Promise((resolve) => { + const src = getURL( + file, + isTablet ? imagePresets[900] : imagePresets[1600], + ); - if (file.metadata?.width && file.metadata.height) { - resolve({ - src, - width: file.metadata.width, - height: file.metadata.height, - }); + if (file.metadata?.width && file.metadata.height) { + resolve({ + src, + w: file.metadata.width, + h: file.metadata.height, + }); - return; - } + return; + } - const img = new Image(); + const img = new Image(); - img.onload = () => { - resolve({ - src, - height: img.naturalHeight, - width: img.naturalWidth, - }); - }; + img.onload = () => { + resolve({ + src, + h: img.naturalHeight, + w: img.naturalWidth, + }); + }; - img.onerror = () => { - resolve({}); - }; + img.onerror = () => { + resolve({}); + }; - img.src = getURL(file, imagePresets[1600]); - }), - ), - ).then(async (images: SlideData[]) => { - const PSWP = await import('photoswipe').then((it) => it.default); + img.src = getURL(file, imagePresets[1600]); + }), + ), + ); - const ps = new PSWP({ - dataSource: images, + resolve(images); + }).then((images) => { + const ps = new PhotoSwipeJs(ref.current, PhotoSwipeUI_Default, images, { index: index || 0, - closeOnVerticalDrag: true, - padding, - mainClass: styles.wrap, - zoom: false, - counter: false, - bgOpacity: 0.1, - arrowNextSVG, - arrowPrevSVG, - closeSVG, + closeOnScroll: false, + history: false, }); - ps.on('destroy', hideModal); - ps.on('close', hideModal); - ps.init(); + ps.listen('destroy', hideModal); + ps.listen('close', hideModal); }); }, [hideModal, items, index, isTablet]); - return null; + return ( +