Created
September 29, 2017 11:22
-
-
Save tavriaforever/eff61287ddbfdb578aa68d3385ad7247 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import PropTypes from 'prop-types'; | |
import { | |
View, | |
StyleSheet, | |
ActivityIndicator, | |
Dimensions, | |
Platform, | |
} from 'react-native'; | |
import Swiper from 'react-native-swiper'; | |
import { CachedImage } from 'react-native-cached-image'; | |
import styleVars from '../../core/styleVars'; | |
const { width } = Dimensions.get('window'); | |
const height = 300; | |
const styles = StyleSheet.create({ | |
photoSlider: { | |
marginLeft: -12, | |
marginRight: -12, | |
position: 'relative', | |
width, | |
}, | |
photoSlider__pagination: { | |
bottom: 10, | |
}, | |
photoSlider__item: { | |
flex: 1, | |
justifyContent: 'center', | |
alignItems: 'center', | |
width, | |
height, | |
}, | |
photoSlider__image: { | |
width, | |
height, | |
}, | |
photoSlider__spinner: { | |
position: 'absolute', | |
alignSelf: 'center', | |
}, | |
}); | |
const Slide = props => { | |
return ( | |
<View style={[styles.photoSlider__item, { height: props.height }]}> | |
<CachedImage | |
style={styles.photoSlider__image} | |
onLoad={props.loadHandle.bind(null, props.i)} | |
source={{ | |
uri: props.url, | |
width: props.width, | |
height: props.height, | |
}} | |
/> | |
{ | |
!props.loaded && <ActivityIndicator color={styleVars.color.darkBlue} style={styles.photoSlider__spinner} /> | |
} | |
</View> | |
); | |
}; | |
export default class PhotoSlider extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
loadQueue: new Array(this.props.photos.length).fill(0), | |
isLoaded: false, | |
height, | |
}; | |
this.loadHandle = this.loadHandle.bind(this); | |
} | |
static propTypes = { | |
photos: PropTypes.arrayOf(PropTypes.shape({ | |
url: PropTypes.string, | |
})), | |
} | |
static defaultProps = { | |
photos: [], | |
} | |
loadHandle(i) { | |
const loadQueue = this.state.loadQueue; | |
loadQueue[i] = 1; | |
this.setState({ | |
loadQueue, | |
height: height + 1, | |
}); | |
} | |
render() { | |
const { | |
id, | |
style, | |
photos, | |
} = this.props; | |
// Супер грязный хак, триггерим изменение высота для обновления слайдера | |
// по-другому починить не получилось, попробовал много вариантов. | |
// p.s. нравится компонент, хотел оставить. | |
if (Platform.OS === 'android' && !this.state.isLoaded) { | |
setTimeout(() => { | |
this.setState({ | |
isLoaded: true, | |
height: height + 1, | |
}); | |
}, 0); | |
} | |
return ( | |
<Swiper | |
key={id} | |
style={styles.photoSlider__body} | |
showsButtons={false} | |
height={this.state.height} | |
showsPagination={true} | |
rootStyle={[styles.photoSlider, { paddingBottom: photos.length > 1 ? 35 : 0 }]} | |
paginationStyle={styles.photoSlider__pagination} | |
loadMinimal={Platform.OS === 'ios'} | |
dotColor={styleVars.color.grey} | |
activeDotColor={styleVars.color.brandBlue} | |
> | |
{ | |
photos.map((photo, idx) => { | |
return (<Slide | |
height={this.state.height} | |
loadHandle={this.loadHandle} | |
loaded={!!this.state.loadQueue[idx]} | |
url={photo.url} | |
i={idx} | |
key={idx} | |
/>); | |
}) | |
} | |
</Swiper> | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment