import type { ReactNode } from 'react'; import type React from 'react'; import { useCallback, useMemo } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import { Link } from 'react-router-dom'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { blockAccount, unblockAccount, muteAccount, unmuteAccount, } from 'mastodon/actions/accounts'; import { openModal } from 'mastodon/actions/modal'; import { initMuteModal } from 'mastodon/actions/mutes'; import { Avatar } from 'mastodon/components/avatar'; import { Button } from 'mastodon/components/button'; import { FollowersCounter } from 'mastodon/components/counters'; import { DisplayName } from 'mastodon/components/display_name'; import { Dropdown } from 'mastodon/components/dropdown_menu'; import { FollowButton } from 'mastodon/components/follow_button'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; import { ShortNumber } from 'mastodon/components/short_number'; import { Skeleton } from 'mastodon/components/skeleton'; import { VerifiedBadge } from 'mastodon/components/verified_badge'; import type { MenuItem } from 'mastodon/models/dropdown_menu'; import { useAppSelector, useAppDispatch } from 'mastodon/store'; const messages = defineMessages({ follow: { id: 'account.follow', defaultMessage: 'Follow' }, unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, cancel_follow_request: { id: 'account.cancel_follow_request', defaultMessage: 'Withdraw follow request', }, unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' }, unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' }, mute_notifications: { id: 'account.mute_notifications_short', defaultMessage: 'Mute notifications', }, unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications', }, mute: { id: 'account.mute_short', defaultMessage: 'Mute' }, block: { id: 'account.block_short', defaultMessage: 'Block' }, more: { id: 'status.more', defaultMessage: 'More' }, addToLists: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists', }, openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page', }, }); export const Account: React.FC<{ size?: number; id: string; hidden?: boolean; minimal?: boolean; defaultAction?: 'block' | 'mute'; withBio?: boolean; hideButtons?: boolean; children?: ReactNode; }> = ({ id, size = 46, hidden, minimal, defaultAction, withBio, hideButtons, children, }) => { const intl = useIntl(); const account = useAppSelector((state) => state.accounts.get(id)); const relationship = useAppSelector((state) => state.relationships.get(id)); const dispatch = useAppDispatch(); const accountUrl = account?.url; const handleBlock = useCallback(() => { if (relationship?.blocking) { dispatch(unblockAccount(id)); } else { dispatch(blockAccount(id)); } }, [dispatch, id, relationship]); const handleMute = useCallback(() => { if (relationship?.muting) { dispatch(unmuteAccount(id)); } else { dispatch(initMuteModal(account)); } }, [dispatch, id, account, relationship]); const menu = useMemo(() => { let arr: MenuItem[] = []; if (defaultAction === 'mute') { const handleMuteNotifications = () => { dispatch(muteAccount(id, true)); }; const handleUnmuteNotifications = () => { dispatch(muteAccount(id, false)); }; arr = [ { text: intl.formatMessage( relationship?.muting_notifications ? messages.unmute_notifications : messages.mute_notifications, ), action: relationship?.muting_notifications ? handleUnmuteNotifications : handleMuteNotifications, }, ]; } else if (defaultAction !== 'block') { const handleAddToLists = () => { dispatch( openModal({ modalType: 'LIST_ADDER', modalProps: { accountId: id, }, }), ); }; arr = [ { text: intl.formatMessage(messages.addToLists), action: handleAddToLists, }, ]; if (accountUrl) { arr.unshift( { text: intl.formatMessage(messages.openOriginalPage), href: accountUrl, }, null, ); } } return arr; }, [dispatch, intl, id, accountUrl, relationship, defaultAction]); if (hidden) { return ( <> {account?.display_name} {account?.username} ); } let button: React.ReactNode, dropdown: React.ReactNode; if (menu.length > 0) { dropdown = ( ); } if (defaultAction === 'block') { button = (