From 606700f5d2b9692b530ba7068ba2f585153b179d Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Thu, 13 Feb 2025 15:36:18 +0700 Subject: [PATCH] fix photoswipe --- src/constants/modal/index.ts | 9 ++- src/containers/dialogs/Modal/index.tsx | 13 ++-- src/containers/dialogs/PhotoSwipe/index.tsx | 85 +++++++-------------- 3 files changed, 44 insertions(+), 63 deletions(-) diff --git a/src/constants/modal/index.ts b/src/constants/modal/index.ts index 820f9962..f72114fd 100644 --- a/src/constants/modal/index.ts +++ b/src/constants/modal/index.ts @@ -1,3 +1,5 @@ +import { lazy } from 'react'; + import { LoginDialog } from '~/containers/auth/LoginDialog'; import { LoginSocialRegisterDialog } from '~/containers/auth/LoginSocialRegisterDialog'; import { RestorePasswordDialog } from '~/containers/auth/RestorePasswordDialog'; @@ -6,9 +8,14 @@ import { TelegramAttachDialog } from '~/containers/auth/TelegramAttachDialog'; import { EditorCreateDialog } from '~/containers/dialogs/EditorCreateDialog'; import { EditorEditDialog } from '~/containers/dialogs/EditorEditDialog'; import { LoadingDialog } from '~/containers/dialogs/LoadingDialog'; -import { PhotoSwipe } from '~/containers/dialogs/PhotoSwipe'; import { TestDialog } from '~/containers/dialogs/TestDialog'; +const PhotoSwipe = lazy(() => + import('~/containers/dialogs/PhotoSwipe').then((it) => ({ + default: it.PhotoSwipe, + })), +); + export enum Dialog { Login = 'Login', Register = 'Register', diff --git a/src/containers/dialogs/Modal/index.tsx b/src/containers/dialogs/Modal/index.tsx index 7bda9a70..090a7a6a 100644 --- a/src/containers/dialogs/Modal/index.tsx +++ b/src/containers/dialogs/Modal/index.tsx @@ -1,7 +1,8 @@ -import { FC, createElement } from 'react'; +import { FC, createElement, Suspense } from 'react'; import { observer } from 'mobx-react-lite'; +import { LoaderCircle } from '~/components/common/LoaderCircle'; import { ModalWrapper } from '~/components/common/ModalWrapper'; import { DIALOG_CONTENT } from '~/constants/modal'; import { useModalStore } from '~/store/modal/useModalStore'; @@ -18,10 +19,12 @@ const Modal: FC = observer(() => { return ( - {createElement(DIALOG_CONTENT[current!]! as any, { - onRequestClose: hide, - ...props, - })} + }> + {createElement(DIALOG_CONTENT[current!]! as any, { + onRequestClose: hide, + ...props, + })} + ); }); diff --git a/src/containers/dialogs/PhotoSwipe/index.tsx b/src/containers/dialogs/PhotoSwipe/index.tsx index b5baccb7..f5d4098c 100644 --- a/src/containers/dialogs/PhotoSwipe/index.tsx +++ b/src/containers/dialogs/PhotoSwipe/index.tsx @@ -1,9 +1,9 @@ -import { useEffect } from 'react'; +import { useEffect, useRef } from 'react'; import 'photoswipe/style.css'; import { observer } from 'mobx-react-lite'; -import { SlideData } from 'photoswipe/dist/types/slide/slide'; +import PSWP from 'photoswipe'; import { renderToStaticMarkup } from 'react-dom/server'; import { Icon } from '~/components/common/Icon'; @@ -29,66 +29,37 @@ const padding = { top: 10, left: 10, right: 10, bottom: 10 } as const; const PhotoSwipe = observer(({ index, items }: Props) => { const { hideModal } = useModal(); const { isTablet } = useWindowSize(); + const pswp = useRef(new PSWP()); useEffect(() => { - Promise.all( - items.map( - (file): Promise => - new Promise((resolve) => { - const src = getURL( - file, - isTablet ? imagePresets[900] : imagePresets[1600], - ); + const dataSource = items.map((file) => ({ + src: getURL(file, imagePresets[1600]), + width: file.metadata?.width, + height: file.metadata?.height, + })); - if (file.metadata?.width && file.metadata.height) { - resolve({ - src, - width: file.metadata.width, - height: file.metadata.height, - }); + pswp.current.options = { + ...pswp.current.options, + dataSource, + index: index || 0, + closeOnVerticalDrag: true, + padding, + mainClass: styles.wrap, + zoom: false, + counter: false, + bgOpacity: 0.1, + arrowNextSVG, + arrowPrevSVG, + closeSVG, + }; - return; - } + pswp.current.on('closingAnimationEnd', hideModal); + pswp.current.init(); - const img = new Image(); - - img.onload = () => { - resolve({ - src, - height: img.naturalHeight, - width: img.naturalWidth, - }); - }; - - img.onerror = () => { - resolve({}); - }; - - img.src = getURL(file, imagePresets[1600]); - }), - ), - ).then(async (images: SlideData[]) => { - const PSWP = await import('photoswipe').then((it) => it.default); - - const ps = new PSWP({ - dataSource: images, - index: index || 0, - 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(); - }); + return () => { + pswp.current?.off('close', hideModal); + pswp.current?.destroy(); + }; }, [hideModal, items, index, isTablet]); return null;