import PropTypes from "prop-types"; import { injectIntl, FormattedMessage, defineMessages } from "react-intl"; import classNames from "classnames"; import { Link } from "react-router-dom"; import ImmutablePropTypes from "react-immutable-proptypes"; import ImmutablePureComponent from "react-immutable-pure-component"; import { HotKeys } from "react-hotkeys"; import { Icon } from "mastodon/components/icon"; import AccountContainer from "mastodon/containers/account_container"; import StatusContainer from "mastodon/containers/status_container"; import { me } from "mastodon/initial_state"; import FollowRequestContainer from "../containers/follow_request_container"; import Report from "./report"; const messages = defineMessages({ favourite: { id: "notification.favourite", defaultMessage: "{name} favorited your status" }, follow: { id: "notification.follow", defaultMessage: "{name} followed you" }, ownPoll: { id: "notification.own_poll", defaultMessage: "Your poll has ended" }, poll: { id: "notification.poll", defaultMessage: "A poll you have voted in has ended" }, reblog: { id: "notification.reblog", defaultMessage: "{name} boosted your status" }, status: { id: "notification.status", defaultMessage: "{name} just posted" }, update: { id: "notification.update", defaultMessage: "{name} edited a post" }, adminSignUp: { id: "notification.admin.sign_up", defaultMessage: "{name} signed up" }, adminReport: { id: "notification.admin.report", defaultMessage: "{name} reported {target}" }, }); const notificationForScreenReader = (intl, message, timestamp) => { const output = [message]; output.push(intl.formatDate(timestamp, { hour: "2-digit", minute: "2-digit", month: "short", day: "numeric" })); return output.join(", "); }; class Notification extends ImmutablePureComponent { static contextTypes = { router: PropTypes.object, }; static propTypes = { notification: ImmutablePropTypes.map.isRequired, hidden: PropTypes.bool, onMoveUp: PropTypes.func.isRequired, onMoveDown: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, onFavourite: PropTypes.func.isRequired, onReblog: PropTypes.func.isRequired, onToggleHidden: PropTypes.func.isRequired, status: ImmutablePropTypes.map, intl: PropTypes.object.isRequired, getScrollPosition: PropTypes.func, updateScrollBottom: PropTypes.func, cacheMediaWidth: PropTypes.func, cachedMediaWidth: PropTypes.number, unread: PropTypes.bool, }; handleMoveUp = () => { const { notification, onMoveUp } = this.props; onMoveUp(notification.get("id")); }; handleMoveDown = () => { const { notification, onMoveDown } = this.props; onMoveDown(notification.get("id")); }; handleOpen = () => { const { notification } = this.props; if (notification.get("status")) { this.context.router.history.push(`/@${notification.getIn(["status", "account", "acct"])}/${notification.get("status")}`); } else { this.handleOpenProfile(); } }; handleOpenProfile = () => { const { notification } = this.props; this.context.router.history.push(`/@${notification.getIn(["account", "acct"])}`); }; handleMention = e => { e.preventDefault(); const { notification, onMention } = this.props; onMention(notification.get("account"), this.context.router.history); }; handleHotkeyFavourite = () => { const { status } = this.props; if (status) { this.props.onFavourite(status); } }; handleHotkeyBoost = e => { const { status } = this.props; if (status) { this.props.onReblog(status, e); } }; handleHotkeyToggleHidden = () => { const { status } = this.props; if (status) { this.props.onToggleHidden(status); } }; getHandlers () { return { reply: this.handleMention, favourite: this.handleHotkeyFavourite, boost: this.handleHotkeyBoost, mention: this.handleMention, open: this.handleOpen, openProfile: this.handleOpenProfile, moveUp: this.handleMoveUp, moveDown: this.handleMoveDown, toggleHidden: this.handleHotkeyToggleHidden, }; } renderFollow (notification, account, link) { const { intl, unread } = this.props; return (
); } renderFollowRequest (notification, account, link) { const { intl, unread } = this.props; return (
); } renderMention (notification) { return (