UNPKG

@hhgtech/hhg-components

Version:
479 lines (454 loc) • 18.2 kB
import React__default, { useState, useEffect, useContext, useRef } from 'react'; import { H as Heading } from './index-e348d0b2.js'; import { M as MediaQueries, t as toggleNoScroll } from './utils-538169b3.js'; import { u as useTranslations } from './index-09d9e570.js'; import { T as TogetherComponentGlobalContext } from './utils-5e9c89a7.js'; import { Portal } from '@mantine/core'; import { T as Text } from './index-0b67696c.js'; import styled from '@emotion/styled'; import { _ as __rest } from './tslib.es6-00ab44b2.js'; import { theme } from './miscTheme.js'; import { setDefaultClass } from './miscDefaultClassWrapper.js'; var img$2 = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none'%3e%3cpath stroke='%23262626' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M18 6 6 18M6 6l12 12'/%3e%3c/svg%3e"; var CloseIcon = img$2; var img$1 = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='25' fill='none'%3e%3cpath stroke='%23262626' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.75' d='M10.05 18.06 4 12.038l6.05-6.025M4.002 12.035h15'/%3e%3c/svg%3e"; var IconArrowLeft = img$1; const StyledWrapper$1 = styled.div ` padding: 14px 16px 14px 17px; background: ${(props) => props.bgColor}; border-left: 3px solid ${(props) => props.highlight}; ${MediaQueries.mbUp} { padding: 12px 12px 12px 17px; } `; const StyledInner$1 = styled.div ` display: flex; `; const StyledText = styled.div ` font-size: 12px; line-height: 18px; &[data-has-icon='true'] { margin-left: 10px; } `; const StyledIcon$1 = styled.div ` flex-shrink: 0; `; const NotificationBar = (_a) => { var { icon, bgColor = theme.colors.yellow50, highlightColor = theme.colors.yellow800, message } = _a, rest = __rest(_a, ["icon", "bgColor", "highlightColor", "message"]); return (React__default.createElement(StyledWrapper$1, Object.assign({ bgColor: bgColor, highlight: highlightColor }, rest), React__default.createElement(StyledInner$1, null, icon && React__default.createElement(StyledIcon$1, null, icon), React__default.createElement(StyledText, { "data-has-icon": Boolean(icon) }, message)))); }; const StyledPostImagePreview = styled.div ` display: grid; grid-gap: 3px; grid-template-columns: 1fr 1fr; grid-template-rows: auto; .img-wrapper { position: relative; overflow: hidden; width: 100%; padding-top: 56.25%; grid-column: auto; & > img { cursor: zoom-in; } .img-preview-blur { position: absolute; top: 50%; left: 50%; width: 110%; height: 110%; /* Add the blur effect */ -webkit-filter: blur(8px); filter: blur(8px); object-fit: cover; object-position: center; opacity: 0.8; transform: translate(-50%, -50%); } .img-preview { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; object-position: center; } .img-more-overlay { position: absolute; top: 0; left: 0; display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.5); z-index: 4; } } &[data-image-count='1'] { .img-wrapper { /* padding-top: 100%; */ grid-column: 1/3; } } &[data-image-count='2'] { .img-wrapper { /* padding-top: 100%; */ } } &[data-image-count='3'] { .img-wrapper { &:first-child { grid-column: 1/3; } } } &[data-image-count='4'] { .img-wrapper { /* padding-top: 100%; */ } } &[data-image-count='5'] { grid-template-columns: repeat(6, 1fr); .img-wrapper { /* padding-top: 100%; */ grid-column: auto/ span 2; &:first-child { padding-top: 56.25%; grid-column: 1/4; } &:nth-child(2) { padding-top: 56.25%; grid-column: 4/7; } } } &[data-is-marrybaby='true'] { grid-gap: 8px; .img-wrapper { padding-top: 66.66%; border-radius: 1rem; .img-preview { object-fit: cover; } } &[data-image-count='3'] { grid-template-columns: 1fr 1fr 1fr; .img-wrapper { &:first-child { padding-top: 100%; grid-column: 1/3; grid-row: 1/3; } } } } `; const StyledImagePreviewPopup = styled.div ` position: fixed; z-index: 999; top: 0; left: 0; display: flex; overflow: hidden; width: 100vw; height: 100vh; flex-direction: column; background: white; opacity: 0; pointer-events: none; transition: opacity 0.2s linear; &[data-open='true'] { opacity: 1; pointer-events: auto; } .top-bar { position: relative; padding: 20px 40px; .icon-arrow-left { position: absolute; top: 50%; left: 20px; height: 24px; width: 24px; cursor: pointer; transform: translateY(-50%); } } .container { flex: 1; overflow-y: auto; .img-preview { width: 100%; min-width: 100%; margin-bottom: 0.5rem; cursor: pointer; max-height: 100%; object-fit: cover; } } `; const StyledNotificationBar = styled(NotificationBar) ` margin-bottom: 16px; &.noti-bottom { border-left: none; margin-top: 4px; padding: 4px 8px; margin-left: 16px; margin-right: 16px; border-radius: 4px; } `; const ImagePreviewPopup = ({ className, style, authorName, images, onClose, onOpenSingleView, alt, }) => { const { t } = useTranslations(); const [isOpen, setIsOpen] = useState(false); useEffect(() => { setTimeout(() => { setIsOpen(true); }, 0); }, []); return (React__default.createElement(Portal, null, React__default.createElement(StyledImagePreviewPopup, { className: className, style: style, "data-open": isOpen }, React__default.createElement("div", { className: "top-bar" }, React__default.createElement("img", { className: "icon-arrow-left", src: IconArrowLeft, onClick: onClose, alt: "go back", loading: "lazy" }), React__default.createElement(Text, { size: "p2", weight: "bold", style: { textAlign: 'center', } }, t('previewPhotos.title', { name: authorName, }))), React__default.createElement("div", { className: "container" }, images.map((image, index) => (React__default.createElement("img", { className: "img-preview", key: index, src: image, onClick: () => onOpenSingleView === null || onOpenSingleView === void 0 ? void 0 : onOpenSingleView(index), alt: alt, loading: "lazy" }))))), ",")); }; const StyledImagePreviewContainer = styled.div ` position: fixed; z-index: 999; top: 0; left: 0; display: flex; width: 100%; height: 100%; flex-direction: column; background: black; opacity: 0; pointer-events: none; transition: opacity 0.2s linear; &[data-open='true'] { opacity: 1; pointer-events: auto; } `; const StyledImagePreviewTopbar = styled.div ` padding: 1rem; background: white; .icon-close { width: 26px; height: 26px; cursor: pointer; } `; const StyledImagePreviewWrapper = styled.div ` position: relative; flex: 1; overflow: hidden; > img { height: 100%; width: 100%; object-fit: contain; object-position: center; } `; const StyledArrowWrapper = styled.div ` --inner-padding: max(16px, 20%); height: 100%; position: absolute; left: 0; padding: 8px; padding-right: var(--inner-padding); display: flex; align-items: center; top: 0; cursor: pointer; &[data-right] { padding-right: 8px; padding-left: var(--inner-padding); left: unset; right: 0; } &[data-disabled='true'] { cursor: not-allowed; } `; const StyledCircleArrow = styled.div ` border-radius: 50%; background: rgba(0, 0, 0, 0.3); display: flex; align-items: center; justify-content: center; padding: 4px; > img { width: 16px; height: 16px; &[data-disabled='true'] { opacity: 0.5; } } ${MediaQueries.tdUp} { padding: 8px; > img { width: 30px; height: 30px; } } `; var img = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='17' fill='none'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.75' d='m6 12.813 4-4-4-4'/%3e%3c/svg%3e"; var ChevronRightIcon = img; const PostSingleImageViewPopup = ({ initialViewIndex, images, onClose, alt, }) => { const [viewIndex, setViewIndex] = useState(initialViewIndex); const [isOpen, setIsOpen] = useState(false); useEffect(() => { setTimeout(() => { setIsOpen(true); }, 0); }, []); const previewImg = images === null || images === void 0 ? void 0 : images[viewIndex]; const leftDisabled = viewIndex === 0; const rightDisabled = !(images === null || images === void 0 ? void 0 : images.length) || viewIndex === (images === null || images === void 0 ? void 0 : images.length) - 1; return (React__default.createElement(Portal, null, React__default.createElement(StyledImagePreviewContainer, { "data-open": isOpen && !!previewImg }, React__default.createElement(StyledImagePreviewTopbar, null, React__default.createElement("img", { src: CloseIcon, className: "icon-close", onClick: onClose, alt: "close", loading: "lazy" })), previewImg && viewIndex >= 0 && (React__default.createElement(React__default.Fragment, null, React__default.createElement(StyledImagePreviewWrapper, null, React__default.createElement("img", { className: "img-preview", src: previewImg, alt: alt, loading: "lazy" }), React__default.createElement(StyledArrowWrapper, { "data-disabled": leftDisabled, onClick: () => !leftDisabled && setViewIndex(viewIndex - 1) }, React__default.createElement(StyledCircleArrow, null, React__default.createElement("img", { src: ChevronRightIcon, style: { transform: 'rotate(180deg)', }, alt: "left arrow", "data-disabled": leftDisabled, loading: "lazy" }))), React__default.createElement(StyledArrowWrapper, { "data-right": true, "data-disabled": rightDisabled, onClick: () => !rightDisabled && setViewIndex(viewIndex + 1) }, React__default.createElement(StyledCircleArrow, null, React__default.createElement("img", { src: ChevronRightIcon, alt: "right arrow", "data-disabled": rightDisabled, loading: "lazy" }))))))))); }; const StyledInner = setDefaultClass(styled.div ` position: absolute; top: 0; right: 0; left: 0; bottom: 0; background: rgba(0, 0, 0, 0.4); color: white; display: flex; align-items: center; justify-content: center; cursor: pointer; `, 'hhgcomp-sensitivemask-inner'); const StyledIcon = styled.div ``; const StyledWrapper = styled.div ` position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; z-index: 3; background: white; cursor: pointer; &, * { // transition: all 300ms; transform-origin: bottom left; } img { transition: none; } .img-preview { width: 100%; } &[data-is-blurred='true'] { .img-preview { /* Add the blur effect */ -webkit-filter: blur(24px); filter: blur(24px); } } &[data-is-blurred='false'] { background: transparent; cursor: zoom-in; ${StyledInner.classSelector} { top: auto; right: auto; left: 8px; bottom: 8px; background: rgba(0, 0, 0, 0); align-items: flex-end; justify-content: flex-start; } } `; const SensitiveMask = ({ image, showIcon = true }) => { const [isBlur, setBlur] = useState(true); return (React__default.createElement(StyledWrapper, { "data-is-blurred": isBlur, onClick: (e) => isBlur && e.stopPropagation() }, React__default.createElement("img", { loading: "lazy", className: "img-preview", src: image }), React__default.createElement(StyledInner, { onClick: (e) => { e.stopPropagation(); setBlur(!isBlur); } }, showIcon && (React__default.createElement(StyledIcon, null, isBlur ? (React__default.createElement("svg", { width: "22", height: "20", viewBox: "0 0 22 20", fill: "none" }, React__default.createElement("path", { d: "M1.71 2.54a.996.996 0 0 1 0-1.41c.39-.39 1.03-.39 1.42 0l16.31 16.33a.996.996 0 1 1-1.41 1.41l-2.72-2.72c-1.34.52-2.79.82-4.31.82-5 0-9.27-3.11-11-7.5C.77 7.5 2.06 5.8 3.68 4.51zM16 9.47c0-2.76-2.24-5-5-5-.51 0-1 .1-1.47.24L7.36 2.54c1.15-.37 2.37-.57 3.64-.57 5 0 9.27 3.11 11 7.49-.69 1.76-1.79 3.3-3.18 4.53l-3.06-3.06c.14-.46.24-.95.24-1.46m-5 5c-2.76 0-5-2.24-5-5 0-.77.18-1.5.49-2.14L8.06 8.9c-.03.18-.06.37-.06.57 0 1.66 1.34 3 3 3 .2 0 .38-.03.57-.07l1.57 1.57c-.65.32-1.37.5-2.14.5m2.97-5.33a2.97 2.97 0 0 0-2.64-2.64z", fill: "#fff" }))) : (React__default.createElement("svg", { width: "23", height: "16", viewBox: "0 0 23 16", fill: "none" }, React__default.createElement("path", { d: "M12 0C5.142 0 1.886 5.879 1.096 7.557c-.132.28-.132.604 0 .884C1.886 10.121 5.142 16 12 16c6.834 0 10.092-5.837 10.896-7.54a1.08 1.08 0 0 0 0-.92C22.092 5.836 18.834 0 12 0m0 3a5 5 0 1 1-.001 10.001 5 5 0 0 1 0-10.001m0 2a3 3 0 1 0 0 6 3 3 0 0 0 0-6", fill: "#2D87F3" })))))))); }; const PostImagePreview = ({ className, images = [], style, authorName, isSensitive = false, alt, positionAlert = 'top', }) => { const { data: { env: { isMarryBaby }, }, } = useContext(TogetherComponentGlobalContext); const { t } = useTranslations(); const moreImageCount = `+ ${(images.length || 0) - 4}`; const [isOpenImagePreview, setIsOpenImagePreview] = useState(false); const [singleImageViewIndex, setSingleImageViewIndex] = useState(-1); const hasMore = images.length > 5; // Check if this component has set no scroll previously and clean it up const hasSetNoScroll = useRef(false); useEffect(() => { return () => { if (hasSetNoScroll.current) { toggleNoScroll(false); } }; }, []); useEffect(() => { if (isOpenImagePreview || singleImageViewIndex >= 0) { toggleNoScroll(true); hasSetNoScroll.current = true; } else { toggleNoScroll(false); hasSetNoScroll.current = false; } }, [isOpenImagePreview, singleImageViewIndex]); return (React__default.createElement(React__default.Fragment, null, isSensitive && positionAlert === 'top' && (React__default.createElement(StyledNotificationBar, { message: t('sensitiveMask.contentWarningDescription'), icon: React__default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" }, React__default.createElement("path", { d: "M9 .667A8.336 8.336 0 0 0 .667 9c0 4.6 3.733 8.333 8.333 8.333S17.333 13.6 17.333 9 13.6.667 9 .667m0 9.166A.836.836 0 0 1 8.167 9V5.667c0-.459.375-.834.833-.834s.833.375.833.834V9A.836.836 0 0 1 9 9.833M8.167 11.5v1.667h1.666V11.5z", fill: "#FE921D" })) })), React__default.createElement(StyledPostImagePreview, { className: className, style: style, "data-image-count": hasMore ? 5 : images.length || 0, "data-is-marrybaby": isMarryBaby, "data-cursor-pointer": !isSensitive }, images === null || images === void 0 ? void 0 : images.slice(0, 5).map((image, index) => { const isMore = index === 4 && hasMore; return (React__default.createElement("div", { className: `img-wrapper`, key: index, onClick: () => { if (index >= 4 && hasMore) { setIsOpenImagePreview(true); } else { setSingleImageViewIndex(index); } } }, isSensitive && (React__default.createElement(SensitiveMask, { image: image, showIcon: !isMore })), !isMarryBaby && (React__default.createElement("img", { loading: "lazy", className: "img-preview-blur", src: image, alt: alt })), React__default.createElement("img", { loading: "lazy", className: "img-preview", src: image, alt: alt }), isMore && (React__default.createElement("div", { className: "img-more-overlay" }, React__default.createElement(Heading, { tag: "h1", as: "h2", color: "white" }, moreImageCount))))); })), isOpenImagePreview && (React__default.createElement(ImagePreviewPopup, { authorName: authorName || '', images: images, onClose: () => setIsOpenImagePreview(false), onOpenSingleView: setSingleImageViewIndex, alt: alt })), singleImageViewIndex >= 0 && (React__default.createElement(PostSingleImageViewPopup, { images: images, initialViewIndex: singleImageViewIndex, onClose: () => setSingleImageViewIndex(-1), alt: alt })), isSensitive && positionAlert === 'bottom' && (React__default.createElement(StyledNotificationBar, { message: t('sensitiveMask.contentWarningDescription.community'), className: "noti-bottom", icon: React__default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" }, React__default.createElement("path", { d: "M9 .667A8.336 8.336 0 0 0 .667 9c0 4.6 3.733 8.333 8.333 8.333S17.333 13.6 17.333 9 13.6.667 9 .667m0 9.166A.836.836 0 0 1 8.167 9V5.667c0-.459.375-.834.833-.834s.833.375.833.834V9A.836.836 0 0 1 9 9.833M8.167 11.5v1.667h1.666V11.5z", fill: "#FE921D" })) })))); }; export { CloseIcon as C, ImagePreviewPopup as I, PostSingleImageViewPopup as P, PostImagePreview as a, IconArrowLeft as b };