import React, { FC, memo, useEffect, useMemo, } from '../../../lib/teact/teact'; import { withGlobal } from '../../../lib/teact/teactn'; import { GlobalActions } from '../../../global/types'; import { ApiMessage, ApiMessageEntityTypes, ApiWebPage } from '../../../api/types'; import { RE_LINK_TEMPLATE } from '../../../config'; import { selectNoWebPage } from '../../../modules/selectors'; import { pick } from '../../../util/iteratees'; import parseMessageInput from './helpers/parseMessageInput'; import useOnChange from '../../../hooks/useOnChange'; import useShowTransition from '../../../hooks/useShowTransition'; import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev'; import buildClassName from '../../../util/buildClassName'; import WebPage from '../message/WebPage'; import Button from '../../ui/Button'; import './WebPagePreview.scss'; type OwnProps = { chatId: number; threadId: number; messageText: string; disabled?: boolean; }; type StateProps = { webPagePreview?: ApiWebPage; noWebPage?: boolean; }; type DispatchProps = Pick; const RE_LINK = new RegExp(RE_LINK_TEMPLATE, 'i'); const WebPagePreview: FC = ({ chatId, threadId, messageText, disabled, webPagePreview, noWebPage, loadWebPagePreview, clearWebPagePreview, toggleMessageWebPage, }) => { const link = useMemo(() => { const { text, entities } = parseMessageInput(messageText); const linkEntity = entities && entities.find(({ type }) => type === ApiMessageEntityTypes.TextUrl); if (linkEntity) { return linkEntity.url; } const textMatch = text.match(RE_LINK); if (textMatch) { return textMatch[0]; } return undefined; }, [messageText]); useEffect(() => { if (link) { loadWebPagePreview({ text: link }); } else { clearWebPagePreview(); toggleMessageWebPage({ chatId, threadId }); } }, [chatId, toggleMessageWebPage, clearWebPagePreview, link, loadWebPagePreview, threadId]); useOnChange(() => { clearWebPagePreview(); toggleMessageWebPage({ chatId, threadId }); }, [chatId]); const isShown = Boolean(webPagePreview && messageText.length && !noWebPage && !disabled); const { shouldRender, transitionClassNames } = useShowTransition(isShown); const renderingWebPage = useCurrentOrPrev(webPagePreview); if (!shouldRender || !renderingWebPage) { return undefined; } const handleClearWebpagePreview = () => { toggleMessageWebPage({ chatId, threadId, noWebPage: true }); }; // TODO Refactor so `WebPage` can be used without message const { photo, ...webPageWithoutPhoto } = renderingWebPage; const messageStub = { content: { webPage: webPageWithoutPhoto, }, } as ApiMessage; return (
); }; export default memo(withGlobal( (global, { chatId, threadId }): StateProps => { const noWebPage = selectNoWebPage(global, chatId, threadId); return { webPagePreview: global.webPagePreview, noWebPage, }; }, (setGlobal, actions): DispatchProps => pick(actions, [ 'loadWebPagePreview', 'clearWebPagePreview', 'toggleMessageWebPage', ]), )(WebPagePreview));