react-native-camera-roll-gallery
Version:
An easy and simple to use React Native component to render a custom layout for CameraRoll photos (next update will have videos) and displayed on a custom interactive image viewer for manipulation. Includes animations and support for both iOS and Android.
114 lines (98 loc) • 2.77 kB
JavaScript
import React from "react";
import {
Animated,
TouchableOpacity,
Dimensions
} from "react-native";
import PropTypes from "prop-types";
export default class ImageCell extends React.PureComponent {
static propTypes = {
data: PropTypes.object.isRequired,
index: PropTypes.number.isRequired,
imageId: PropTypes.string.isRequired,
source: PropTypes.any.isRequired,
imageMargin: PropTypes.number.isRequired,
imagesPerRow: PropTypes.number.isRequired,
containerWidth: PropTypes.number,
imageContainerStyle: PropTypes.object,
renderIndividualHeader: PropTypes.func,
renderIndividualFooter: PropTypes.func,
onPressImage: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.state = {
imageLoaded: false
};
var { width } = Dimensions.get("window");
var { imageMargin, imagesPerRow, containerWidth } = this.props;
if (typeof containerWidth !== "undefined") {
width = containerWidth;
}
this.state.imageSize = (width - (imagesPerRow + 1) * imageMargin) / imagesPerRow;
}
componentDidMount() {
Dimensions.addEventListener("change", this.setImageSize);
}
setImageSize = () => {
var { width } = Dimensions.get("window");
var { imageMargin, imagesPerRow, containerWidth } = this.props;
if (typeof containerWidth !== "undefined") {
width = containerWidth;
}
this.setState({
imageSize: (width - (imagesPerRow + 1) * imageMargin) / imagesPerRow
});
}
_onPressImage = async (uri) => {
// Wait for the image to load before reacting to press events
if (this.state.imageLoaded) {
this.props.onPressImage(this.props.imageId, this.props.index);
}
}
componentWillUnmount() {
Dimensions.removeEventListener("change", this.setImageSize);
}
render() {
const {
imageSize
} = this.state;
const {
data, index, source, imageMargin, imagesPerRow,
imageContainerStyle, renderIndividualHeader,
renderIndividualFooter
} = this.props;
const header = (renderIndividualHeader) &&
renderIndividualHeader(data, index);
const footer = (renderIndividualFooter) &&
renderIndividualFooter(data, index);
return (
<TouchableOpacity
style={{
marginTop: imageMargin,
marginLeft: index === 0 || index % imagesPerRow === 0
? imageMargin : imageMargin / 2,
marginRight: (index + 1) % imagesPerRow === 0
? imageMargin : imageMargin / 2
}}
onPress={() => this._onPressImage(source.uri)}
>
{header}
<Animated.Image
onLoad={() => {
this.setState({ imageLoaded: true });
}}
source={source}
resizeMode="cover"
style={{
height: imageSize,
width: imageSize,
backgroundColor: "lightgrey",
...imageContainerStyle
}}
/>
{footer}
</TouchableOpacity>
);
}
}