import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { Link } from 'react-router-dom'; import { fetchEventIcs } from 'soapbox/actions/events'; import { openModal } from 'soapbox/actions/modals'; import { deleteStatusModal, toggleStatusSensitivityModal } from 'soapbox/actions/moderation'; import Icon from 'soapbox/components/icon'; import StillImage from 'soapbox/components/still_image'; import { Button, HStack, IconButton, Menu, MenuButton, MenuDivider, MenuItem, MenuLink, MenuList, Stack, Text } from 'soapbox/components/ui'; import SvgIcon from 'soapbox/components/ui/icon/svg-icon'; import VerificationBadge from 'soapbox/components/verification_badge'; import { useAppDispatch, useOwnAccount } from 'soapbox/hooks'; import { download } from 'soapbox/utils/download'; import { shortNumberFormat } from 'soapbox/utils/numbers'; import PlaceholderEventHeader from '../../placeholder/components/placeholder_event_header'; import EventActionButton from '../components/event-action-button'; import EventDate from '../components/event-date'; import type { Menu as MenuType } from 'soapbox/components/dropdown_menu'; import type { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities'; const messages = defineMessages({ bannerHeader: { id: 'event.banner', defaultMessage: 'Event banner' }, exportIcs: { id: 'event.export_ics', defaultMessage: 'Export to your calendar' }, copy: { id: 'event.copy', defaultMessage: 'Copy link to event' }, bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' }, unbookmark: { id: 'status.unbookmark', defaultMessage: 'Remove bookmark' }, adminAccount: { id: 'status.admin_account', defaultMessage: 'Moderate @{name}' }, adminStatus: { id: 'status.admin_status', defaultMessage: 'Open this post in the moderation interface' }, markStatusSensitive: { id: 'admin.statuses.actions.mark_status_sensitive', defaultMessage: 'Mark post sensitive' }, markStatusNotSensitive: { id: 'admin.statuses.actions.mark_status_not_sensitive', defaultMessage: 'Mark post not sensitive' }, deleteStatus: { id: 'admin.statuses.actions.delete_status', defaultMessage: 'Delete post' }, }); interface IEventHeader { status?: StatusEntity, } const EventHeader: React.FC = ({ status }) => { const intl = useIntl(); const dispatch = useAppDispatch(); const ownAccount = useOwnAccount(); const isStaff = ownAccount ? ownAccount.staff : false; const isAdmin = ownAccount ? ownAccount.admin : false; if (!status || !status.event) { return ( <>
); } const account = status.account as AccountEntity; const event = status.event; const banner = status.media_attachments?.find(({ description }) => description === 'Banner'); const handleHeaderClick: React.MouseEventHandler = (e) => { e.stopPropagation(); const index = status.media_attachments!.findIndex(({ description }) => description === 'Banner'); dispatch(openModal('MEDIA', { media: status.media_attachments, index })); }; const handleExportClick = () => { dispatch(fetchEventIcs(status.id)).then((response) => { download(response, 'calendar.ics'); }).catch(() => {}); }; const handleCopy = () => { const { uri } = status; const textarea = document.createElement('textarea'); textarea.textContent = uri; textarea.style.position = 'fixed'; document.body.appendChild(textarea); try { textarea.select(); document.execCommand('copy'); } catch { // Do nothing } finally { document.body.removeChild(textarea); } }; const handleModerate = () => { dispatch(openModal('ACCOUNT_MODERATION', { accountId: account.id })); }; const handleModerateStatus = () => { window.open(`/pleroma/admin/#/statuses/${status.id}/`, '_blank'); }; const handleToggleStatusSensitivity = () => { dispatch(toggleStatusSensitivityModal(intl, status.id, status.sensitive)); }; const handleDeleteStatus = () => { dispatch(deleteStatusModal(intl, status.id)); }; const menu: MenuType = [ { text: intl.formatMessage(messages.exportIcs), action: handleExportClick, icon: require('@tabler/icons/calendar-plus.svg'), }, { text: intl.formatMessage(messages.copy), action: handleCopy, icon: require('@tabler/icons/link.svg'), }, ]; if (isStaff) { menu.push(null); menu.push({ text: intl.formatMessage(messages.adminAccount, { name: account.username }), action: handleModerate, icon: require('@tabler/icons/gavel.svg'), }); if (isAdmin) { menu.push({ text: intl.formatMessage(messages.adminStatus), action: handleModerateStatus, icon: require('@tabler/icons/pencil.svg'), }); } menu.push({ text: intl.formatMessage(status.sensitive === false ? messages.markStatusSensitive : messages.markStatusNotSensitive), action: handleToggleStatusSensitivity, icon: require('@tabler/icons/alert-triangle.svg'), }); if (account.id !== ownAccount?.id) { menu.push({ text: intl.formatMessage(messages.deleteStatus), action: handleDeleteStatus, icon: require('@tabler/icons/trash.svg'), destructive: true, }); } } const handleManageClick: React.MouseEventHandler = e => { e.stopPropagation(); dispatch(openModal('MANAGE_EVENT', { statusId: status.id, })); }; const handleParticipantsClick: React.MouseEventHandler = e => { e.stopPropagation(); dispatch(openModal('EVENT_PARTICIPANTS', { statusId: status.id, })); }; return ( <>
{banner && ( )}
{event.name} {menu.map((menuItem, idx) => { if (typeof menuItem?.text === 'undefined') { return ; } else { const Comp = (menuItem.action ? MenuItem : MenuLink) as any; const itemProps = menuItem.action ? { onSelect: menuItem.action } : { to: menuItem.to, as: Link, target: menuItem.newTab ? '_blank' : '_self' }; return (
{menuItem.icon && ( )}
{menuItem.text}
); } })}
{account.id === ownAccount?.id ? ( ) : }
{account.verified && } ), }} /> {event.location && ( {event.location.get('name')} )}
); }; export default EventHeader;