1
1
import React from 'react' ;
2
- import { View , Keyboard , AppState } from 'react-native' ;
2
+ import {
3
+ Animated , View , Keyboard , AppState , Easing ,
4
+ } from 'react-native' ;
3
5
import PropTypes from 'prop-types' ;
4
6
import _ from 'underscore' ;
5
7
import lodashGet from 'lodash.get' ;
6
8
import { withOnyx } from 'react-native-onyx' ;
7
9
import Text from '../../../components/Text' ;
10
+ import UnreadActionIndicator from '../../../components/UnreadActionIndicator' ;
8
11
import { fetchActions , updateLastReadActionID } from '../../../libs/actions/Report' ;
9
12
import ONYXKEYS from '../../../ONYXKEYS' ;
10
13
import ReportActionItem from './ReportActionItem' ;
@@ -23,6 +26,11 @@ const propTypes = {
23
26
24
27
/* Onyx Props */
25
28
29
+ // List of reports to display
30
+ reports : PropTypes . objectOf ( PropTypes . shape ( {
31
+ reportID : PropTypes . number ,
32
+ } ) ) ,
33
+
26
34
// Array of report actions for this report
27
35
reportActions : PropTypes . objectOf ( PropTypes . shape ( ReportActionPropTypes ) ) ,
28
36
@@ -34,6 +42,7 @@ const propTypes = {
34
42
} ;
35
43
36
44
const defaultProps = {
45
+ reports : { } ,
37
46
reportActions : { } ,
38
47
session : { } ,
39
48
} ;
@@ -46,8 +55,15 @@ class ReportActionsView extends React.Component {
46
55
this . scrollToListBottom = this . scrollToListBottom . bind ( this ) ;
47
56
this . recordMaxAction = this . recordMaxAction . bind ( this ) ;
48
57
this . onVisibilityChange = this . onVisibilityChange . bind ( this ) ;
49
- this . sortedReportActions = this . updateSortedReportActions ( ) ;
58
+ this . setUpUnreadActionIndicator = this . setUpUnreadActionIndicator . bind ( this ) ;
59
+ this . updateSortedReportActions = this . updateSortedReportActions . bind ( this ) ;
60
+
61
+ this . sortedReportActions = [ ] ;
50
62
this . timers = [ ] ;
63
+ this . unreadActionCount = 0 ;
64
+ this . shouldShowNewActionIndicator = true ;
65
+ this . unreadIndicatorOpacity = new Animated . Value ( 1 ) ;
66
+ this . unreadIndicatorTimer = null ;
51
67
52
68
this . state = {
53
69
refetchNeeded : true ,
@@ -121,6 +137,7 @@ class ReportActionsView extends React.Component {
121
137
this . keyboardEvent . remove ( ) ;
122
138
}
123
139
140
+ clearTimeout ( this . unreadIndicatorTimer ) ;
124
141
AppState . removeEventListener ( 'change' , this . onVisibilityChange ) ;
125
142
126
143
_ . each ( this . timers , timer => clearTimeout ( timer ) ) ;
@@ -145,6 +162,35 @@ class ReportActionsView extends React.Component {
145
162
this . setState ( { refetchNeeded} ) ;
146
163
}
147
164
165
+ /**
166
+ * Checks if the unreadActionIndicator should be shown.
167
+ * If it does, starts a timeout for the fading out animation and creates
168
+ * a flag to not show it again if the report is still open
169
+ */
170
+ setUpUnreadActionIndicator ( ) {
171
+ if ( ! this . props . isActiveReport || ! this . shouldShowNewActionIndicator ) {
172
+ return ;
173
+ }
174
+
175
+ this . unreadActionCount = _ . find ( this . props . reports , report => (
176
+ report . reportID === this . props . reportID
177
+ ) ) . unreadActionCount ;
178
+
179
+ if ( this . unreadActionCount > 0 ) {
180
+ this . unreadIndicatorOpacity = new Animated . Value ( 1 ) ;
181
+ this . unreadIndicatorTimer = setTimeout ( ( ) => {
182
+ Animated . timing ( this . unreadIndicatorOpacity , {
183
+ toValue : 0 ,
184
+ duration : 500 ,
185
+ easing : Easing . ease ,
186
+ useNativeDriver : false ,
187
+ } ) . start ( ) ;
188
+ } , 3000 ) ;
189
+ }
190
+
191
+ this . shouldShowNewActionIndicator = false ;
192
+ }
193
+
148
194
/**
149
195
* Updates and sorts the report actions by sequence number
150
196
*/
@@ -239,12 +285,17 @@ class ReportActionsView extends React.Component {
239
285
needsLayoutCalculation,
240
286
} ) {
241
287
return (
242
- < ReportActionItem
243
- action = { item . action }
244
- displayAsGroup = { this . isConsecutiveActionMadeByPreviousActor ( index ) }
245
- onLayout = { onLayout }
246
- needsLayoutCalculation = { needsLayoutCalculation }
247
- />
288
+ < View >
289
+ { this . unreadActionCount > 0 && index === this . unreadActionCount - 1 && (
290
+ < UnreadActionIndicator animatedOpacity = { this . unreadIndicatorOpacity } />
291
+ ) }
292
+ < ReportActionItem
293
+ action = { item . action }
294
+ displayAsGroup = { this . isConsecutiveActionMadeByPreviousActor ( index ) }
295
+ onLayout = { onLayout }
296
+ needsLayoutCalculation = { needsLayoutCalculation }
297
+ />
298
+ </ View >
248
299
) ;
249
300
}
250
301
@@ -263,6 +314,7 @@ class ReportActionsView extends React.Component {
263
314
) ;
264
315
}
265
316
317
+ this . setUpUnreadActionIndicator ( ) ;
266
318
this . updateSortedReportActions ( ) ;
267
319
return (
268
320
< InvertedFlatList
@@ -281,6 +333,9 @@ ReportActionsView.propTypes = propTypes;
281
333
ReportActionsView . defaultProps = defaultProps ;
282
334
283
335
export default withOnyx ( {
336
+ reports : {
337
+ key : ONYXKEYS . COLLECTION . REPORT ,
338
+ } ,
284
339
reportActions : {
285
340
key : ( { reportID} ) => `${ ONYXKEYS . COLLECTION . REPORT_ACTIONS } ${ reportID } ` ,
286
341
canEvict : props => ! props . isActiveReport ,
0 commit comments