@@ -85,63 +85,112 @@ export default class NotificationList extends Component {
8585 return < div className = "NotificationList-empty" > { app . translator . trans ( 'core.forum.notifications.empty_text' ) } </ div > ;
8686 }
8787
88- return state . getPages ( ) . map ( ( page ) => {
89- const groups = [ ] ;
90- const discussions = { } ;
91-
92- page . items . forEach ( ( notification ) => {
93- const subject = notification . subject ( ) ;
94-
95- if ( typeof subject === 'undefined' ) return ;
96-
97- // Get the discussion that this notification is related to. If it's not
98- // directly related to a discussion, it may be related to a post or
99- // other entity which is related to a discussion.
100- let discussion = null ;
101- if ( subject instanceof Discussion ) discussion = subject ;
102- else if ( subject && subject . discussion ) discussion = subject . discussion ( ) ;
103-
104- // If the notification is not related to a discussion directly or
105- // indirectly, then we will assign it to a neutral group.
106- const key = discussion ? discussion . id ( ) : 0 ;
107- discussions [ key ] = discussions [ key ] || { discussion : discussion , notifications : [ ] } ;
108- discussions [ key ] . notifications . push ( notification ) ;
109-
110- if ( groups . indexOf ( discussions [ key ] ) === - 1 ) {
111- groups . push ( discussions [ key ] ) ;
112- }
113- } ) ;
114-
115- return groups . map ( ( group ) => {
116- const badges = group . discussion && group . discussion . badges ( ) . toArray ( ) ;
117-
118- return (
119- < div className = "NotificationGroup" >
120- { group . discussion ? (
121- < Link className = "NotificationGroup-header" href = { app . route . discussion ( group . discussion ) } >
122- { badges && ! ! badges . length && < ul className = "NotificationGroup-badges badges" > { listItems ( badges ) } </ ul > }
123- < span > { group . discussion . title ( ) } </ span >
124- </ Link >
125- ) : (
126- < div className = "NotificationGroup-header" > { this . groupTitle ( group ) } </ div >
127- ) }
128-
129- < ul className = "NotificationGroup-content" >
130- { group . notifications . map ( ( notification ) => {
131- const NotificationComponent = app . notificationComponents [ notification . contentType ( ) ] ;
132- return (
133- ! ! NotificationComponent && (
134- < li >
135- < NotificationComponent notification = { notification } />
136- </ li >
137- )
138- ) ;
139- } ) }
140- </ ul >
141- </ div >
142- ) ;
143- } ) ;
88+ return state . getPages ( ) . flatMap ( ( page ) => this . pageItems ( page ) . toArray ( ) ) ;
89+ }
90+
91+ pageItems ( page ) {
92+ const items = new ItemList ( ) ;
93+
94+ const groups = this . buildGroups ( page ) ;
95+
96+ groups . forEach ( ( group , index ) => {
97+ items . add ( `group-${ index } ` , this . groupView ( group ) , - index ) ;
14498 } ) ;
99+
100+ return items ;
101+ }
102+
103+ buildGroups ( page ) {
104+ const groups = [ ] ;
105+ const discussions = { } ;
106+
107+ page . items . forEach ( ( notification ) => {
108+ const subject = notification . subject ( ) ;
109+ if ( typeof subject === 'undefined' ) return ;
110+
111+ // Get the discussion that this notification is related to. If it's not
112+ // directly related to a discussion, it may be related to a post or
113+ // other entity which is related to a discussion.
114+ let discussion = null ;
115+ if ( subject instanceof Discussion ) discussion = subject ;
116+ else if ( subject && subject . discussion ) discussion = subject . discussion ( ) ;
117+
118+ // If the notification is not related to a discussion directly or
119+ // indirectly, then we will assign it to a neutral group.
120+ const key = discussion ? discussion . id ( ) : 0 ;
121+ discussions [ key ] = discussions [ key ] || { discussion, notifications : [ ] } ;
122+ discussions [ key ] . notifications . push ( notification ) ;
123+
124+ if ( groups . indexOf ( discussions [ key ] ) === - 1 ) {
125+ groups . push ( discussions [ key ] ) ;
126+ }
127+ } ) ;
128+
129+ return groups ;
130+ }
131+
132+ groupKey ( group , fallbackIndex ) {
133+ return group . discussion ? group . discussion . id ( ) : `neutral-${ fallbackIndex } ` ;
134+ }
135+
136+ groupView ( group ) {
137+ const badges = group . discussion && group . discussion . badges ( ) . toArray ( ) ;
138+
139+ const items = this . groupItems ( group , badges ) . toArray ( ) ;
140+
141+ return < div className = "NotificationGroup" > { items } </ div > ;
142+ }
143+
144+ groupItems ( group , badges ) {
145+ const items = new ItemList ( ) ;
146+
147+ items . add ( 'header' , this . groupHeaderItems ( group , badges ) . toArray ( ) [ 0 ] , 100 ) ;
148+
149+ items . add ( 'body' , this . groupBodyItems ( group ) . toArray ( ) [ 0 ] , 90 ) ;
150+
151+ return items ;
152+ }
153+
154+ groupHeaderItems ( group , badges ) {
155+ const items = new ItemList ( ) ;
156+
157+ if ( group . discussion ) {
158+ items . add (
159+ 'discussion' ,
160+ < Link className = "NotificationGroup-header" href = { app . route . discussion ( group . discussion ) } >
161+ { badges && ! ! badges . length && < ul className = "NotificationGroup-badges badges" > { listItems ( badges ) } </ ul > }
162+ < span > { group . discussion . title ( ) } </ span >
163+ </ Link > ,
164+ 100
165+ ) ;
166+ } else {
167+ items . add ( 'neutral' , < div className = "NotificationGroup-header" > { this . groupTitle ( group ) } </ div > , 0 ) ;
168+ }
169+
170+ return items ;
171+ }
172+
173+ groupBodyItems ( group ) {
174+ const items = new ItemList ( ) ;
175+
176+ items . add (
177+ 'list' ,
178+ < ul className = "NotificationGroup-content" > { group . notifications . map ( ( n , i ) => this . notificationItem ( n , i ) ) . filter ( Boolean ) } </ ul > ,
179+ 100
180+ ) ;
181+
182+ return items ;
183+ }
184+
185+ notificationItem ( notification ) {
186+ const NotificationComponent = app . notificationComponents [ notification . contentType ( ) ] ;
187+ if ( ! NotificationComponent ) return null ;
188+
189+ return (
190+ < li >
191+ < NotificationComponent notification = { notification } />
192+ </ li >
193+ ) ;
145194 }
146195
147196 groupTitle ( group ) {
0 commit comments