1
1
import assign from 'assign-deep' ;
2
2
import React , { Component , PropTypes } from 'react' ;
3
3
import {
4
+ StatusBar ,
4
5
StyleSheet ,
5
6
Text ,
6
7
View ,
@@ -11,6 +12,10 @@ import {
11
12
Platform ,
12
13
} from 'react-native' ;
13
14
import Swiper from 'react-native-swiper' ;
15
+ import DoneButton from './components/DoneButton' ;
16
+ import SkipButton from './components/SkipButton' ;
17
+ import RenderDots from './components/Dots' ;
18
+
14
19
const windowsWidth = Dimensions . get ( 'window' ) . width ;
15
20
const windowsHeight = Dimensions . get ( 'window' ) . height ;
16
21
@@ -62,13 +67,6 @@ const defaulStyles = {
62
67
} ,
63
68
activeDotStyle : {
64
69
backgroundColor : '#fff' ,
65
- width : 13 ,
66
- height : 13 ,
67
- borderRadius : 7 ,
68
- marginLeft : 7 ,
69
- marginRight : 7 ,
70
- marginTop : 7 ,
71
- marginBottom : 7 ,
72
70
} ,
73
71
paginationContainer : {
74
72
position : 'absolute' ,
@@ -189,21 +187,6 @@ export default class AppIntro extends Component {
189
187
}
190
188
191
189
renderPagination = ( index , total , context ) => {
192
- const { activeDotColor, dotColor, rightTextColor, leftTextColor } = this . props ;
193
- const ActiveDot = (
194
- < View
195
- style = { [ this . styles . activeDotStyle , { backgroundColor : activeDotColor } ] }
196
- />
197
- ) ;
198
- const Dot = < View style = { [ this . styles . dotStyle , { backgroundColor : dotColor } ] } /> ;
199
- let dots = [ ] ;
200
- for ( let i = 0 ; i < total ; i ++ ) {
201
- dots . push ( i === index ?
202
- React . cloneElement ( ActiveDot , { key : i } )
203
- :
204
- React . cloneElement ( Dot , { key : i } )
205
- ) ;
206
- }
207
190
let isDoneBtnShow ;
208
191
let isSkipBtnShow ;
209
192
if ( index === total - 1 ) {
@@ -219,91 +202,31 @@ export default class AppIntro extends Component {
219
202
isDoneBtnShow = false ;
220
203
isSkipBtnShow = true ;
221
204
}
222
- let controllBts ;
223
- if ( Platform . OS === 'ios' ) {
224
- controllBts = (
225
- < View style = { this . styles . paginationContainer } >
226
- < Animated . View style = { [ this . styles . btnContainer , {
227
- opacity : this . state . skipFadeOpacity ,
228
- transform : [ {
229
- translateX : this . state . skipFadeOpacity . interpolate ( {
230
- inputRange : [ 0 , 1 ] ,
231
- outputRange : [ 0 , 15 ] ,
232
- } ) ,
233
- } ] ,
234
- } ] }
235
- >
236
- < TouchableOpacity
237
- style = { this . styles . full }
238
- onPress = { isSkipBtnShow ? ( ) => this . props . onSkipBtnClick ( index ) : null }
239
- >
240
- < Text style = { [ this . styles . controllText , { color : leftTextColor } ] } > { this . props . skipBtnLabel } </ Text >
241
- </ TouchableOpacity >
242
- </ Animated . View >
243
- < View style = { this . styles . dotContainer } >
244
- { dots }
245
- </ View >
246
- < View style = { this . styles . btnContainer } >
247
- < Animated . View style = { [ this . styles . full , { height : 0 } , {
248
- opacity : this . state . doneFadeOpacity ,
249
- transform : [ {
250
- translateX : this . state . skipFadeOpacity . interpolate ( {
251
- inputRange : [ 0 , 1 ] ,
252
- outputRange : [ 0 , 20 ] ,
253
- } ) ,
254
- } ] ,
255
- } ] }
256
- >
257
- < View style = { this . styles . full } >
258
- < Text style = { [ this . styles . controllText , {
259
- color : rightTextColor , paddingRight : 30 ,
260
- } ] }
261
- > { this . props . doneBtnLabel } </ Text >
262
- </ View >
263
- </ Animated . View >
264
- < Animated . View style = { [ this . styles . full , { height : 0 } , { opacity : this . state . nextOpacity } ] } >
265
- < TouchableOpacity style = { this . styles . full }
266
- onPress = { isDoneBtnShow ?
267
- this . props . onDoneBtnClick : this . onNextBtnClick . bind ( this , context ) }
268
- >
269
- < Text style = { [ this . styles . nextButtonText , { color : rightTextColor } ] } > { this . props . nextBtnLabel } </ Text >
270
- </ TouchableOpacity >
271
- </ Animated . View >
272
- </ View >
273
- </ View >
274
- ) ;
275
- } else {
276
- controllBts = (
277
- < View style = { this . styles . paginationContainer } >
278
- < View style = { [ this . styles . btnContainer , {
279
- paddingBottom : 5 ,
280
- opacity : isSkipBtnShow ? 1 : 0 ,
281
- } ] }
282
- >
283
- < TouchableOpacity
284
- style = { this . styles . full }
285
- onPress = { isSkipBtnShow ? ( ) => this . props . onSkipBtnClick ( index ) : null }
286
- >
287
- < Text style = { [ this . styles . controllText , { color : leftTextColor } ] } > { this . props . skipBtnLabel } </ Text >
288
- </ TouchableOpacity >
289
- </ View >
290
- < View style = { this . styles . dotContainer } >
291
- { dots }
292
- </ View >
293
- < View style = { [ this . styles . btnContainer , { height : 0 , paddingBottom : 5 } ] } >
294
- < TouchableOpacity style = { this . styles . full }
295
- onPress = { isDoneBtnShow ?
296
- this . props . onDoneBtnClick : this . onNextBtnClick . bind ( this , context ) }
297
- >
298
- < Text style = { [ this . styles . nextButtonText , { color : rightTextColor } ] } >
299
- { isDoneBtnShow ? this . props . doneBtnLabel : this . props . nextBtnLabel }
300
- </ Text >
301
- </ TouchableOpacity >
302
- </ View >
303
- </ View >
304
- ) ;
305
- }
306
- return controllBts ;
205
+ return (
206
+ < View style = { [ this . styles . paginationContainer ] } >
207
+ { this . props . showSkipButton ? < SkipButton
208
+ { ...this . props }
209
+ { ...this . state }
210
+ isSkipBtnShow = { isSkipBtnShow }
211
+ styles = { this . styles }
212
+ onSkipBtnClick = { ( ) => this . props . onSkipBtnClick ( index ) } /> :
213
+ < View style = { this . styles . btnContainer } />
214
+ }
215
+ { this . props . showDots && RenderDots ( index , total , {
216
+ ...this . props ,
217
+ styles : this . styles
218
+ } ) }
219
+ { this . props . showDoneButton ? < DoneButton
220
+ { ...this . props }
221
+ { ...this . state }
222
+ isDoneBtnShow = { isDoneBtnShow }
223
+ styles = { this . styles }
224
+ onNextBtnClick = { this . onNextBtnClick . bind ( this , context ) }
225
+ onDoneBtnClick = { this . props . onDoneBtnClick } /> :
226
+ < View style = { this . styles . btnContainer } />
227
+ }
228
+ </ View >
229
+ ) ;
307
230
}
308
231
309
232
renderBasicSlidePage = ( index , {
@@ -318,10 +241,11 @@ export default class AppIntro extends Component {
318
241
const AnimatedStyle1 = this . getTransform ( index , 10 , level ) ;
319
242
const AnimatedStyle2 = this . getTransform ( index , 0 , level ) ;
320
243
const AnimatedStyle3 = this . getTransform ( index , 15 , level ) ;
244
+ const imgSource = ( typeof img === 'string' ) ? { uri : img } : img ;
321
245
const pageView = (
322
246
< View style = { [ this . styles . slide , { backgroundColor } ] } showsPagination = { false } key = { index } >
323
247
< Animated . View style = { [ this . styles . header , ...AnimatedStyle1 . transform ] } >
324
- < Image style = { imgStyle } source = { { uri : img } } />
248
+ < Image style = { imgStyle } source = { imgSource } />
325
249
</ Animated . View >
326
250
< View style = { this . styles . info } >
327
251
< Animated . View style = { AnimatedStyle2 . transform } >
@@ -361,6 +285,22 @@ export default class AppIntro extends Component {
361
285
return animatedChild ;
362
286
}
363
287
288
+ shadeStatusBarColor ( color , percent ) {
289
+ const first = parseInt ( color . slice ( 1 ) , 16 ) ;
290
+ const black = first & 0x0000FF ;
291
+ const green = first >> 8 & 0x00FF ;
292
+ const percentage = percent < 0 ? percent * - 1 : percent ;
293
+ const red = first >> 16 ;
294
+ const theme = percent < 0 ? 0 : 255 ;
295
+ const finalColor = ( 0x1000000 + ( Math . round ( ( theme - red ) * percentage ) + red ) * 0x10000 + ( Math . round ( ( theme - green ) * percentage ) + green ) * 0x100 + ( Math . round ( ( theme - black ) * percentage ) + black ) ) . toString ( 16 ) . slice ( 1 ) ;
296
+
297
+ return `#${ finalColor } ` ;
298
+ }
299
+
300
+ isToTintStatusBar ( ) {
301
+ return this . props . pageArray && this . props . pageArray . length > 0 && Platform . OS === 'android'
302
+ }
303
+
364
304
render ( ) {
365
305
const childrens = this . props . children ;
366
306
const { pageArray } = this . props ;
@@ -391,13 +331,23 @@ export default class AppIntro extends Component {
391
331
} ) ;
392
332
}
393
333
}
334
+
335
+ if ( this . isToTintStatusBar ( ) ) {
336
+ StatusBar . setBackgroundColor ( this . shadeStatusBarColor ( this . props . pageArray [ 0 ] . backgroundColor , - 0.3 ) , false ) ;
337
+ }
338
+
394
339
return (
395
340
< View >
396
341
{ androidPages }
397
342
< Swiper
398
343
loop = { false }
344
+ index = { this . props . defaultIndex }
399
345
renderPagination = { this . renderPagination }
400
346
onMomentumScrollEnd = { ( e , state ) => {
347
+ if ( this . isToTintStatusBar ( ) ) {
348
+ StatusBar . setBackgroundColor ( this . shadeStatusBarColor ( this . props . pageArray [ state . index ] . backgroundColor , - 0.3 ) , false ) ;
349
+ }
350
+
401
351
this . props . onSlideChange ( state . index , state . total ) ;
402
352
} }
403
353
onScroll = { Animated . event (
@@ -434,6 +384,10 @@ AppIntro.propTypes = {
434
384
PropTypes . element ,
435
385
] ) ,
436
386
customStyles : PropTypes . object ,
387
+ defaultIndex : PropTypes . number ,
388
+ showSkipButton : PropTypes . bool ,
389
+ showDoneButton : PropTypes . bool ,
390
+ showDots : PropTypes . bool ,
437
391
} ;
438
392
439
393
AppIntro . defaultProps = {
@@ -449,4 +403,8 @@ AppIntro.defaultProps = {
449
403
doneBtnLabel : 'Done' ,
450
404
skipBtnLabel : 'Skip' ,
451
405
nextBtnLabel : '›' ,
406
+ defaultIndex : 0 ,
407
+ showSkipButton : true ,
408
+ showDoneButton : true ,
409
+ showDots : true
452
410
} ;
0 commit comments