import React, { useState, useEffect, useRef } from 'react'; import { FormattedMessage } from 'react-intl'; import { Stack, HStack, Card, Avatar, Text, Icon } from 'soapbox/components/ui'; import IconButton from 'soapbox/components/ui/icon-button/icon-button'; import StatusCard from 'soapbox/features/status/components/card'; import { useAppSelector } from 'soapbox/hooks'; import type { Card as CardEntity } from 'soapbox/types/entities'; interface IAd { /** Embedded ad data in Card format (almost like OEmbed). */ card: CardEntity, /** Impression URL to fetch upon display. */ impression?: string, } /** Displays an ad in sponsored post format. */ const Ad: React.FC = ({ card, impression }) => { const instance = useAppSelector(state => state.instance); const infobox = useRef(null); const [showInfo, setShowInfo] = useState(false); /** Toggle the info box on click. */ const handleInfoButtonClick: React.MouseEventHandler = () => { setShowInfo(!showInfo); }; /** Hide the info box when clicked outside. */ const handleClickOutside = (event: MouseEvent) => { if (event.target && infobox.current && !infobox.current.contains(event.target as any)) { setShowInfo(false); } }; // Hide the info box when clicked outside. // https://stackoverflow.com/a/42234988 useEffect(() => { document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [infobox]); // Fetch the impression URL (if any) upon displaying the ad. // It's common for ad providers to provide this. useEffect(() => { if (impression) { fetch(impression); } }, [impression]); return (
{instance.title} {}} horizontal /> {showInfo && (
)}
); }; export default Ad;