react-native-ui-blueprint
Version:
To develop pixel perfect apps.
216 lines (210 loc) • 8.44 kB
JavaScript
import { __awaiter } from "tslib";
import React from 'react';
import { ActivityIndicator, Animated, FlatList, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { animateGenericNative } from "./Utils";
/**
* Add guidelines on screen
*/
export default class ImageSelect extends React.PureComponent {
constructor() {
super(...arguments);
this.state = {
loading: true
};
this.animatedLoading = new Animated.Value(1);
this.animatedValue = new Animated.Value(0);
this.getImages = () => __awaiter(this, void 0, void 0, function* () {
let images = [];
if (Array.isArray(this.props.images) && this.props.images.length > 0) {
let localImages = yield Promise.all(this.props.images.map(this.getImageSize));
images = images.concat(localImages);
}
else if (this.props.imagesAsync) {
let asyncImages = yield this.props.imagesAsync();
let imagesAsync = yield Promise.all(asyncImages.map((image) => __awaiter(this, void 0, void 0, function* () {
if (!image.thumb) {
image.thumb = {
uri: image.uri
};
let size = yield this.getImageSize({
uri: image.uri
});
image.width = image.thumb.width = size.width;
image.height = image.thumb.height = size.height;
}
else if (!image.thumb.width || !image.thumb.height) {
let size = yield this.getImageSize({
uri: image.uri
});
image.thumb.width = size.width;
image.thumb.height = size.height;
}
return image;
})));
images = images.concat(imagesAsync);
}
this.setState({
images: images
}, () => {
animateGenericNative(this.animatedLoading, 0, result => {
});
});
});
}
getImageSize(image) {
return __awaiter(this, void 0, void 0, function* () {
if (typeof image === "number") {
let asset = Image.resolveAssetSource(image);
return {
uri: asset.uri,
width: asset.width,
height: asset.height,
thumb: {
uri: asset.uri,
width: asset.width,
height: asset.height
}
};
}
const uri = image.uri;
return new Promise((resolve, reject) => {
Image.getSize(uri, (width, height) => {
resolve({
uri: uri,
width: width,
height: height,
thumb: {
uri: uri,
width: width,
height: height
}
});
}, reject);
});
});
}
componentDidMount() {
return __awaiter(this, void 0, void 0, function* () {
animateGenericNative(this.animatedValue, 1);
this.getImages();
});
}
render() {
const width = this.props.width * 0.35;
return (<Animated.View style={{
position: 'absolute',
left: 0,
right: 0,
bottom: this.props.bottom,
height: this.props.height,
backgroundColor: '#FFF',
borderColor: '#2C2C2C33',
borderTopWidth: StyleSheet.hairlineWidth,
borderBottomWidth: StyleSheet.hairlineWidth,
opacity: this.animatedValue.interpolate({
inputRange: [0, 1, 1.5],
outputRange: [0, 1, 0],
extrapolate: 'clamp'
}),
transform: [
{
translateY: this.animatedValue.interpolate({
inputRange: [0, 1, 1.5],
outputRange: [30, 0, 10],
extrapolate: 'clamp'
})
},
]
}} pointerEvents={'box-none'}>
<Animated.View style={{
flex: 1,
opacity: this.animatedLoading.interpolate({
inputRange: [0, 1],
outputRange: [1, 0]
})
}}>
<FlatList data={this.state.images || []} showsHorizontalScrollIndicator={false} ListEmptyComponent={props => {
return (<View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style={{
fontFamily: 'System',
fontSize: 16,
textAlign: 'left'
}}>
{"There are no images to display"}
</Text>
</View>);
}} contentContainerStyle={{
flex: (this.state.images && this.state.images.length > 0) ? undefined : 1,
paddingLeft: (this.state.images && this.state.images.length > 0) ? width + 5 : 0
}} renderItem={({ item }) => {
return (<TouchableOpacity onPress={() => __awaiter(this, void 0, void 0, function* () {
if (!item.width || !item.height) {
animateGenericNative(this.animatedLoading, 1);
let size = yield this.getImageSize({
uri: item.uri
});
item.width = size.width;
item.height = size.height;
}
animateGenericNative(this.animatedValue, 2, result => {
this.props.onSelect(item);
});
})}>
<View style={{
flex: 1,
backgroundColor: '#18A0FB11',
width: width,
marginRight: 5,
}}>
<Image source={{
uri: item.uri,
height: item.height,
width: item.width
}} style={{
width: width,
height: '100%',
resizeMode: 'contain'
}}/>
{item.title
? (<Text style={{
position: 'absolute',
bottom: 0,
fontFamily: 'System',
fontSize: 9,
textAlign: 'left'
}}>
{item.title}
</Text>)
: null}
</View>
</TouchableOpacity>);
}} horizontal={true} keyExtractor={(item, index) => `${index}`} refreshing={this.state.loading}/>
</Animated.View>
<Animated.View style={{
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
justifyContent: 'center',
backgroundColor: '#FFF',
opacity: this.animatedLoading
}} pointerEvents={'box-none'}>
<ActivityIndicator color={'#18A0FB'} size={'small'}/>
</Animated.View>
<Image source={require('./../assets/shadow.png')} style={{
position: 'absolute',
top: this.props.height - 1 + StyleSheet.hairlineWidth,
width: '100%',
alignSelf: 'center',
resizeMode: 'stretch',
opacity: 0.3
}}/>
</Animated.View>);
}
}
//# sourceMappingURL=ImageSelect.js.map