@@ -8,8 +8,9 @@ import { Link } from 'react-router-dom'
88import { connect } from 'react-redux'
99import _ from 'lodash'
1010import { getNotifications , visitNotifications , toggleNotificationSeen , markAllNotificationsRead ,
11- toggleNotificationRead , toggleBundledNotificationRead , viewOlderNotifications , toggleNotificationsDropdownMobile } from '../../routes/notifications/actions'
12- import { splitNotificationsBySources , filterReadNotifications , limitQuantityInSources , filterOldNotifications } from '../../routes/notifications/helpers/notifications'
11+ toggleNotificationRead , toggleBundledNotificationRead , viewOlderNotifications ,
12+ toggleNotificationsDropdownMobile , hideOlderNotifications } from '../../routes/notifications/actions'
13+ import { splitNotificationsBySources , filterReadNotifications , limitQuantityInSources } from '../../routes/notifications/helpers/notifications'
1314import NotificationsSection from '../NotificationsSection/NotificationsSection'
1415import NotificationsEmpty from '../NotificationsEmpty/NotificationsEmpty'
1516import NotificationsDropdownHeader from '../NotificationsDropdownHeader/NotificationsDropdownHeader'
@@ -18,21 +19,11 @@ import NotificationsMobilePage from './NotificationsMobilePage'
1819import NotificationsReadAll from './NotificationsReadAll'
1920import ScrollLock from 'react-scroll-lock-component'
2021import MediaQuery from 'react-responsive'
21- import { NOTIFICATIONS_DROPDOWN_PER_SOURCE , NOTIFICATIONS_DROPDOWN_MAX_TOTAL , REFRESH_NOTIFICATIONS_INTERVAL , SCREEN_BREAKPOINT_MD } from '../../config/constants'
22+ import { NOTIFICATIONS_DROPDOWN_PER_SOURCE , NOTIFICATIONS_NEW_PER_SOURCE , REFRESH_NOTIFICATIONS_INTERVAL , SCREEN_BREAKPOINT_MD } from '../../config/constants'
2223import './NotificationsDropdown.scss'
2324
2425class NotificationsDropdownContainer extends React . Component {
2526
26- constructor ( props ) {
27- super ( props )
28-
29- this . state = {
30- isViewAll : false
31- }
32-
33- this . viewAll = this . viewAll . bind ( this )
34- }
35-
3627 componentDidMount ( ) {
3728 this . props . getNotifications ( )
3829 this . autoRefreshNotifications = setInterval ( ( ) => this . props . getNotifications ( ) , REFRESH_NOTIFICATIONS_INTERVAL )
@@ -42,6 +33,7 @@ class NotificationsDropdownContainer extends React.Component {
4233 clearInterval ( this . autoRefreshNotifications )
4334 // hide notifications dropdown for mobile, when this component is unmounted
4435 this . props . toggleNotificationsDropdownMobile ( false )
36+ this . props . hideOlderNotifications ( )
4537 }
4638
4739 componentWillReceiveProps ( nextProps ) {
@@ -52,13 +44,10 @@ class NotificationsDropdownContainer extends React.Component {
5244 // hide notifications dropdown for mobile,
5345 // when this component persist but URL changed
5446 this . props . toggleNotificationsDropdownMobile ( false )
47+ this . props . hideOlderNotifications ( )
5548 }
5649 }
5750
58- viewAll ( ) {
59- this . setState ( { isViewAll : true } )
60- }
61-
6251 render ( ) {
6352 if ( ! this . props . initialized ) {
6453 return < NotificationsDropdown hasUnread = { false } />
@@ -67,10 +56,9 @@ class NotificationsDropdownContainer extends React.Component {
6756 const { lastVisited, sources, notifications, markAllNotificationsRead, toggleNotificationRead, toggleNotificationSeen,
6857 pending, toggleBundledNotificationRead, visitNotifications, oldSourceIds, viewOlderNotifications, isDropdownMobileOpen,
6958 toggleNotificationsDropdownMobile } = this . props
70- const { isViewAll} = this . state
7159 const getPathname = link => link . split ( / [ ? # ] / ) [ 0 ] . replace ( / \/ ? $ / , '' )
7260
73- // mark notifications with url mathc current page's url as seen
61+ // mark notifications with url match current page's url as seen
7462 if ( ! pending ) {
7563 const seenNotificationIds = notifications
7664 . filter ( ( { isRead, seen, goto = '' } ) => ! isRead && ! seen && getPathname ( goto ) === getPathname ( window . location . pathname ) )
@@ -80,26 +68,9 @@ class NotificationsDropdownContainer extends React.Component {
8068 }
8169
8270 const notReadNotifications = filterReadNotifications ( notifications )
83- const notOldNotifications = filterOldNotifications ( notReadNotifications , oldSourceIds )
84- const allNotificationsBySources = splitNotificationsBySources ( sources , notOldNotifications )
85- let notificationsBySources
86-
87- if ( ! isViewAll ) {
88- notificationsBySources = limitQuantityInSources (
89- allNotificationsBySources ,
90- NOTIFICATIONS_DROPDOWN_PER_SOURCE ,
91- NOTIFICATIONS_DROPDOWN_MAX_TOTAL
92- )
93- } else {
94- notificationsBySources = allNotificationsBySources
95- }
96-
97- const hiddenByLimitCount = _ . sumBy ( allNotificationsBySources , 'notifications.length' ) - _ . sumBy ( notificationsBySources , 'notifications.length' )
71+ const allNotificationsBySources = splitNotificationsBySources ( sources , notReadNotifications )
9872
99- const globalSource = notificationsBySources . length > 0 && notificationsBySources [ 0 ] . id === 'global' ? notificationsBySources [ 0 ] : null
100- const projectSources = notificationsBySources . length > 1 && globalSource ? notificationsBySources . slice ( 1 ) : notificationsBySources
10173 const hasUnread = notReadNotifications . length > 0
102- const olderNotificationsCount = notReadNotifications . length - notOldNotifications . length
10374 // we have to give Dropdown component some time
10475 // before removing notification item node from the list
10576 // otherwise dropdown thinks we clicked outside and closes dropdown
@@ -142,92 +113,111 @@ class NotificationsDropdownContainer extends React.Component {
142113
143114 return (
144115 < MediaQuery minWidth = { SCREEN_BREAKPOINT_MD } >
145- { ( matches ) => ( matches ? (
146- < NotificationsDropdown hasUnread = { hasUnread } hasNew = { hasNew } onToggle = { visitNotifications } >
147- < NotificationsDropdownHeader onMarkAllClick = { ( ) => ! pending && markAllNotificationsRead ( ) } hasUnread = { hasUnread } />
148- { ! hasUnread ? (
149- < div className = "notifications-dropdown-body" >
150- { notificationsEmpty }
151- </ div >
152- ) : ( [
153- < ScrollLock key = "body" >
154- < div className = "notifications-dropdown-body" >
155- { globalSource && globalSource . notifications . length &&
156- < NotificationsSection
157- { ...globalSource }
158- isGlobal
159- isSimple
160- onReadToggleClick = { toggleNotificationReadWithDelay }
161- onLinkClick = { markNotificationSeen }
162- />
163- }
164- { projectSources . filter ( source => source . notifications . length > 0 ) . map ( source => (
165- < NotificationsSection
166- { ...source }
167- key = { source . id }
168- isSimple
169- onReadToggleClick = { toggleNotificationReadWithDelay }
170- onLinkClick = { markNotificationSeen }
171- />
172- ) ) }
173- </ div >
174- </ ScrollLock > ,
175- < NotificationsReadAll key = "footer" to = "/notifications" >
176- {
177- olderNotificationsCount > 0 ?
178- `View ${ olderNotificationsCount } older notification${ olderNotificationsCount > 1 ? 's' : '' } ` :
179- 'View all notifications'
180- }
181- </ NotificationsReadAll >
182- ] ) }
183- </ NotificationsDropdown >
184- ) : (
185- < NotificationsMobilePage
186- hasUnread = { hasUnread }
187- hasNew = { hasNew }
188- onToggle = { ( ) => {
189- toggleNotificationsDropdownMobile ( )
190- visitNotifications ( )
191- } }
192- isOpen = { isDropdownMobileOpen }
193- >
194- { ! hasUnread ? (
195- notificationsEmpty
196- ) : (
197- < div >
198- { globalSource && ( globalSource . notifications . length || isViewAll && globalSource . total ) &&
199- < NotificationsSection
200- { ...globalSource }
201- isGlobal
202- isSimple
203- isLoading = { globalSource . isLoading }
204- onReadToggleClick = { toggleNotificationReadWithDelay }
205- onViewOlderClick = { isViewAll ? ( ) => viewOlderNotifications ( globalSource . id ) : null }
206- onLinkClick = { ( notificationId ) => {
207- toggleNotificationsDropdownMobile ( )
208- markNotificationSeen ( notificationId )
209- } }
210- /> }
211- { projectSources . filter ( source => source . notifications . length || isViewAll && source . total ) . map ( source => (
212- < NotificationsSection
213- { ...source }
214- key = { source . id }
215- isSimple
216- isLoading = { source . isLoading }
217- onReadToggleClick = { toggleNotificationReadWithDelay }
218- onViewOlderClick = { isViewAll ? ( ) => viewOlderNotifications ( source . id ) : null }
219- onLinkClick = { ( notificationId ) => {
220- toggleNotificationsDropdownMobile ( )
221- markNotificationSeen ( notificationId )
222- } }
223- />
224- ) ) }
225- { ! isViewAll && ( olderNotificationsCount > 0 || hiddenByLimitCount > 0 ) &&
226- < NotificationsReadAll onClick = { this . viewAll } > Read all notifications</ NotificationsReadAll > }
227- </ div >
228- ) }
229- </ NotificationsMobilePage >
230- ) ) }
116+ { ( matches ) => {
117+ if ( matches ) {
118+ const notificationsBySources = limitQuantityInSources (
119+ allNotificationsBySources ,
120+ NOTIFICATIONS_DROPDOWN_PER_SOURCE ,
121+ oldSourceIds
122+ )
123+ const hiddenByLimitCount = _ . sumBy ( notificationsBySources , 'total' ) - _ . sumBy ( notificationsBySources , 'notifications.length' )
124+ const globalSource = notificationsBySources . length > 0 && notificationsBySources [ 0 ] . id === 'global' ? notificationsBySources [ 0 ] : null
125+ const projectSources = notificationsBySources . length > 1 && globalSource ? notificationsBySources . slice ( 1 ) : notificationsBySources
126+
127+ return (
128+ < NotificationsDropdown hasUnread = { hasUnread } hasNew = { hasNew } onToggle = { visitNotifications } >
129+ < NotificationsDropdownHeader onMarkAllClick = { ( ) => ! pending && markAllNotificationsRead ( ) } hasUnread = { hasUnread } />
130+ { ! hasUnread ? (
131+ < div className = "notifications-dropdown-body" >
132+ { notificationsEmpty }
133+ </ div >
134+ ) : ( [
135+ < ScrollLock key = "body" >
136+ < div className = "notifications-dropdown-body" >
137+ { globalSource && globalSource . notifications . length &&
138+ < NotificationsSection
139+ { ...globalSource }
140+ isGlobal
141+ isSimple
142+ onReadToggleClick = { toggleNotificationReadWithDelay }
143+ onLinkClick = { markNotificationSeen }
144+ />
145+ }
146+ { projectSources . filter ( source => source . notifications . length > 0 ) . map ( source => (
147+ < NotificationsSection
148+ { ...source }
149+ key = { source . id }
150+ isSimple
151+ onReadToggleClick = { toggleNotificationReadWithDelay }
152+ onLinkClick = { markNotificationSeen }
153+ />
154+ ) ) }
155+ </ div >
156+ </ ScrollLock > ,
157+ < NotificationsReadAll key = "footer" to = "/notifications" >
158+ {
159+ hiddenByLimitCount > 0 ?
160+ `View ${ hiddenByLimitCount } older notification${ hiddenByLimitCount > 1 ? 's' : '' } ` :
161+ 'View all notifications'
162+ }
163+ </ NotificationsReadAll >
164+ ] ) }
165+ </ NotificationsDropdown >
166+ )
167+ } else {
168+ const notificationsBySources = limitQuantityInSources (
169+ allNotificationsBySources ,
170+ NOTIFICATIONS_NEW_PER_SOURCE ,
171+ oldSourceIds
172+ )
173+ const globalSource = notificationsBySources . length > 0 && notificationsBySources [ 0 ] . id === 'global' ? notificationsBySources [ 0 ] : null
174+ const projectSources = notificationsBySources . length > 1 && globalSource ? notificationsBySources . slice ( 1 ) : notificationsBySources
175+
176+ return (
177+ < NotificationsMobilePage
178+ hasUnread = { hasUnread }
179+ hasNew = { hasNew }
180+ onToggle = { ( ) => {
181+ toggleNotificationsDropdownMobile ( )
182+ visitNotifications ( )
183+ } }
184+ isOpen = { isDropdownMobileOpen }
185+ >
186+ { ! hasUnread ? (
187+ notificationsEmpty
188+ ) : (
189+ < div >
190+ { globalSource && globalSource . notifications . length > 0 &&
191+ < NotificationsSection
192+ { ...globalSource }
193+ isGlobal
194+ isSimple
195+ onReadToggleClick = { toggleNotificationReadWithDelay }
196+ onViewOlderClick = { ( ) => viewOlderNotifications ( globalSource . id ) }
197+ onLinkClick = { ( notificationId ) => {
198+ toggleNotificationsDropdownMobile ( )
199+ markNotificationSeen ( notificationId )
200+ } }
201+ /> }
202+ { projectSources . filter ( source => source . notifications . length ) . map ( source => (
203+ < NotificationsSection
204+ { ...source }
205+ key = { source . id }
206+ isSimple
207+ onReadToggleClick = { toggleNotificationReadWithDelay }
208+ onViewOlderClick = { ( ) => viewOlderNotifications ( source . id ) }
209+ onLinkClick = { ( notificationId ) => {
210+ toggleNotificationsDropdownMobile ( )
211+ markNotificationSeen ( notificationId )
212+ } }
213+ />
214+ ) ) }
215+ </ div >
216+ ) }
217+ </ NotificationsMobilePage >
218+ )
219+ }
220+ } }
231221 </ MediaQuery >
232222 )
233223 }
@@ -243,6 +233,7 @@ const mapDispatchToProps = {
243233 toggleNotificationRead,
244234 toggleBundledNotificationRead,
245235 viewOlderNotifications,
236+ hideOlderNotifications,
246237 toggleNotificationsDropdownMobile
247238}
248239
0 commit comments