import React from 'react'; import { useIntl, MessageDescriptor } from 'react-intl'; import { NotificationStack, NotificationObject, StyleFactoryFn } from 'react-notification'; import { useHistory } from 'react-router-dom'; import { dismissAlert } from 'soapbox/actions/alerts'; import { Button } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch } from 'soapbox/hooks'; import type { Alert } from 'soapbox/reducers/alerts'; /** Portal for snackbar alerts. */ const SnackbarContainer: React.FC = () => { const intl = useIntl(); const history = useHistory(); const dispatch = useAppDispatch(); const alerts = useAppSelector(state => state.alerts); /** Apply i18n to the message if it's an object. */ const maybeFormatMessage = (message: MessageDescriptor | string): string => { switch (typeof message) { case 'string': return message; case 'object': return intl.formatMessage(message); default: return ''; } }; /** Convert a reducer Alert into a react-notification object. */ const buildAlert = (item: Alert): NotificationObject => { // Backwards-compatibility if (item.actionLink) { item = item.set('action', () => history.push(item.actionLink)); } const alert: NotificationObject = { message: maybeFormatMessage(item.message), title: maybeFormatMessage(item.title), key: item.key, className: `notification-bar-${item.severity}`, activeClassName: 'snackbar--active', dismissAfter: item.dismissAfter, style: false, }; if (item.action && item.actionLabel) { // HACK: it's a JSX.Element instead of a string! // react-notification displays it just fine. alert.action = (