1 import React
from 'react';
2 import PropTypes
from 'prop-types';
3 import ImmutablePropTypes
from 'react-immutable-proptypes';
4 import StatusContainer
from '../../../containers/status_container';
5 import AccountContainer
from '../../../containers/account_container';
6 import { injectIntl
, FormattedMessage
} from 'react-intl';
7 import Permalink
from '../../../components/permalink';
8 import ImmutablePureComponent
from 'react-immutable-pure-component';
9 import { HotKeys
} from 'react-hotkeys';
11 const notificationForScreenReader
= (intl
, message
, timestamp
) => {
12 const output
= [message
];
14 output
.push(intl
.formatDate(timestamp
, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }));
16 return output
.join(', ');
19 export default @injectIntl
20 class Notification
extends ImmutablePureComponent
{
22 static contextTypes
= {
23 router: PropTypes
.object
,
27 notification: ImmutablePropTypes
.map
.isRequired
,
28 hidden: PropTypes
.bool
,
29 onMoveUp: PropTypes
.func
.isRequired
,
30 onMoveDown: PropTypes
.func
.isRequired
,
31 onMention: PropTypes
.func
.isRequired
,
32 intl: PropTypes
.object
.isRequired
,
35 handleMoveUp
= () => {
36 const { notification
, onMoveUp
} = this.props
;
37 onMoveUp(notification
.get('id'));
40 handleMoveDown
= () => {
41 const { notification
, onMoveDown
} = this.props
;
42 onMoveDown(notification
.get('id'));
46 const { notification
} = this.props
;
48 if (notification
.get('status')) {
49 this.context
.router
.history
.push(`/statuses/${notification.get('status')}`);
51 this.handleOpenProfile();
55 handleOpenProfile
= () => {
56 const { notification
} = this.props
;
57 this.context
.router
.history
.push(`/accounts/${notification.getIn(['account', 'id'])}`);
60 handleMention
= e
=> {
63 const { notification
, onMention
} = this.props
;
64 onMention(notification
.get('account'), this.context
.router
.history
);
69 moveUp: this.handleMoveUp
,
70 moveDown: this.handleMoveDown
,
71 open: this.handleOpen
,
72 openProfile: this.handleOpenProfile
,
73 mention: this.handleMention
,
74 reply: this.handleMention
,
78 renderFollow (notification
, account
, link
) {
79 const { intl
} = this.props
;
82 <HotKeys handlers
={this.getHandlers()}>
83 <div className
='notification notification-follow focusable' tabIndex
='0' aria
-label
={notificationForScreenReader(intl
, intl
.formatMessage({ id: 'notification.follow', defaultMessage: '{name} followed you' }, { name: account
.get('acct') }), notification
.get('created_at'))}>
84 <div className
='notification__message'>
85 <div className
='notification__favourite-icon-wrapper'>
86 <i className
='fa fa-fw fa-user-plus' />
89 <FormattedMessage id
='notification.follow' defaultMessage
='{name} followed you' values
={{ name: link
}} />
92 <AccountContainer id
={account
.get('id')} withNote
={false} hidden
={this.props
.hidden
} />
98 renderMention (notification
) {
101 id
={notification
.get('status')}
103 hidden
={this.props
.hidden
}
104 onMoveDown
={this.handleMoveDown
}
105 onMoveUp
={this.handleMoveUp
}
106 contextType
='notifications'
111 renderFavourite (notification
, link
) {
112 const { intl
} = this.props
;
115 <HotKeys handlers
={this.getHandlers()}>
116 <div className
='notification notification-favourite focusable' tabIndex
='0' aria
-label
={notificationForScreenReader(intl
, intl
.formatMessage({ id: 'notification.favourite', defaultMessage: '{name} favourited your status' }, { name: notification
.getIn(['account', 'acct']) }), notification
.get('created_at'))}>
117 <div className
='notification__message'>
118 <div className
='notification__favourite-icon-wrapper'>
119 <i className
='fa fa-fw fa-star star-icon' />
121 <FormattedMessage id
='notification.favourite' defaultMessage
='{name} favourited your status' values
={{ name: link
}} />
124 <StatusContainer id
={notification
.get('status')} account
={notification
.get('account')} muted withDismiss hidden
={!!this.props
.hidden
} />
130 renderReblog (notification
, link
) {
131 const { intl
} = this.props
;
134 <HotKeys handlers
={this.getHandlers()}>
135 <div className
='notification notification-reblog focusable' tabIndex
='0' aria
-label
={notificationForScreenReader(intl
, intl
.formatMessage({ id: 'notification.reblog', defaultMessage: '{name} boosted your status' }, { name: notification
.getIn(['account', 'acct']) }), notification
.get('created_at'))}>
136 <div className
='notification__message'>
137 <div className
='notification__favourite-icon-wrapper'>
138 <i className
='fa fa-fw fa-retweet' />
140 <FormattedMessage id
='notification.reblog' defaultMessage
='{name} boosted your status' values
={{ name: link
}} />
143 <StatusContainer id
={notification
.get('status')} account
={notification
.get('account')} muted withDismiss hidden
={this.props
.hidden
} />
150 const { notification
} = this.props
;
151 const account
= notification
.get('account');
152 const displayNameHtml
= { __html: account
.get('display_name_html') };
153 const link
= <bdi
><Permalink className
='notification__display-name' href
={account
.get('url')} title
={account
.get('acct')} to
={`/accounts/${account.get('id')}`} dangerouslySetInnerHTML
={displayNameHtml
} /></bdi
>;
155 switch(notification
.get('type')) {
157 return this.renderFollow(notification
, account
, link
);
159 return this.renderMention(notification
);
161 return this.renderFavourite(notification
, link
);
163 return this.renderReblog(notification
, link
);