UNPKG

@hhgtech/hhg-components

Version:
233 lines (224 loc) • 11 kB
'use strict'; var tslib_es6 = require('./tslib.es6-92cccef3.js'); var React = require('react'); var core = require('@mantine/core'); var useScreenSize = require('./useScreenSize-30f50b76.js'); var togetherComponentGlobalContext = require('./utils-aea77f4a.js'); var styled = require('@emotion/styled'); var togetherApiPaths = require('./togetherApiPaths.js'); var constants = require('./constants-bb30dda6.js'); var post = require('./post-ca5ee38c.js'); var index = require('./index-33cb6efd.js'); function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefault(React); var styled__default = /*#__PURE__*/_interopDefault(styled); const StyledSocialLinkPreview = styled__default["default"].div ` .link-info-container { padding: 0.5rem 1rem; background: ${(props) => props.color || '#f4faff'}; } .link-image-wrapper { position: relative; overflow: hidden; width: 100%; padding-top: 56.25%; &.fetching { background: lightgray; } .loading-spinner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .link-image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; } } a { text-decoration: none; } &[data-is-marrybaby='true'] { overflow: hidden; border-radius: 1rem; } `; const useExternalScript = ({ url, onLoad, onError }) => { const [state, setState] = React.useState(url ? 'loading' : 'idle'); React.useEffect(() => { if (!url) { setState('idle'); return; } let script = document.querySelector(`script[src="${url}"]`); const handleLoadScript = () => { setState('ready'); onLoad === null || onLoad === void 0 ? void 0 : onLoad(); }; const handleErrorScript = () => { setState('error'); onError === null || onError === void 0 ? void 0 : onError(); }; if (!script) { script = document.createElement('script'); script.type = 'application/javascript'; script.src = url; script.async = true; document.body.appendChild(script); script.addEventListener('load', handleLoadScript); script.addEventListener('error', handleErrorScript); } script.addEventListener('load', handleLoadScript); script.addEventListener('error', handleErrorScript); return () => { script.removeEventListener('load', handleLoadScript); script.removeEventListener('error', handleErrorScript); }; }, [url]); return state; }; const YoutubePlyr = ({ id, autoplay }) => { const ref = React.useRef(null); const state = useExternalScript({ url: 'https://cdn.plyr.io/3.7.8/plyr.js' }); React.useEffect(() => { if (!document.getElementById('hhg-plyr-player')) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = 'https://cdn.plyr.io/3.7.8/plyr.css'; link.id = 'hhg-plyr-player'; document.head.appendChild(link); } if (state === 'ready' || typeof Plyr !== 'undefined') { new Plyr(ref.current.querySelector('[data-id="player"]'), { autoplay, muted: true, }); } }, [state]); return (React__default["default"].createElement(React__default["default"].Fragment, null, React__default["default"].createElement(core.Box, { ref: ref, sx: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: '#000', '&, > div': { width: '100%', height: '100%', }, } }, React__default["default"].createElement("div", { "data-id": "player" }, React__default["default"].createElement("iframe", { width: "100%", height: "100%", src: `https://www.youtube.com/embed/${id}?&mute=1&enablejsapi=1&rel=0`, allowFullScreen: true, frameBorder: "0" }))))); }; const SocialLinkPreview = ({ url, image, className, style, baseUrl = '', autoPlay = true, onPushStatus, }) => { const { data: { locale }, } = React.useContext(togetherComponentGlobalContext.TogetherComponentGlobalContext); const [previewData, setPreviewData] = React.useState(null); React.useEffect(() => { (() => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { if (image) return; if (!url) return setPreviewData(null); setPreviewData((_data) => (Object.assign(Object.assign({}, _data), { isFetching: true }))); // fetch('./api/fetch-meta?url=' + encodeURIComponent(url)) // .then((res) => res.json()) // .then((res) => // setPreviewData({ // url, // image: res?.image || res?.logo, // }), // ) togetherComponentGlobalContext.callApi(togetherComponentGlobalContext.getApiPath(togetherApiPaths.PATHS.FETCH_PREVIEW, { _locale: locale, }, undefined, baseUrl), 'POST', { data: { link: url, }, headers: { 'Content-Type': 'application/json', }, }, !!baseUrl) .then((res) => { var _a, _b; setPreviewData({ url, image: ((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.image) || ((_b = res === null || res === void 0 ? void 0 : res.data) === null || _b === void 0 ? void 0 : _b.logo), }); }) .catch(() => { setPreviewData(null); }); }))(); }, [url, image]); const displayImage = image || (previewData === null || previewData === void 0 ? void 0 : previewData.image); const displayUrl = (previewData === null || previewData === void 0 ? void 0 : previewData.url) || url; const youtubeVidId = React.useMemo(() => { return post.youtubeVidIdGetter(displayUrl); }, [displayUrl]); const facebookVidId = React.useMemo(() => { return (displayUrl.includes('facebook.com') || displayUrl.includes('fb.watch')); }, [displayUrl]); const responsiveWidth = React.useRef(0); const responsiveHeight = React.useRef(0); const [forceRerenderFB, setForceRerenderFB] = React.useState(false); // FACEBOOK Video is not responsive for desktop browser // => hack: set size to same as container, if size change too large, re-render facebook iframe with new config React.useEffect(() => { const handleResize = () => { var _a; const containerRect = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect(); let toChangeSize = false; if (containerRect && (!responsiveWidth.current || Math.abs((responsiveWidth.current - containerRect.width) / (containerRect === null || containerRect === void 0 ? void 0 : containerRect.width)) > 0.2)) { responsiveWidth.current = Math.floor(containerRect.width); toChangeSize = true; } if (containerRect && (!responsiveHeight.current || Math.abs((responsiveHeight.current - containerRect.height) / (containerRect === null || containerRect === void 0 ? void 0 : containerRect.height)) > 0.2)) { responsiveHeight.current = Math.floor(containerRect.height); toChangeSize = true; } if (toChangeSize) { setForceRerenderFB((v) => !v); } }; handleResize(); window.addEventListener('resize', handleResize, { passive: true, }); return () => { window.removeEventListener('resize', handleResize); }; }, []); React.useEffect(() => { if ((previewData === null || previewData === void 0 ? void 0 : previewData.image) && (previewData === null || previewData === void 0 ? void 0 : previewData.url)) { onPushStatus === null || onPushStatus === void 0 ? void 0 : onPushStatus(true); } }, [previewData]); const containerRef = React.useRef(null); const _theme = core.useMantineTheme(); return (React__default["default"].createElement(StyledSocialLinkPreview, { className: `${className} no-replace-click`, style: style, ref: containerRef, color: _theme.colors[_theme.primaryColor][0] }, !image && (youtubeVidId || facebookVidId) ? (React__default["default"].createElement("div", { className: "link-image-wrapper" }, youtubeVidId ? (React__default["default"].createElement(YoutubePlyr, { id: youtubeVidId, autoplay: autoPlay })) : facebookVidId ? (React__default["default"].createElement("iframe", { key: String(forceRerenderFB), src: `https://www.facebook.com/plugins/video.php?href=${encodeURIComponent(displayUrl)}&autoplay=${autoPlay ? 1 : 0}&show_text=false&t=0&width=${responsiveWidth.current}&height=${responsiveHeight.current}`, style: { position: 'absolute', top: '50%', left: '50%', border: 'none', overflow: 'hidden', height: responsiveHeight.current, width: responsiveWidth.current, transform: 'translate(-50%, -50%)', }, scrolling: "no", frameBorder: "0", allowFullScreen: true, allow: "autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share", loading: "lazy" })) : null)) : (React__default["default"].createElement("a", { href: displayUrl, target: "_blank", rel: "noreferrer" }, React__default["default"].createElement("div", { className: `link-image-wrapper ${(previewData === null || previewData === void 0 ? void 0 : previewData.isFetching) ? 'fetching' : ''}` }, (previewData === null || previewData === void 0 ? void 0 : previewData.isFetching) ? (React__default["default"].createElement(index.Loading, { className: "loading-spinner" })) : (React__default["default"].createElement(useScreenSize.ImageWrap, { className: "link-image", src: displayImage || constants.DEFAULT_IMG, backupSrc: constants.DEFAULT_IMG, alt: displayUrl }))))))); }; exports.SocialLinkPreview = SocialLinkPreview;