1
- import React , { Component , PropTypes } from ' react' ;
1
+ import React , { Component , PropTypes } from " react" ;
2
2
import {
3
3
Animated ,
4
4
Dimensions ,
@@ -9,12 +9,12 @@ import {
9
9
StatusBar ,
10
10
Text ,
11
11
TouchableWithoutFeedback ,
12
- View ,
13
- } from ' react-native' ;
14
- import Icon from ' react-native-vector-icons/Ionicons' ;
12
+ View
13
+ } from " react-native" ;
14
+ import Icon from " react-native-vector-icons/Ionicons" ;
15
15
16
16
// Get screen dimensions
17
- const { width, height } = Dimensions . get ( ' window' ) ;
17
+ const { width, height } = Dimensions . get ( " window" ) ;
18
18
19
19
export default class Drawer extends Component {
20
20
// Define prop types
@@ -28,15 +28,15 @@ export default class Drawer extends Component {
28
28
// Header height
29
29
headerHeight : PropTypes . number ,
30
30
// Height of the visible teaser area at the bottom of the screen
31
- teaserHeight : PropTypes . number ,
31
+ teaserHeight : PropTypes . number
32
32
} ;
33
33
34
34
// Set default prop values
35
35
static defaultProps = {
36
36
isOpen : false ,
37
- header : ' Messages' ,
37
+ header : " Messages" ,
38
38
headerHeight : 70 ,
39
- teaserHeight : 75 ,
39
+ teaserHeight : 75
40
40
} ;
41
41
42
42
// Define state
@@ -46,7 +46,7 @@ export default class Drawer extends Component {
46
46
// Whether the window is being pulled up/down or not
47
47
pulling : false ,
48
48
// Zero means user haven't scrolled the content yet
49
- scrollOffset : 0 ,
49
+ scrollOffset : 0
50
50
} ;
51
51
52
52
// Configure animations
@@ -62,18 +62,18 @@ export default class Drawer extends Component {
62
62
// minimal possible value - a bit lower the top of the screen
63
63
min : this . props . headerHeight ,
64
64
// When animated triggers these value updates
65
- animates : [ ( ) => this . _animatedOpacity , ( ) => this . _animatedWidth ] ,
65
+ animates : [ ( ) => this . _animatedOpacity , ( ) => this . _animatedWidth ]
66
66
} ,
67
67
// Window width
68
68
width : {
69
69
end : width , // takes full with once opened
70
- start : width - 20 , // slightly narrower than screen when closed
70
+ start : width - 20 // slightly narrower than screen when closed
71
71
} ,
72
72
// Window backdrop opacity
73
73
opacity : {
74
74
start : 0 , // fully transparent when closed
75
- end : 1 , // not transparent once opened
76
- } ,
75
+ end : 1 // not transparent once opened
76
+ }
77
77
} ;
78
78
79
79
// Pan responder to handle gestures
@@ -87,18 +87,18 @@ export default class Drawer extends Component {
87
87
88
88
// Animates window position
89
89
_animatedPosition = new Animated . Value (
90
- this . props . isOpen ? this . config . position . end : this . config . position . start ,
90
+ this . props . isOpen ? this . config . position . end : this . config . position . start
91
91
) ;
92
92
93
93
componentWillMount ( ) {
94
94
// Set current position
95
95
this . _currentPosition = this . _animatedPosition . _value ;
96
96
// Listen for this._animatedPosition changes
97
- this . _animatedPosition . addListener ( ( value ) => {
97
+ this . _animatedPosition . addListener ( value => {
98
98
// Update _currentPosition
99
99
this . _currentPosition = value . value ;
100
100
// Animate depending values
101
- this . config . position . animates . map ( ( item ) => {
101
+ this . config . position . animates . map ( item => {
102
102
item ( ) . setValue ( value . value ) ;
103
103
} ) ;
104
104
} ) ;
@@ -115,7 +115,7 @@ export default class Drawer extends Component {
115
115
onPanResponderTerminationRequest : ( evt , gestureState ) => true ,
116
116
onPanResponderRelease : this . _handlePanResponderEnd ,
117
117
onPanResponderTerminate : this . _handlePanResponderEnd ,
118
- onShouldBlockNativeResponder : ( evt , gestureState ) => true ,
118
+ onShouldBlockNativeResponder : ( evt , gestureState ) => true
119
119
} ) ;
120
120
}
121
121
@@ -135,27 +135,27 @@ export default class Drawer extends Component {
135
135
// Interpolate position value into opacity value
136
136
animatedOpacity = this . _animatedOpacity . interpolate ( {
137
137
inputRange : [ this . config . position . end , this . config . position . start ] ,
138
- outputRange : [ this . config . opacity . end , this . config . opacity . start ] ,
138
+ outputRange : [ this . config . opacity . end , this . config . opacity . start ]
139
139
} ) ,
140
140
// Interpolate position value into width value
141
141
animatedWidth = this . _animatedWidth . interpolate ( {
142
142
inputRange : [
143
143
this . config . position . min , // top of the screen
144
144
this . config . position . start - 50 , // 50 pixels higher than next point
145
145
this . config . position . start , // a bit higher than the bottom of the screen
146
- this . config . position . max , // the bottom of the screen
146
+ this . config . position . max // the bottom of the screen
147
147
] ,
148
148
outputRange : [
149
149
this . config . width . end , // keep max width after next point
150
150
this . config . width . end , // end: max width at 50 pixel higher
151
151
this . config . width . start , // start: min width at the bottom
152
- this . config . width . start , // keep min width before previous point
153
- ] ,
152
+ this . config . width . start // keep min width before previous point
153
+ ]
154
154
} ) ;
155
155
return (
156
156
< Animated . View style = { [ styles . container , this . getContainerStyle ( ) ] } >
157
157
{ /* Use light status bar because we have dark background */ }
158
- < StatusBar barStyle = { ' light-content' } />
158
+ < StatusBar barStyle = { " light-content" } />
159
159
{ /* Backdrop with animated opacity */ }
160
160
< Animated . View style = { [ styles . backdrop , { opacity : animatedOpacity } ] } >
161
161
{ /* Close window when tapped on header */ }
@@ -184,16 +184,16 @@ export default class Drawer extends Component {
184
184
// Animate position on the screen
185
185
transform : [
186
186
{ translateY : this . _animatedPosition } ,
187
- { translateX : 0 } ,
188
- ] ,
189
- } ,
187
+ { translateX : 0 }
188
+ ]
189
+ }
190
190
] }
191
191
// Handle gestures
192
192
{ ...this . _panResponder . panHandlers }
193
193
>
194
194
{ /* Put all content in a scrollable container */ }
195
195
< ScrollView
196
- ref = { ( scrollView ) => {
196
+ ref = { scrollView => {
197
197
this . _scrollView = scrollView ;
198
198
} }
199
199
// Enable scrolling only when the window is open
@@ -249,6 +249,7 @@ export default class Drawer extends Component {
249
249
250
250
// Called when gesture ended
251
251
_handlePanResponderEnd = ( evt , gestureState ) => {
252
+ console . log ( gestureState ) ;
252
253
// Reset offset
253
254
this . _animatedPosition . flattenOffset ( ) ;
254
255
// Reset pulling state
@@ -262,20 +263,25 @@ export default class Drawer extends Component {
262
263
} else if ( this . tapped ( gestureState ) ) {
263
264
// Toggle if tapped
264
265
return this . toggle ( ) ;
266
+ } else if ( this . down ( gestureState ) ) {
267
+ // Toggle if tapped
268
+ return this . toggle ( ) ;
265
269
}
266
270
// Restore back to appropriate position otherwise
267
271
this . restore ( ) ;
268
272
} ;
269
273
270
274
// Handle content scrolling
271
- _handleScroll = ( event ) => {
275
+ _handleScroll = event => {
272
276
const { y } = event . nativeEvent . contentOffset ;
273
277
this . setState ( { scrollOffset : y } ) ;
274
278
} ;
275
279
276
280
// Check if gesture was a tap
277
281
tapped = gestureState => gestureState . dx === 0 && gestureState . dy === 0 ;
278
282
283
+ down = gestureState => gestureState . dy > 0 ;
284
+
279
285
// Check if pulled up
280
286
pulledUp = gestureState => gestureState . dy < 0 ;
281
287
@@ -298,7 +304,7 @@ export default class Drawer extends Component {
298
304
this . setState ( { open : true } , ( ) => {
299
305
Animated . timing ( this . _animatedPosition , {
300
306
toValue : this . config . position . end ,
301
- duration : 400 ,
307
+ duration : 400
302
308
} ) . start ( ) ;
303
309
} ) ;
304
310
} ;
@@ -308,10 +314,10 @@ export default class Drawer extends Component {
308
314
this . _scrollView . scrollTo ( { y : 0 } ) ;
309
315
Animated . timing ( this . _animatedPosition , {
310
316
toValue : this . config . position . start ,
311
- duration : 400 ,
317
+ duration : 400
312
318
} ) . start ( ( ) => {
313
319
this . setState ( {
314
- open : false ,
320
+ open : false
315
321
} ) ;
316
322
317
323
this . _scrollView . scrollTo ( { y : 0 } ) ;
@@ -339,57 +345,57 @@ export default class Drawer extends Component {
339
345
// Get header style
340
346
getHeaderStyle = ( ) => ( {
341
347
height :
342
- Platform . OS === ' ios'
348
+ Platform . OS === " ios"
343
349
? this . props . headerHeight
344
- : this . props . headerHeight - 40 , // compensate for the status bar
350
+ : this . props . headerHeight - 40 // compensate for the status bar
345
351
} ) ;
346
352
347
353
// Get container style
348
354
getContainerStyle = ( ) => ( {
349
355
// Move the view below others if not open or moving
350
356
// to not block gesture handlers on other views
351
- zIndex : this . state . pulling || this . state . open ? 1 : - 1 ,
357
+ zIndex : this . state . pulling || this . state . open ? 1 : - 1
352
358
} ) ;
353
359
}
354
360
355
361
const styles = StyleSheet . create ( {
356
362
// Main container
357
363
container : {
358
364
...StyleSheet . absoluteFillObject , // fill up all screen
359
- alignItems : ' center' , // center children
360
- justifyContent : ' flex-end' , // align popup at the bottom
361
- backgroundColor : ' transparent' , // transparent background
362
- elevation : 999 , // fix android dynamic zindex issue
365
+ alignItems : " center" , // center children
366
+ justifyContent : " flex-end" , // align popup at the bottom
367
+ backgroundColor : " transparent" , // transparent background
368
+ elevation : 999 // fix android dynamic zindex issue
363
369
} ,
364
370
// Semi-transparent background below popup
365
371
backdrop : {
366
372
...StyleSheet . absoluteFillObject , // fill up all screen
367
- alignItems : ' center' , // center children
368
- justifyContent : ' flex-start' , // align popup at the bottom
369
- backgroundColor : ' black' ,
373
+ alignItems : " center" , // center children
374
+ justifyContent : " flex-start" , // align popup at the bottom
375
+ backgroundColor : " black"
370
376
} ,
371
377
// Body
372
378
content : {
373
- backgroundColor : ' black' ,
374
- height,
379
+ backgroundColor : " black" ,
380
+ height
375
381
} ,
376
382
// Header
377
383
header : {
378
- flexDirection : ' row' , // arrange children in a row
379
- alignItems : ' center' , // center vertically
384
+ flexDirection : " row" , // arrange children in a row
385
+ alignItems : " center" , // center vertically
380
386
paddingTop : 20 ,
381
- paddingHorizontal : 20 ,
387
+ paddingHorizontal : 20
382
388
} ,
383
389
headerIcon : {
384
- marginRight : 10 ,
390
+ marginRight : 10
385
391
} ,
386
392
headerTitle : {
387
- flex : 1 , // take up all available space
393
+ flex : 1 // take up all available space
388
394
} ,
389
395
headerText : {
390
- color : ' white' ,
391
- fontFamily : ' Avenir' ,
392
- fontWeight : ' 600' ,
393
- fontSize : 16 ,
394
- } ,
396
+ color : " white" ,
397
+ fontFamily : " Avenir" ,
398
+ fontWeight : " 600" ,
399
+ fontSize : 16
400
+ }
395
401
} ) ;
0 commit comments