import type { RefObject } from 'react'; import type { FC } from '../../../lib/teact/teact'; import React, { memo, useEffect, useRef } from '../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../global'; import type { ApiSponsoredMessage } from '../../../api/types'; import { selectSponsoredMessage } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { IS_ANDROID } from '../../../util/windowEnvironment'; import { renderTextWithEntities } from '../../common/helpers/renderTextWithEntities'; import { preventMessageInputBlur } from '../helpers/preventMessageInputBlur'; import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers'; import useFlag from '../../../hooks/useFlag'; import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver'; import useLastCallback from '../../../hooks/useLastCallback'; import useOldLang from '../../../hooks/useOldLang'; import AboutAdsModal from '../../common/AboutAdsModal.async'; import Avatar from '../../common/Avatar'; import Icon from '../../common/icons/Icon'; import PeerColorWrapper from '../../common/PeerColorWrapper'; import Button from '../../ui/Button'; import MessageAppendix from './MessageAppendix'; import SponsoredMessageContextMenuContainer from './SponsoredMessageContextMenuContainer.async'; import './SponsoredMessage.scss'; type OwnProps = { chatId: string; containerRef: RefObject; }; type StateProps = { message?: ApiSponsoredMessage; }; const INTERSECTION_DEBOUNCE_MS = 200; const SponsoredMessage: FC = ({ chatId, message, containerRef, }) => { const { viewSponsoredMessage, openUrl, hideSponsoredMessages, clickSponsoredMessage, reportSponsoredMessage, } = getActions(); const lang = useOldLang(); // eslint-disable-next-line no-null/no-null const ref = useRef(null); // eslint-disable-next-line no-null/no-null const contentRef = useRef(null); const shouldObserve = Boolean(message); const { observe: observeIntersection, } = useIntersectionObserver({ rootRef: containerRef, debounceMs: INTERSECTION_DEBOUNCE_MS, threshold: 1, }); const { isContextMenuOpen, contextMenuAnchor, handleBeforeContextMenu, handleContextMenu, handleContextMenuClose, handleContextMenuHide, } = useContextMenuHandlers(ref, undefined, true, IS_ANDROID); const [isAboutAdsModalOpen, openAboutAdsModal, closeAboutAdsModal] = useFlag(false); useEffect(() => { return shouldObserve ? observeIntersection(contentRef.current!, (target) => { if (target.isIntersecting) { viewSponsoredMessage({ chatId }); } }) : undefined; }, [chatId, shouldObserve, observeIntersection, viewSponsoredMessage]); const handleMouseDown = (e: React.MouseEvent) => { preventMessageInputBlur(e); handleBeforeContextMenu(e); }; const handleReportSponsoredMessage = useLastCallback(() => { reportSponsoredMessage({ chatId, randomId: message!.randomId }); }); const handleHideSponsoredMessage = useLastCallback(() => { hideSponsoredMessages(); }); const handleClick = useLastCallback(() => { if (!message) return; clickSponsoredMessage({ chatId }); openUrl({ url: message!.url, shouldSkipModal: true }); }); if (!message) { return undefined; } function renderContent() { if (!message) return undefined; return ( <>
{message.title}
{renderTextWithEntities({ text: message!.text.text, entities: message!.text.entities, })}
); } return (
{message.photo && ( )} {message!.isRecommended ? lang('Message.RecommendedLabel') : lang('SponsoredMessage')} {lang('SponsoredMessageAdWhatIsThis')} {renderContent()}
{message.canReport && ( )}
{contextMenuAnchor && ( )}
); }; export default memo(withGlobal( (global, { chatId }): StateProps => { const message = selectSponsoredMessage(global, chatId); return { message, }; }, )(SponsoredMessage));