Skip to content

Instantly share code, notes, and snippets.

@jjdp
Created April 3, 2019 06:41
Show Gist options
  • Save jjdp/51e817fd5b7c8f3038f09e3434427388 to your computer and use it in GitHub Desktop.
Save jjdp/51e817fd5b7c8f3038f09e3434427388 to your computer and use it in GitHub Desktop.
PhotoView
// @flow
import React, { Component } from 'react';
import {
View,
Dimensions,
Text,
TouchableOpacity,
Image
} from 'react-native';
import { connect } from 'react-redux';
import { Icon } from 'react-native-elements';
import Spinner from 'react-native-spinkit';
import Swiper from 'react-native-swiper';
import ImageZoom from 'react-native-image-pan-zoom';
import { deletePhoto } from '../../actions/GalleryActions';
import { hasInternet } from '../../utils';
import { moderateScale, verticalScale } from '../../utils/scaler';
import { HEADER_HEIGHT } from '../../utils/index';
import styles from './styles';
import CommonStyles from '../../styles/CommonStyles';
const { height, width } = Dimensions.get('window');
const imageWidth = width - moderateScale(50);
const imageHeight1 = height / 1.3;
const imageHeight2 = height - HEADER_HEIGHT - verticalScale(30);
type Props = {
navigation: Object,
connectionInfo: Object,
deletePhoto: Function
};
type State = {
photoIndex: number,
loadedIndexes: Array<number>
};
class _PhotoView extends Component<Props, State> {
constructor(props) {
super(props);
const params = this.props.navigation.state.params;
this.itemArray = params.itemArray;
this.photoIndex = params.photoIndex;
this.isInstagram = params.isInstagram;
this.uri = params.uri;
this.state = {
photoIndex: this.photoIndex,
loadedIndexes: []
};
}
itemArray: Array<number>
photoIndex: number
isInstagram: boolean
uri: string
swiper: typeof Swiper
static navigationOptions = ({navigation}) => {
const params = navigation.state.params;
let headerRight = (
<Icon
name="delete"
color="white"
size={moderateScale(26)}
containerStyle={styles.trashIcon}
component={TouchableOpacity}
onPress={() => navigation.setParams({ deletePhoto : true})}
/>
);
return {
headerRight: params && params.showDelete ? headerRight : <View/>,
gesturesEnabled: !(params && params.disableGestures)
};
}
componentDidMount() {
if(this.itemArray)
this.props.navigation.setParams({ disableGestures: true });
}
componentWillReceiveProps(nextProps) {
const params = nextProps.navigation.state.params;
if(params && params.deletePhoto) {
this._onDelete();
}
}
//check instagram api
_getArrayUri = (item: any) => {
if(this.isInstagram) {
if(item.images && item.images.standard_resolution && item.images.standard_resolution.url) {
return item.images.standard_resolution.url;
}
return '';
} else {
return item.attributes.photo;
}
}
_onDelete = () => {
if(hasInternet(this.props.connectionInfo)) {
this.props.deletePhoto(this.itemArray[this.state.photoIndex]).then(() => {
this.props.navigation.goBack();
});
}
}
_renderSpinner = (index) => {
if(this.state.loadedIndexes.indexOf(index) !== -1) {
return null;
} else {
return (
<Spinner
style={{
top: (height / 2 - verticalScale(100)),
left: (width/2 - moderateScale(18)),
position: 'absolute'
}}
color="#E74C3C"
type="ThreeBounce" />
);
}
}
render() {
if(this.itemArray) {
return (
<View
style={styles.container}>
<Swiper
ref={(ref) => this.swiper = ref}
index={this.state.photoIndex}
width={width}
loadMinimal={true}
loadMinimalSize={1}
loop={false}
showsPagination={false}
showsButtons={false}
onIndexChanged={(index) => {
this.setState({
photoIndex: index
});
}}>
{
this.itemArray.map((item, i) => (
<View
key={i}
style={styles.swiperItem}>
{this._renderSpinner(i)}
<ImageZoom
cropWidth={imageWidth}
cropHeight={imageHeight1}
imageWidth={imageWidth}
imageHeight={imageHeight1}>
<Image
onLoad={() => {
this.setState({
loadedIndexes: this.state.loadedIndexes.concat(i)
});
}}
style={{
width: imageWidth,
height: imageHeight1}}
source={{uri: this._getArrayUri(item)}}
resizeMode="contain"
/>
</ImageZoom>
</View>
))
}
</Swiper>
<View
style={styles.buttonWrapper}>
{ this.state.photoIndex === 0 ?
null
:
<TouchableOpacity
onPress={() => this.swiper.scrollBy(-1)}>
<Text
style={[CommonStyles.BoldFont, styles.buttonText]}>
Previous
</Text>
</TouchableOpacity>
}
{ this.state.photoIndex === (this.itemArray.length - 1) ?
null
:
<TouchableOpacity
onPress={() => this.swiper.scrollBy(1)}>
<Text
style={[CommonStyles.BoldFont, styles.buttonText]}>
Next
</Text>
</TouchableOpacity>
}
</View>
</View>
);
} else {
return (
<View
style={styles.container}>
{this._renderSpinner(0)}
<ImageZoom
cropWidth={imageWidth}
cropHeight={imageHeight2}
imageWidth={imageWidth}
imageHeight={imageHeight2}>
<Image
onLoad={() => {
this.setState({
loadedIndexes: [0]
});
}}
style={{
width: imageWidth,
height: imageHeight2}}
source={{uri: this.uri}}
resizeMode="contain"
/>
</ImageZoom>
</View>
);
}
}
}
const mapDispatchToProps = dispatch => ({
deletePhoto: (parseObject) =>
dispatch(deletePhoto(parseObject)),
});
const mapStateToProps = state => ({
connectionInfo: state.generic.connectionInfo,
});
const PhotoView = connect(mapStateToProps, mapDispatchToProps)(_PhotoView);
export default PhotoView;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment