Skip to content

Instantly share code, notes, and snippets.

@tavriaforever
Created September 29, 2017 11:22
Show Gist options
  • Save tavriaforever/eff61287ddbfdb578aa68d3385ad7247 to your computer and use it in GitHub Desktop.
Save tavriaforever/eff61287ddbfdb578aa68d3385ad7247 to your computer and use it in GitHub Desktop.
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