import { useRef, useState, useEffect, FC } from "react"; import styled, { keyframes } from "styled-components"; import { useOutsideClick, useKey } from "rooks"; import { Ring } from "@uiball/loaders"; import Modal from "./Modal"; const AniFadeIn = keyframes` from { background: transparent; } to { background: rgba(1, 1, 1, 0.9); } `; const StyledWrapper = styled.div` transition: all 0.5s ease; width: 100vw; height: 100vh; animation: ${AniFadeIn} 0.3s ease-in-out forwards; display: flex; align-items: center; justify-content: center; .box { position: relative; transition: all 0.2s ease; display: flex; flex-direction: column; justify-content: flex-start; gap: 10px; > .loading { position: absolute; top: 40%; left: 50%; transform: translateX(-50%); } > .image { overflow: auto; img { max-width: 70vw; max-height: 80vh; } } &.loading .image img { filter: blur(2px); } .origin { font-weight: bold; font-size: 14px; color: #aaa; &:hover { text-decoration: underline; color: #fff; } } } `; export interface PreviewImageData { originUrl: string; thumbnail?: string; downloadLink?: string; name?: string; type?: string; } interface Props { download?: boolean; data?: PreviewImageData; closeModal: () => void; } const ImagePreviewModal: FC = ({ download = true, data, closeModal }) => { const [url, setUrl] = useState(data?.thumbnail); const [loading, setLoading] = useState(true); const wrapperRef = useRef(null); useOutsideClick(wrapperRef, closeModal); useKey( "Escape", () => { closeModal(); }, { eventTypes: ["keyup"] } ); useEffect(() => { if (data) { const { originUrl } = data; if (!originUrl) setLoading(false); const img = new Image(); img.src = originUrl; img.onload = () => { setUrl(originUrl); setLoading(false); }; img.onerror = () => { setLoading(false); }; } }, [data]); if (!data) return null; const { originUrl, downloadLink, name, type } = data; return (
preview
{download && ( Download original )} {loading && (
)}
); }; export default ImagePreviewModal;