import clsx from 'clsx'; import React, { useEffect, useState } from 'react'; import { useIntl, FormattedMessage } from 'react-intl'; import { usePopper } from 'react-popper'; import { useHistory } from 'react-router-dom'; import { fetchRelationships } from 'soapbox/actions/accounts'; import { closeProfileHoverCard, updateProfileHoverCard, } from 'soapbox/actions/profile-hover-card'; import Badge from 'soapbox/components/badge'; import ActionButton from 'soapbox/features/ui/components/action-button'; import BundleContainer from 'soapbox/features/ui/containers/bundle-container'; import { UserPanel } from 'soapbox/features/ui/util/async-components'; import { useAppSelector, useAppDispatch } from 'soapbox/hooks'; import { makeGetAccount } from 'soapbox/selectors'; import { isLocal } from 'soapbox/utils/accounts'; import { showProfileHoverCard } from './hover-ref-wrapper'; import { Card, CardBody, HStack, Icon, Stack, Text } from './ui'; import type { AppDispatch } from 'soapbox/store'; import type { Account } from 'soapbox/types/entities'; const getAccount = makeGetAccount(); const getBadges = (account: Account): JSX.Element[] => { const badges = []; if (account.admin) { badges.push(); } else if (account.moderator) { badges.push(); } if (account.getIn(['patron', 'is_patron'])) { badges.push(); } return badges; }; const handleMouseEnter = (dispatch: AppDispatch): React.MouseEventHandler => { return () => { dispatch(updateProfileHoverCard()); }; }; const handleMouseLeave = (dispatch: AppDispatch): React.MouseEventHandler => { return () => { dispatch(closeProfileHoverCard(true)); }; }; interface IProfileHoverCard { visible: boolean } /** Popup profile preview that appears when hovering avatars and display names. */ export const ProfileHoverCard: React.FC = ({ visible = true }) => { const dispatch = useAppDispatch(); const history = useHistory(); const intl = useIntl(); const [popperElement, setPopperElement] = useState(null); const me = useAppSelector(state => state.me); const accountId: string | undefined = useAppSelector(state => state.profile_hover_card.accountId || undefined); const account = useAppSelector(state => accountId && getAccount(state, accountId)); const targetRef = useAppSelector(state => state.profile_hover_card.ref?.current); const badges = account ? getBadges(account) : []; useEffect(() => { if (accountId) dispatch(fetchRelationships([accountId])); }, [dispatch, accountId]); useEffect(() => { const unlisten = history.listen(() => { showProfileHoverCard.cancel(); dispatch(closeProfileHoverCard()); }); return () => { unlisten(); }; }, []); const { styles, attributes } = usePopper(targetRef, popperElement); if (!account) return null; const accountBio = { __html: account.note_emojified }; const memberSinceDate = intl.formatDate(account.created_at, { month: 'long', year: 'numeric' }); const followedBy = me !== account.id && account.relationship?.followed_by === true; return (
{Component => ( } badges={badges} /> )} {isLocal(account) ? ( ) : null} {account.note.length > 0 && ( )} {followedBy && (
} />
)}
); }; export default ProfileHoverCard;