diff --git a/package-lock.json b/package-lock.json index a3b3a94..134dbb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "react-copy-to-clipboard": "^5.0.4", "react-dom": "^17.0.2", "react-icons": "^4.3.1", + "react-image-lightbox": "^5.1.4", "react-loader-spinner": "^4.0.0", "react-loading-skeleton": "^3.0.2", "react-multi-carousel": "^2.6.5", @@ -17859,6 +17860,11 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -52647,6 +52653,19 @@ "react": "*" } }, + "node_modules/react-image-lightbox": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/react-image-lightbox/-/react-image-lightbox-5.1.4.tgz", + "integrity": "sha512-kTiAODz091bgT7SlWNHab0LSMZAPJtlNWDGKv7pLlLY1krmf7FuG1zxE0wyPpeA8gPdwfr3cu6sPwZRqWsc3Eg==", + "dependencies": { + "prop-types": "^15.7.2", + "react-modal": "^3.11.1" + }, + "peerDependencies": { + "react": "16.x || 17.x", + "react-dom": "16.x || 17.x" + } + }, "node_modules/react-inspector": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz", @@ -52668,8 +52687,7 @@ }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "dev": true + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "node_modules/react-loader-spinner": { "version": "4.0.0", @@ -52691,6 +52709,24 @@ "react": ">=16.8.0" } }, + "node_modules/react-modal": { + "version": "3.14.4", + "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.14.4.tgz", + "integrity": "sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==", + "dependencies": { + "exenv": "^1.2.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.0", + "warning": "^4.0.3" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16 || ^17", + "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17" + } + }, "node_modules/react-multi-carousel": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/react-multi-carousel/-/react-multi-carousel-2.6.5.tgz", @@ -59042,7 +59078,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, "dependencies": { "loose-envify": "^1.0.0" } @@ -74466,6 +74501,11 @@ "strip-final-newline": "^2.0.0" } }, + "exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -101219,6 +101259,15 @@ "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==", "requires": {} }, + "react-image-lightbox": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/react-image-lightbox/-/react-image-lightbox-5.1.4.tgz", + "integrity": "sha512-kTiAODz091bgT7SlWNHab0LSMZAPJtlNWDGKv7pLlLY1krmf7FuG1zxE0wyPpeA8gPdwfr3cu6sPwZRqWsc3Eg==", + "requires": { + "prop-types": "^15.7.2", + "react-modal": "^3.11.1" + } + }, "react-inspector": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz", @@ -101237,8 +101286,7 @@ }, "react-lifecycles-compat": { "version": "3.0.4", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "dev": true + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-loader-spinner": { "version": "4.0.0", @@ -101254,6 +101302,17 @@ "integrity": "sha512-rlALwuZEcjazUDeIy3+fEhm20Uk9Yd/zZGeITU034K2ts5/yEf7RuZaV2FyrPWypIII4LAsFEo9WDTPKp6G0fQ==", "requires": {} }, + "react-modal": { + "version": "3.14.4", + "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.14.4.tgz", + "integrity": "sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==", + "requires": { + "exenv": "^1.2.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.0", + "warning": "^4.0.3" + } + }, "react-multi-carousel": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/react-multi-carousel/-/react-multi-carousel-2.6.5.tgz", @@ -106183,7 +106242,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, "requires": { "loose-envify": "^1.0.0" } diff --git a/package.json b/package.json index 8fccc5d..e24b1a6 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "react-copy-to-clipboard": "^5.0.4", "react-dom": "^17.0.2", "react-icons": "^4.3.1", + "react-image-lightbox": "^5.1.4", "react-loader-spinner": "^4.0.0", "react-loading-skeleton": "^3.0.2", "react-multi-carousel": "^2.6.5", diff --git a/src/Components/Lightbox/Lightbox.tsx b/src/Components/Lightbox/Lightbox.tsx new file mode 100644 index 0000000..1af2573 --- /dev/null +++ b/src/Components/Lightbox/Lightbox.tsx @@ -0,0 +1,52 @@ + +import { useEffect, useState } from 'react'; +import LightboxComponent from 'react-image-lightbox'; +import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app +import './styles.css' + + +interface Props { + images: string[]; + isOpen?: boolean; + onClose?: () => void; + initOpenIndex?: number; +} + +export default function Lightbox(props: Props) { + + const [photoIndex, setPhotoIndex] = useState(0); + const [isOpen, setIsOpen] = useState(false); + + useEffect(() => { + if (props.isOpen) { + setIsOpen(true); + setPhotoIndex(props.initOpenIndex ?? 0) + } else + setIsOpen(false); + + }, [props.initOpenIndex, props.isOpen]) + + + + return ( + <> + {isOpen &&
+ props.onClose?.()} + onMovePrevRequest={() => + setPhotoIndex((photoIndex + props.images.length - 1) % props.images.length + ) + } + onMoveNextRequest={() => + setPhotoIndex((photoIndex + 1) % props.images.length) + } + imagePadding={48} + /> +
} + + ) +} diff --git a/src/Components/Lightbox/styles.css b/src/Components/Lightbox/styles.css new file mode 100644 index 0000000..f0277f8 --- /dev/null +++ b/src/Components/Lightbox/styles.css @@ -0,0 +1,3 @@ +.ReactModal__Overlay { + z-index: 10000 !important; +} diff --git a/src/pages/ProjectPage/ProjectDetailsCard/ProjectDetailsCard.tsx b/src/pages/ProjectPage/ProjectDetailsCard/ProjectDetailsCard.tsx index 0328e1d..303989b 100644 --- a/src/pages/ProjectPage/ProjectDetailsCard/ProjectDetailsCard.tsx +++ b/src/pages/ProjectPage/ProjectDetailsCard/ProjectDetailsCard.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react' import { BsJoystick } from 'react-icons/bs' import { MdClose, MdLocalFireDepartment } from 'react-icons/md'; import { ModalCard } from 'src/Components/Modals/ModalsContainer/ModalsContainer'; @@ -10,6 +11,7 @@ import ProjectCardSkeleton from './ProjectDetailsCard.Skeleton' import VoteButton from 'src/pages/ProjectPage/VoteButton/VoteButton'; import { Wallet_Service } from 'src/services' import { useProjectDetailsQuery } from 'src/graphql'; +import Lightbox from 'src/Components/Lightbox/Lightbox' interface Props extends ModalCard { @@ -19,6 +21,8 @@ interface Props extends ModalCard { export default function ProjectDetailsCard({ onClose, direction, projectId, ...props }: Props) { const dispatch = useAppDispatch(); + const [screenshotsOpen, setScreenshotsOpen] = useState(-1); + @@ -113,14 +117,26 @@ export default function ProjectDetailsCard({ onClose, direction, projectId, ...p } - {project.screenshots.length > 0 &&
-

Screenshots

-
- {project.screenshots.map((screenshot, idx) =>
- -
)} + {project.screenshots.length > 0 && <> +
+

Screenshots

+
+ {project.screenshots.map((screenshot, idx) =>
setScreenshotsOpen(idx)} + > + +
)} +
-
} + setScreenshotsOpen(-1)} + /> + }

Are you the creator of this project?