import React , { useState , useEffect , useRef , useCallback } from 'react' ; import { StyleSheet , View , Image , ScrollView , Dimensions , TouchableOpacity , NativeSyntheticEvent , NativeScrollEvent , } from 'react-native' ; import Loader from '../Loader' ; import { colors } from '../utils' ; export interface dataSourceType { url : string ; onClick ? : ( ) => void ; } export type dotType = 'dot' | 'block' ; export interface SwiperProps { dataSource ? : dataSourceType [ ] ; width ? : number ; height ? : number ; time ? : number ; borderRadius ? : number ; autoplay ? : boolean ; dotStyle ? : dotType ; loading ? : boolean ; } const Swiper = ( porps ) => { const gitwidth = Dimensions . get ( 'window' ) . width ; const { dataSource = [ ] , width = gitwidth , height = 130 , time = 6000 , autoplay = true , borderRadius = 0 , dotStyle = 'dot' , loading = false , } = porps ; let [ curIndex , setCurIndex ] = useState ( 0 ) ; let timer = useRef < NodeJS . Timeout | undefined > ( ) ; const scrollToRef = useRef ( ) ; const autoPlay = useCallback ( ( ) => { clearInterval ( timer . current as unknown as number ) ; timer . current = setInterval ( ( ) => { let index = curIndex + 1 ; if ( curIndex === dataSource . length - 1 ) { index = 0 ; setCurIndex ( 0 ) ; } else { setCurIndex ( curIndex + 1 ) ; } scrollToRef . current . scrollTo ( { x : width * index , y : 0 , animated : true } ) ; } , time ) ; } , [ curIndex ] ) ; useEffect ( ( ) => { if ( autoplay && ! loading ) autoPlay ( ) ; } , [ autoPlay ] ) ; useEffect ( ( ) => { return ( ) => { clearInterval ( timer . current as unknown as number ) ; } ; } , [ ] ) ; const onScrollBeginDrag = ( ) => { if ( autoplay ) clearInterval ( timer . current as unknown as number ) ; } ; const onScrollEndDrag = ( ) => { if ( autoplay ) autoPlay ( ) ; } ; const onMomentumScrollEnd = ( e ) => { e . persist ( ) ; let offSetX = e . nativeEvent . contentOffset . x ; let mentWidth = e . nativeEvent . layoutMeasurement . width ; let page = offSetX / mentWidth ; setCurIndex ( page ) ; } ; const onClickDot = ( index ) => { setCurIndex ( index ) ; scrollToRef . current . scrollTo ( { x : width * index , y : 0 , animated : true } ) ; } ; return ( < Loader loading = { loading } rounded = { 5 } maskColor = "transparent" > < View style = { StyleSheet . flatten ( [ styles . banner , { width , height } ] ) } > < ScrollView ref = { scrollToRef } horizontal = { true } showsHorizontalScrollIndicator = { false } pagingEnabled = { true } onScrollBeginDrag = { onScrollBeginDrag } onScrollEndDrag = { onScrollEndDrag } onMomentumScrollEnd = { onMomentumScrollEnd } > { dataSource . map ( ( item , index ) => { return ( < View key = { index } style = { { width , height } } > < View style = { { padding : 12 } } > < TouchableOpacity activeOpacity = { 1 } onPress = { ( ) => { item . onClick && item . onClick ( ) ; } } > < Image key = { index } style = { StyleSheet . flatten ( [ { borderRadius , width : '100%' , height : '100%' } ] ) } resizeMode = "cover" source = { typeof item . url === 'number' ? item . url : { uri : item . url } } / > < /TouchableOpacity> < /View> < /View>); } ) } < /ScrollView> < View style = { styles . dotBox } > { dataSource . map ( ( _ , index ) => { return ( < TouchableOpacity onPress = { onClickDot . bind ( this , index ) } key = { index } style = { StyleSheet . flatten ( [ dotStyle === 'block' ? styles . block : styles . dot , index === curIndex ? styles . dotSetColor : styles . dotColor , ] ) } / > ) ; } ) } < /View> < /View> < /Loader>); } ; const styles = StyleSheet . create ( { banner : { width : '100%' , position : 'relative' , overflow : 'hidden' , } , dotBox : { width : '100%' , flexDirection : 'row' , alignItems : 'center' , justifyContent : 'center' , position : 'absolute' , bottom : 22 , } , dot : { width : 8 , height : 8 , borderRadius : 4 , marginTop : 0 , marginBottom : 0 , marginLeft : 8 , marginRight : 8 , } , block : { width : 16 , height : 3 , marginTop : 0 , marginBottom : 0 , marginLeft : 8 , marginRight : 8 , } , dotColor : { backgroundColor : colors . white , } , dotSetColor : { backgroundColor : colors . colorsPalette . grey50 , } , } ) ; export default Swiper ;