diff --git a/package.json b/package.json index 133af634..ca720cff 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": "^4.1.3", + "photoswipe": "^5.4.4", "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.0.3", + "swiper": "^11.2.2", "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 6901c609..e491e77c 100644 --- a/src/components/common/Columns/index.tsx +++ b/src/components/common/Columns/index.tsx @@ -31,7 +31,7 @@ const Columns: FC<ColumnsProps> = ({ if (!childs) return; - const timeout = setTimeout(() => setColumns([...childs]), 150); + const timeout = setTimeout(() => setColumns([...childs.values()]), 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 9e5d8082..c3c778d3 100644 --- a/src/components/node/NodeImageSwiperBlock/index.tsx +++ b/src/components/node/NodeImageSwiperBlock/index.tsx @@ -57,7 +57,9 @@ const NodeImageSwiperBlock: FC<Props> = 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 3a285696..b5baccb7 100644 --- a/src/containers/dialogs/PhotoSwipe/index.tsx +++ b/src/containers/dialogs/PhotoSwipe/index.tsx @@ -1,10 +1,12 @@ -import { useEffect, useRef, VFC } from 'react'; +import { useEffect } from 'react'; + +import 'photoswipe/style.css'; -import classNames from 'classnames'; import { observer } from 'mobx-react-lite'; -import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default.js'; -import PhotoSwipeJs from 'photoswipe/dist/photoswipe.js'; +import { SlideData } from 'photoswipe/dist/types/slide/slide'; +import { renderToStaticMarkup } from 'react-dom/server'; +import { Icon } from '~/components/common/Icon'; import { imagePresets } from '~/constants/urls'; import { useWindowSize } from '~/hooks/dom/useWindowSize'; import { useModal } from '~/hooks/modal/useModal'; @@ -13,125 +15,83 @@ import { DialogComponentProps } from '~/types/modal'; import { getURL } from '~/utils/dom'; import styles from './styles.module.scss'; - -export interface PhotoSwipeProps extends DialogComponentProps { +export interface Props extends DialogComponentProps { items: IFile[]; index: number; } -const PhotoSwipe: VFC<PhotoSwipeProps> = observer(({ index, items }) => { - let ref = useRef<HTMLDivElement>(null); +const arrowNextSVG = renderToStaticMarkup(<Icon icon="right" size={40} />); +const arrowPrevSVG = renderToStaticMarkup(<Icon icon="left" size={40} />); +const closeSVG = renderToStaticMarkup(<Icon icon="close" size={32} />); + +const padding = { top: 10, left: 10, right: 10, bottom: 10 } as const; + +const PhotoSwipe = observer(({ index, items }: Props) => { const { hideModal } = useModal(); const { isTablet } = useWindowSize(); useEffect(() => { - new Promise(async (resolve) => { - const images = await Promise.all( - items.map( - (file) => - new Promise((resolve) => { - const src = getURL( - file, - isTablet ? imagePresets[900] : imagePresets[1600], - ); + Promise.all( + items.map( + (file): Promise<SlideData> => + new Promise((resolve) => { + const src = getURL( + file, + isTablet ? imagePresets[900] : imagePresets[1600], + ); - if (file.metadata?.width && file.metadata.height) { - resolve({ - src, - w: file.metadata.width, - h: file.metadata.height, - }); + if (file.metadata?.width && file.metadata.height) { + resolve({ + src, + width: file.metadata.width, + height: file.metadata.height, + }); - return; - } + return; + } - const img = new Image(); + const img = new Image(); - img.onload = () => { - resolve({ - src, - h: img.naturalHeight, - w: img.naturalWidth, - }); - }; + img.onload = () => { + resolve({ + src, + height: img.naturalHeight, + width: img.naturalWidth, + }); + }; - img.onerror = () => { - resolve({}); - }; + img.onerror = () => { + resolve({}); + }; - img.src = getURL(file, imagePresets[1600]); - }), - ), - ); + img.src = getURL(file, imagePresets[1600]); + }), + ), + ).then(async (images: SlideData[]) => { + const PSWP = await import('photoswipe').then((it) => it.default); - resolve(images); - }).then((images) => { - const ps = new PhotoSwipeJs(ref.current, PhotoSwipeUI_Default, images, { + const ps = new PSWP({ + dataSource: images, index: index || 0, - closeOnScroll: false, - history: false, + closeOnVerticalDrag: true, + padding, + mainClass: styles.wrap, + zoom: false, + counter: false, + bgOpacity: 0.1, + arrowNextSVG, + arrowPrevSVG, + closeSVG, }); + ps.on('destroy', hideModal); + ps.on('close', hideModal); + ps.init(); - ps.listen('destroy', hideModal); - ps.listen('close', hideModal); }); }, [hideModal, items, index, isTablet]); - return ( - <div - className="pswp" - tabIndex={-1} - role="dialog" - aria-hidden="true" - ref={ref} - > - <div className={classNames('pswp__bg', styles.bg)} /> - <div className={classNames('pswp__scroll-wrap', styles.wrap)}> - <div className="pswp__container"> - <div className="pswp__item" /> - <div className="pswp__item" /> - <div className="pswp__item" /> - </div> - - <div className="pswp__ui pswp__ui--hidden"> - <div className={classNames('pswp__top-bar', styles.bar)}> - <div className="pswp__counter" /> - <button - className="pswp__button pswp__button--close" - title="Close (Esc)" - /> - - <div className="pswp__preloader"> - <div className="pswp__preloader__icn"> - <div className="pswp__preloader__cut"> - <div className="pswp__preloader__donut" /> - </div> - </div> - </div> - </div> - - <div className="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"> - <div className="pswp__share-tooltip" /> - </div> - - <button - className="pswp__button pswp__button--arrow--left" - title="Previous (arrow left)" - /> - - <button - className="pswp__button pswp__button--arrow--right" - title="Next (arrow right)" - /> - - <div className="pswp__caption"> - <div className="pswp__caption__center" /> - </div> - </div> - </div> - </div> - ); + return null; }); export { PhotoSwipe }; diff --git a/src/containers/dialogs/PhotoSwipe/styles.module.scss b/src/containers/dialogs/PhotoSwipe/styles.module.scss index 8a6d6c8b..e66eeb25 100644 --- a/src/containers/dialogs/PhotoSwipe/styles.module.scss +++ b/src/containers/dialogs/PhotoSwipe/styles.module.scss @@ -1,4 +1,4 @@ -@import "src/styles/variables"; +@import 'src/styles/variables'; .wrap { :global(.pswp__img) { diff --git a/src/styles/_global.scss b/src/styles/_global.scss index ab87de67..33f1f85a 100644 --- a/src/styles/_global.scss +++ b/src/styles/_global.scss @@ -2,8 +2,6 @@ @use './themes/horizon' as theme_horizon; @import 'src/styles/variables'; -@import 'photoswipe/dist/photoswipe'; -@import 'photoswipe/dist/default-skin/default-skin'; @import 'swiper/css'; @import 'swiper/css/effect-fade'; diff --git a/yarn.lock b/yarn.lock index 7a7ea181..51753816 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2423,10 +2423,10 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -photoswipe@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/photoswipe/-/photoswipe-4.1.3.tgz#59f49494eeb9ddab5888d03392926a19bc197550" - integrity sha512-89Z43IRUyw7ycTolo+AaiDn3W1EEIfox54hERmm9bI12IB9cvRfHSHez3XhAyU8XW2EAFrC+2sKMhh7SJwn0bA== +photoswipe@^5.4.4: + version "5.4.4" + resolved "https://registry.yarnpkg.com/photoswipe/-/photoswipe-5.4.4.tgz#e045dc036453493188d5c8665b0e8f1000ac4d6e" + integrity sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA== picocolors@^1.0.0: version "1.0.0" @@ -3102,10 +3102,10 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -swiper@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/swiper/-/swiper-11.0.3.tgz#9c325154db2a4431f508b7e8e300621365eb4c3d" - integrity sha512-MyV9ooQsriAe2EibeamqewLjgCfSvl2xoyratl6S3ln5BXDL4BzlO6mxcbLMCzQL6Z60b/u0AS/nKrepL0+TAg== +swiper@^11.2.2: + version "11.2.2" + resolved "https://registry.yarnpkg.com/swiper/-/swiper-11.2.2.tgz#b49089fad99501e34cb1be916e1ae05379aace9a" + integrity sha512-FmAN6zACpVUbd/1prO9xQ9gKo9cc6RE2UKU/z4oXtS8fNyX4sdOW/HHT/e444WucLJs0jeMId6WjdWM2Lrs8zA== swr@^1.0.1: version "1.2.0"