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 'pl-fe/actions/accounts'; import { closeProfileHoverCard, updateProfileHoverCard } from 'pl-fe/actions/profile-hover-card'; import { useAccount } from 'pl-fe/api/hooks'; import Badge from 'pl-fe/components/badge'; import ActionButton from 'pl-fe/features/ui/components/action-button'; import { UserPanel } from 'pl-fe/features/ui/util/async-components'; import { useAppSelector, useAppDispatch } from 'pl-fe/hooks'; import { showProfileHoverCard } from './hover-ref-wrapper'; import { dateFormatOptions } from './relative-timestamp'; import { Card, CardBody, HStack, Icon, Stack, Text } from './ui'; import type { Account } from 'pl-fe/normalizers'; import type { AppDispatch } from 'pl-fe/store'; const getBadges = ( account?: Pick, ): JSX.Element[] => { const badges = []; if (account?.is_admin) { badges.push(} />); } else if (account?.is_moderator) { badges.push(} />); } return badges; }; const handleMouseEnter = (dispatch: AppDispatch): React.MouseEventHandler => () => { dispatch(updateProfileHoverCard()); }; const handleMouseLeave = (dispatch: AppDispatch): React.MouseEventHandler => () => { dispatch(closeProfileHoverCard(true)); }; interface IProfileHoverCard { visible?: boolean; } /** Popup profile preview that appears when hovering avatars and display names. */ 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 } = useAccount(accountId, { withRelationship: true }); const targetRef = useAppSelector(state => state.profile_hover_card.ref?.current); const badges = 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 (
} badges={badges} /> {account.local ? ( ) : null} {account.note.length > 0 && ( )} {followedBy && (
} />
)}
); }; export { ProfileHoverCard as default };