diff --git a/package.json b/package.json index 8278fb30c..10d4748a9 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "axios": "^0.20.0", "bootstrap": "^4.5.2", "comlink": "^4.3.0", + "exif-js": "^2.3.0", "formik": "^2.1.5", "http-proxy-middleware": "^1.0.5", "libsodium-wrappers": "^0.7.8", @@ -21,6 +22,7 @@ "react": "16.13.1", "react-bootstrap": "^1.3.0", "react-dom": "16.13.1", + "react-dropzone": "^11.2.4", "react-photoswipe": "^1.3.0", "react-virtualized-auto-sizer": "^1.0.2", "react-window": "^1.8.6", @@ -42,7 +44,7 @@ "@types/yup": "^0.29.7", "babel-plugin-styled-components": "^1.11.1", "next-on-netlify": "^2.4.0", - "typescript": "^4.0.2", + "typescript": "^4.1.3", "worker-plugin": "^5.0.0" }, "standard": { diff --git a/public/fav-button.png b/public/fav-button.png new file mode 100644 index 000000000..3ec964d07 Binary files /dev/null and b/public/fav-button.png differ diff --git a/public/plus-sign.png b/public/plus-sign.png new file mode 100644 index 000000000..38e90b29c Binary files /dev/null and b/public/plus-sign.png differ diff --git a/src/components/FavButton.tsx b/src/components/FavButton.tsx new file mode 100644 index 000000000..3be4b5f07 --- /dev/null +++ b/src/components/FavButton.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import styled from "styled-components"; + +const HeartUI = styled.button<{ + isClick: boolean, + size: number, +}>` + width: ${props => props.size}px; + height: ${props => props.size}px; + float:right; + background: url("/fav-button.png") no-repeat; + cursor: pointer; + background-size: cover; + border: none; + ${({ isClick, size }) => isClick && `background-position: -${28 * size}px;transition: background 1s steps(28);`} +`; + + +export default function FavButton({ isClick, onClick, size }) { + return ( + + ); +} \ No newline at end of file diff --git a/src/components/FullScreenDropZone.tsx b/src/components/FullScreenDropZone.tsx new file mode 100644 index 000000000..20977552d --- /dev/null +++ b/src/components/FullScreenDropZone.tsx @@ -0,0 +1,41 @@ +import React, { useRef } from 'react'; +import styled from 'styled-components'; + +const DropDiv = styled.div` + flex: 1; + display: flex; + flex-direction: column; +`; + +type Props = React.PropsWithChildren<{ + showModal: () => void; + closeModal: () => void; +}>; + +export default function FullScreenDropZone({ children, showModal, closeModal }: Props) { + const closeTimer = useRef(); + + const clearTimer = () => { + if (closeTimer.current) { + clearTimeout(closeTimer.current); + } + } + + const onDragOver = (e) => { + e.preventDefault(); + clearTimer(); + showModal(); + } + + const onDragLeave = (e) => { + e.preventDefault(); + clearTimer(); + closeTimer.current = setTimeout(closeModal, 1000); + } + + return ( + + {children} + + ); +}; diff --git a/src/components/PhotoSwipe/PhotoSwipe.tsx b/src/components/PhotoSwipe/PhotoSwipe.tsx new file mode 100644 index 000000000..8e7f3546f --- /dev/null +++ b/src/components/PhotoSwipe/PhotoSwipe.tsx @@ -0,0 +1,196 @@ +import React, { useEffect, useState } from 'react'; +import Photoswipe from 'photoswipe'; +import PhotoswipeUIDefault from 'photoswipe/dist/photoswipe-ui-default'; +import classnames from 'classnames'; +import events from './events'; +import FavButton from 'components/FavButton'; +import { addToFavorites, removeFromFavorites } from 'services/collectionService'; +import { file } from 'services/fileService'; + +interface Iprops { + isOpen: boolean + items: any[]; + options?: Object; + onClose?: () => void; + gettingData?: (instance: any, index: number, item: file) => void; + id?: string; + className?: string; + favItemIds: Set; + setFavItemIds: (favItemIds: Set) => void; +}; + +function PhotoSwipe(props: Iprops) { + + let pswpElement; + const [photoSwipe, setPhotoSwipe] = useState>(); + + const { isOpen } = props; + const [isFav, setIsFav] = useState(false) + + + useEffect(() => { + if (!pswpElement) + return; + if (isOpen) + openPhotoSwipe(); + + }, [pswpElement]); + + useEffect(() => { + if (!pswpElement) + return; + if (isOpen) { + openPhotoSwipe(); + } + if (!isOpen) { + closePhotoSwipe(); + } + return () => { + closePhotoSwipe(); + } + }, [isOpen]); + + function updateFavButton() { + console.log(this.currItem.id, props.favItemIds) + setIsFav(isInFav(this?.currItem)); + } + + + const openPhotoSwipe = () => { + const { items, options } = props; + let photoSwipe = new Photoswipe(pswpElement, PhotoswipeUIDefault, items, options); + events.forEach((event) => { + const callback = props[event]; + if (callback || event === 'destroy') { + photoSwipe.listen(event, function (...args) { + if (callback) { + args.unshift(this); + callback(...args); + } + if (event === 'destroy') { + handleClose(); + } + }); + } + }); + photoSwipe.listen('beforeChange', updateFavButton); + photoSwipe.init(); + setPhotoSwipe(photoSwipe); + + }; + + const updateItems = (items = []) => { + photoSwipe.items = []; + items.forEach((item) => { + photoSwipe.items.push(item); + }); + photoSwipe.invalidateCurrItems(); + photoSwipe.updateSize(true); + }; + + const closePhotoSwipe = () => { + if (photoSwipe) + photoSwipe.close(); + }; + + const handleClose = () => { + const { onClose } = props; + if (onClose) { + onClose(); + } + }; + const isInFav = (file) => { + const { favItemIds } = props; + if (favItemIds && file) { + return favItemIds.has(file.id); + } + else + return false; + } + + const onFavClick = async (file) => { + const { favItemIds, setFavItemIds } = props; + if (!isInFav(file)) { + favItemIds.add(file.id); + await addToFavorites(file); + console.log("added to Favorites"); + setIsFav(true); + setFavItemIds(favItemIds); + } + else { + favItemIds.delete(file.id); + await removeFromFavorites(file) + console.log("removed from Favorites"); + setIsFav(false); + setFavItemIds(favItemIds); + + } + } + const { id } = props; + let { className } = props; + className = classnames(['pswp', className]).trim(); + return ( +