2020-05-21 20:37:40 +01:00
import { Fragment } from 'react'
2020-06-10 22:44:38 +01:00
import { withRouter } from 'react-router-dom'
2020-03-04 03:45:16 +00:00
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
2020-05-21 20:37:40 +01:00
import { FormattedMessage } from 'react-intl'
2020-04-08 02:06:59 +01:00
import debounce from 'lodash.debounce'
2020-06-10 22:44:38 +01:00
import throttle from 'lodash.throttle'
2019-08-13 16:54:29 +01:00
import {
expandNotifications ,
scrollTopNotifications ,
dequeueNotifications ,
2020-06-10 22:44:38 +01:00
forceDequeueNotifications ,
2020-04-24 04:17:27 +01:00
} from '../actions/notifications'
import NotificationContainer from '../containers/notification_container'
import ScrollableList from '../components/scrollable_list'
2020-05-21 20:37:40 +01:00
import TimelineQueueButtonHeader from '../components/timeline_queue_button_header'
import Block from '../components/block'
2020-06-13 02:52:26 +01:00
import Account from '../components/account'
2020-07-28 21:11:51 +01:00
import NotificationPlaceholder from '../components/placeholder/notification_placeholder'
2019-08-13 16:54:29 +01:00
2020-04-11 23:29:19 +01:00
const mapStateToProps = ( state ) => ( {
notifications : state . getIn ( [ 'notifications' , 'items' ] ) ,
2020-05-21 20:37:40 +01:00
sortedNotifications : state . getIn ( [ 'notifications' , 'sortedItems' ] ) ,
2019-08-13 16:54:29 +01:00
isLoading : state . getIn ( [ 'notifications' , 'isLoading' ] , true ) ,
hasMore : state . getIn ( [ 'notifications' , 'hasMore' ] ) ,
totalQueuedNotificationsCount : state . getIn ( [ 'notifications' , 'totalQueuedNotificationsCount' ] , 0 ) ,
2020-06-13 02:52:26 +01:00
selectedFilter : state . getIn ( [ 'notifications' , 'filter' , 'active' ] ) ,
2020-03-04 03:45:16 +00:00
} )
2019-08-13 16:54:29 +01:00
2020-06-10 22:44:38 +01:00
const mapDispatchToProps = ( dispatch ) => ( {
onDequeueNotifications ( ) {
dispatch ( dequeueNotifications ( ) )
} ,
onExpandNotifications ( options ) {
if ( ! options ) dispatch ( forceDequeueNotifications ( ) )
dispatch ( expandNotifications ( options ) )
} ,
onScrollTopNotifications ( top ) {
dispatch ( scrollTopNotifications ( top ) )
} ,
} )
2020-02-25 16:04:44 +00:00
export default
2020-06-10 22:44:38 +01:00
@ withRouter
@ connect ( mapStateToProps , mapDispatchToProps )
2019-08-13 16:54:29 +01:00
class Notifications extends ImmutablePureComponent {
static propTypes = {
hasMore : PropTypes . bool ,
2020-06-10 22:44:38 +01:00
isLoading : PropTypes . bool ,
notifications : ImmutablePropTypes . list . isRequired ,
onDequeueNotifications : PropTypes . func . isRequired ,
onExpandNotifications : PropTypes . func . isRequired ,
onScrollTopNotifications : PropTypes . func . isRequired ,
sortedNotifications : ImmutablePropTypes . list . isRequired ,
2019-08-13 16:54:29 +01:00
totalQueuedNotificationsCount : PropTypes . number ,
2020-06-13 02:52:26 +01:00
selectedFilter : PropTypes . string . isRequired ,
2020-03-04 03:45:16 +00:00
}
2019-08-13 16:54:29 +01:00
2020-07-16 05:01:49 +01:00
state = {
changedTabs : false ,
}
2020-05-21 20:37:40 +01:00
componentWillUnmount ( ) {
2020-03-04 03:45:16 +00:00
this . handleLoadOlder . cancel ( )
this . handleScrollToTop . cancel ( )
this . handleScroll . cancel ( )
2020-06-10 22:44:38 +01:00
this . props . onScrollTopNotifications ( false )
2019-08-13 16:54:29 +01:00
}
componentDidMount ( ) {
2020-03-04 03:45:16 +00:00
this . handleDequeueNotifications ( )
2020-06-10 22:44:38 +01:00
this . props . onScrollTopNotifications ( true )
2019-08-13 16:54:29 +01:00
}
2020-07-16 05:01:49 +01:00
componentDidUpdate ( prevProps , prevState ) {
2020-06-10 22:44:38 +01:00
//Check if clicked on "notifications" button, if so, reload
if ( prevProps . location . key !== this . props . location . key &&
prevProps . location . pathname === '/notifications' &&
this . props . location . pathname === '/notifications' ) {
this . handleReload ( )
}
2020-07-16 05:01:49 +01:00
if ( prevProps . selectedFilter !== this . props . selectedFilter ) {
this . setState ( { changedTabs : true } )
}
if ( prevProps . selectedFilter === this . props . selectedFilter && prevState . changedTabs ) {
this . setState ( { changedTabs : false } )
}
2020-06-10 22:44:38 +01:00
}
handleReload = throttle ( ( ) => {
this . props . onExpandNotifications ( )
} , 5000 )
2019-08-13 16:54:29 +01:00
handleLoadOlder = debounce ( ( ) => {
2020-03-04 03:45:16 +00:00
const last = this . props . notifications . last ( )
2020-06-10 22:44:38 +01:00
this . props . onExpandNotifications ( { maxId : last && last . get ( 'id' ) } )
2020-03-04 03:45:16 +00:00
} , 300 , { leading : true } )
2019-08-13 16:54:29 +01:00
handleScrollToTop = debounce ( ( ) => {
2020-06-10 22:44:38 +01:00
this . props . onScrollTopNotifications ( true )
2020-03-04 03:45:16 +00:00
} , 100 )
2019-08-13 16:54:29 +01:00
handleScroll = debounce ( ( ) => {
2020-06-10 22:44:38 +01:00
this . props . onScrollTopNotifications ( false )
2020-03-04 03:45:16 +00:00
} , 100 )
2019-08-13 16:54:29 +01:00
handleDequeueNotifications = ( ) => {
2020-06-10 22:44:38 +01:00
this . props . onDequeueNotifications ( )
2020-03-04 03:45:16 +00:00
}
2019-08-13 16:54:29 +01:00
2020-05-21 20:37:40 +01:00
render ( ) {
2020-03-04 03:45:16 +00:00
const {
2020-05-21 20:37:40 +01:00
sortedNotifications ,
2020-03-04 03:45:16 +00:00
isLoading ,
hasMore ,
2020-05-21 20:37:40 +01:00
totalQueuedNotificationsCount ,
2020-06-13 02:52:26 +01:00
selectedFilter ,
2020-03-04 03:45:16 +00:00
} = this . props
2020-07-16 05:01:49 +01:00
const { changedTabs } = this . state
2020-03-04 03:45:16 +00:00
let scrollableContent = null
2019-08-13 16:54:29 +01:00
2020-07-29 21:40:47 +01:00
if ( isLoading && this . scrollableContent && ! changedTabs ) {
2020-03-04 03:45:16 +00:00
scrollableContent = this . scrollableContent
2020-07-29 21:40:47 +01:00
} else if ( ( sortedNotifications . size > 0 || hasMore ) && selectedFilter !== 'follow' && ! changedTabs ) {
2020-05-21 20:37:40 +01:00
scrollableContent = sortedNotifications . map ( ( item , index ) => (
2019-08-13 16:54:29 +01:00
< NotificationContainer
2020-03-04 03:45:16 +00:00
key = { ` notification- ${ index } ` }
2019-08-13 16:54:29 +01:00
notification = { item }
/ >
2020-03-04 03:45:16 +00:00
) )
2020-07-29 21:40:47 +01:00
} else if ( ( sortedNotifications . size > 0 || hasMore ) && selectedFilter === 'follow' && ! changedTabs ) {
2020-06-13 02:52:26 +01:00
const followNotifications = [ ]
sortedNotifications . forEach ( ( block ) => {
2020-06-13 03:01:13 +01:00
if ( block ) {
const followBlock = block . get ( 'follow' )
if ( followBlock && followBlock . size > 0 ) {
followBlock . forEach ( ( item ) => {
followNotifications . push ( item )
} )
}
}
2020-06-13 02:52:26 +01:00
} )
scrollableContent = followNotifications . map ( ( item , index ) => {
return (
< Account
compact
withBio
key = { ` account- ${ index } ` }
id = { item . get ( 'account' ) }
/ >
)
} )
2019-08-13 16:54:29 +01:00
}
2020-03-04 03:45:16 +00:00
this . scrollableContent = scrollableContent
2019-08-13 16:54:29 +01:00
return (
2020-05-21 20:37:40 +01:00
< Fragment >
2020-03-02 22:26:25 +00:00
< TimelineQueueButtonHeader
onClick = { this . handleDequeueNotifications }
count = { totalQueuedNotificationsCount }
itemType = 'notification'
/ >
2020-03-04 03:45:16 +00:00
< Block >
< ScrollableList
scrollKey = 'notifications'
isLoading = { isLoading }
2020-07-29 21:53:02 +01:00
showLoading = { isLoading && sortedNotifications . size === 0 || changedTabs }
2020-03-04 03:45:16 +00:00
hasMore = { hasMore }
emptyMessage = { < FormattedMessage id = 'empty_column.notifications' defaultMessage = "You don't have any notifications yet. Interact with others to start the conversation." / > }
onLoadMore = { this . handleLoadOlder }
onScrollToTop = { this . handleScrollToTop }
onScroll = { this . handleScroll }
2020-07-28 21:11:51 +01:00
placeholderComponent = { NotificationPlaceholder }
placeholderCount = { 3 }
2020-03-04 03:45:16 +00:00
>
2020-05-21 20:37:40 +01:00
{ scrollableContent }
2020-03-04 03:45:16 +00:00
< / S c r o l l a b l e L i s t >
< / B l o c k >
2020-05-21 20:37:40 +01:00
< / F r a g m e n t >
2020-03-02 22:26:25 +00:00
)
2019-08-13 16:54:29 +01:00
}
}