2017-05-03 03:04:16 +03:00
import React from 'react' ;
2017-08-28 23:23:44 +03:00
import PropTypes from 'prop-types' ;
2016-11-20 20:39:18 +02:00
import ImmutablePropTypes from 'react-immutable-proptypes' ;
import StatusContainer from '../../../containers/status_container' ;
import AccountContainer from '../../../containers/account_container' ;
2018-08-26 18:53:26 +03:00
import { injectIntl , FormattedMessage } from 'react-intl' ;
2016-12-02 16:05:50 +02:00
import Permalink from '../../../components/permalink' ;
2017-05-03 03:04:16 +03:00
import ImmutablePureComponent from 'react-immutable-pure-component' ;
2017-10-06 02:07:59 +03:00
import { HotKeys } from 'react-hotkeys' ;
2016-11-20 20:39:18 +02:00
2018-08-26 18:53:26 +03:00
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 ( ', ' ) ;
} ;
2018-09-14 18:59:48 +03:00
export default @ injectIntl
class Notification extends ImmutablePureComponent {
2016-11-20 20:39:18 +02:00
2017-10-06 02:07:59 +03:00
static contextTypes = {
router : PropTypes . object ,
} ;
2017-05-12 15:44:10 +03:00
static propTypes = {
2017-05-20 18:31:47 +03:00
notification : ImmutablePropTypes . map . isRequired ,
2017-08-28 23:23:44 +03:00
hidden : PropTypes . bool ,
2017-10-06 02:07:59 +03:00
onMoveUp : PropTypes . func . isRequired ,
onMoveDown : PropTypes . func . isRequired ,
onMention : PropTypes . func . isRequired ,
2018-08-26 18:53:26 +03:00
intl : PropTypes . object . isRequired ,
2017-05-12 15:44:10 +03:00
} ;
2017-10-06 02:07:59 +03:00
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 ( ` /statuses/ ${ notification . get ( 'status' ) } ` ) ;
} else {
this . handleOpenProfile ( ) ;
}
}
handleOpenProfile = ( ) => {
const { notification } = this . props ;
this . context . router . history . push ( ` /accounts/ ${ notification . getIn ( [ 'account' , 'id' ] ) } ` ) ;
}
handleMention = e => {
e . preventDefault ( ) ;
const { notification , onMention } = this . props ;
onMention ( notification . get ( 'account' ) , this . context . router . history ) ;
}
getHandlers ( ) {
return {
moveUp : this . handleMoveUp ,
moveDown : this . handleMoveDown ,
open : this . handleOpen ,
openProfile : this . handleOpenProfile ,
mention : this . handleMention ,
reply : this . handleMention ,
} ;
}
2018-08-26 18:53:26 +03:00
renderFollow ( notification , account , link ) {
const { intl } = this . props ;
2016-11-20 20:39:18 +02:00
return (
2017-10-06 02:07:59 +03:00
< HotKeys handlers = { this . getHandlers ( ) } >
2018-08-26 18:53:26 +03:00
< 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' ) ) } >
2017-10-06 02:07:59 +03:00
< div className = 'notification__message' >
< div className = 'notification__favourite-icon-wrapper' >
< i className = 'fa fa-fw fa-user-plus' / >
< / d i v >
< FormattedMessage id = 'notification.follow' defaultMessage = '{name} followed you' values = { { name : link } } / >
2016-12-02 15:52:41 +02:00
< / d i v >
2017-10-06 02:07:59 +03:00
< AccountContainer id = { account . get ( 'id' ) } withNote = { false } hidden = { this . props . hidden } / >
2016-12-02 15:52:41 +02:00
< / d i v >
2017-10-06 02:07:59 +03:00
< / H o t K e y s >
2016-11-20 20:39:18 +02:00
) ;
2017-04-21 21:05:35 +03:00
}
2016-11-20 20:39:18 +02:00
renderMention ( notification ) {
2017-10-06 02:07:59 +03:00
return (
< StatusContainer
id = { notification . get ( 'status' ) }
withDismiss
hidden = { this . props . hidden }
onMoveDown = { this . handleMoveDown }
onMoveUp = { this . handleMoveUp }
2018-07-07 20:31:19 +03:00
contextType = 'notifications'
2017-10-06 02:07:59 +03:00
/ >
) ;
2017-04-21 21:05:35 +03:00
}
2016-11-20 20:39:18 +02:00
renderFavourite ( notification , link ) {
2018-08-26 18:53:26 +03:00
const { intl } = this . props ;
2016-11-20 20:39:18 +02:00
return (
2017-10-06 02:07:59 +03:00
< HotKeys handlers = { this . getHandlers ( ) } >
2018-08-26 18:53:26 +03:00
< 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' ) ) } >
2017-10-06 02:07:59 +03:00
< div className = 'notification__message' >
< div className = 'notification__favourite-icon-wrapper' >
< i className = 'fa fa-fw fa-star star-icon' / >
< / d i v >
< FormattedMessage id = 'notification.favourite' defaultMessage = '{name} favourited your status' values = { { name : link } } / >
2016-12-02 15:52:41 +02:00
< / d i v >
2017-10-06 02:07:59 +03:00
< StatusContainer id = { notification . get ( 'status' ) } account = { notification . get ( 'account' ) } muted withDismiss hidden = { ! ! this . props . hidden } / >
< / d i v >
< / H o t K e y s >
2016-11-20 20:39:18 +02:00
) ;
2017-04-21 21:05:35 +03:00
}
2016-11-20 20:39:18 +02:00
renderReblog ( notification , link ) {
2018-08-26 18:53:26 +03:00
const { intl } = this . props ;
2016-11-20 20:39:18 +02:00
return (
2017-10-06 02:07:59 +03:00
< HotKeys handlers = { this . getHandlers ( ) } >
2018-08-26 18:53:26 +03:00
< 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' ) ) } >
2017-10-06 02:07:59 +03:00
< div className = 'notification__message' >
< div className = 'notification__favourite-icon-wrapper' >
< i className = 'fa fa-fw fa-retweet' / >
< / d i v >
< FormattedMessage id = 'notification.reblog' defaultMessage = '{name} boosted your status' values = { { name : link } } / >
2016-12-02 15:52:41 +02:00
< / d i v >
2017-10-06 02:07:59 +03:00
< StatusContainer id = { notification . get ( 'status' ) } account = { notification . get ( 'account' ) } muted withDismiss hidden = { this . props . hidden } / >
< / d i v >
< / H o t K e y s >
2016-11-20 20:39:18 +02:00
) ;
2017-04-21 21:05:35 +03:00
}
2016-11-20 20:39:18 +02:00
2017-06-11 11:42:42 +03:00
render ( ) {
2016-11-20 20:39:18 +02:00
const { notification } = this . props ;
const account = notification . get ( 'account' ) ;
2017-08-07 21:32:03 +03:00
const displayNameHtml = { _ _html : account . get ( 'display_name_html' ) } ;
2018-01-15 19:55:10 +02:00
const link = < bdi > < Permalink className = 'notification__display-name' href = { account . get ( 'url' ) } title = { account . get ( 'acct' ) } to = { ` /accounts/ ${ account . get ( 'id' ) } ` } dangerouslySetInnerHTML = { displayNameHtml } / > < / b d i > ;
2016-11-20 20:39:18 +02:00
switch ( notification . get ( 'type' ) ) {
2017-04-11 23:53:58 +03:00
case 'follow' :
2018-08-26 18:53:26 +03:00
return this . renderFollow ( notification , account , link ) ;
2017-04-11 23:53:58 +03:00
case 'mention' :
return this . renderMention ( notification ) ;
case 'favourite' :
return this . renderFavourite ( notification , link ) ;
case 'reblog' :
return this . renderReblog ( notification , link ) ;
2016-11-20 20:39:18 +02:00
}
2017-06-11 11:42:42 +03:00
return null ;
2016-11-20 20:39:18 +02:00
}
2017-04-21 21:05:35 +03:00
}