Skip to content

Instantly share code, notes, and snippets.

@furkancelik
Created September 9, 2017 14:07
Show Gist options
  • Save furkancelik/74d93a3ab5e40c8c2b1f24113fd94429 to your computer and use it in GitHub Desktop.
Save furkancelik/74d93a3ab5e40c8c2b1f24113fd94429 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import {
TouchableHighlight,
TouchableOpacity,
Image,
ImageBackground,
View,
Text,
StatusBar,
ScrollView,
Dimensions,
CameraRoll,
Platform,
FlatList,
Animated,
Button,
MaskedViewIOS,
InteractionManager,
} from 'react-native';
//import { observer, inject } from 'mobx-react/native';
const AFlatList = Animated.createAnimatedComponent(FlatList);
//import Icon from 'react-native-vector-icons/Ionicons';
//import Svg, { LinearGradient, Stop, Rect } from 'react-native-svg';
//import styles from '../../configs/styles';
const { width } = Dimensions.get('window');
class ImageItem extends React.PureComponent {
selectImage(item) {
this.props.selectImage(item);
}
render() {
const { item } = this.props;
return (
<TouchableHighlight onPress={() => this.selectImage(item)}>
<Image
source={{ uri: item.node.image.uri }}
style={{
width: width / 4 - 5,
height: width / 4 - 5,
margin: 2,
borderWidth:
this.props.selectImageItem.node.image.uri === item.node.image.uri
? (width / 4 - 5) / 2
: 0,
borderColor:
this.props.selectImageItem.node.image.uri === item.node.image.uri
? 'rgba(255,255,255,0.4)'
: 'transparent',
}}
/>
</TouchableHighlight>
);
}
}
export default class Picker extends Component {
//static navigationOptions = {
// header: false,
//};
constructor(props) {
super(props);
this.state = {
page: 1,
loading: false,
images: null,
selectImage: null,
};
this.scrollY = new Animated.Value(0);
}
shouldComponentUpdate(nextProps, nextState) {
if (nextState.selectImage !== this.state.selectImage) {
return true;
}
return false;
}
componentWillMount() {
this.fetch();
}
fetch() {
const fetchParams = {
first: 1000,
groupTypes: 'SavedPhotos',
assetType: 'Photos',
};
if (Platform.OS === 'android') {
delete fetchParams.groupTypes;
}
CameraRoll.getPhotos(fetchParams).then(data => this.appendImage(data), e => console.log(e));
}
appendImage(data) {
const allImages = data.edges;
// const images = allImages.slice(0, 100);
// const images = allImages.slice(0, 9);
const images = [...data.edges];
this.setState({ selectImage: data.edges[0], images, allImages, loading: true });
// if (assets.length > 0) {
// newState.lastCursor = data.page_info.end_cursor;
// newState.images = this.state.images.concat(assets);
// newState.dataSource = this.state.dataSource.cloneWithRows(
// this._nEveryRow(newState.images, this.props.imagesPerRow),
// );
// this.setState({ loading: true });
// }
}
setAnimate() {
Animated.timing(this.scrollY, {
toValue: 0,
duration: 300,
useNativeDriver: true,
}).start();
}
selectImage(image) {
this.setState({ selectImage: image }, this.setAnimate());
}
gridRender(color = 'rgba(255,255,255,0.5)', lineSize = 0.5) {
return (
<View style={{ position: 'absolute', zIndex: 1 }}>
<View
style={{
position: 'absolute',
width,
height: lineSize,
backgroundColor: color,
top: width / 3 * 2,
}}
/>
<View
style={{
position: 'absolute',
width,
height: lineSize,
backgroundColor: color,
top: width / 3,
}}
/>
<View
style={{
position: 'absolute',
width: lineSize,
height: width,
backgroundColor: color,
top: 0,
left: width / 3,
}}
/>
<View
style={{
position: 'absolute',
width: lineSize,
height: width,
backgroundColor: color,
top: 0,
left: width / 3 * 2,
}}
/>
</View>
);
}
imageRender(image) {
let imageHeight = width;
let imageWidth = width;
if (image.width > image.height) {
imageHeight = width;
imageWidth = image.width / (image.height / width);
} else {
imageHeight = image.height / (image.width / width);
imageWidth = width;
}
return (
<Image
resizeMode={'contain'}
source={{ uri: image.uri }}
style={{
height: imageHeight,
width: imageWidth,
}}
/>
);
}
render() {
if (!this.state.loading) {
return (
<View>
<Text>Resimler Yükleniyor...</Text>
</View>
);
}
if (this.state.images.length < 1) {
return (
<View>
<Text>Galeride resim bulunamadı!</Text>
</View>
);
}
const imageTranslate = this.scrollY.interpolate({
inputRange: [0, width],
outputRange: [0, -width],
extrapolate: 'clamp',
});
return (
<View style={{ flex: 1, backgroundColor: '#000' }}>
<StatusBar hidden />
<AFlatList
// shouldItemUpdate={(p, s) => {
// console.log(p, s);
// return true;
// }}
// onEndReached={this.appendImage2(100)}
// onEndReachedThreshold={200}
// onEndReachedThreshold={10}
contentContainerStyle={{ marginTop: width + 50, paddingBottom: width + 50 }}
numColumns={4}
keyExtractor={item => item.node.image.uri}
data={this.state.images}
scrollEventThrottle={1}
style={{ flex: 1, backgroundColor: '#000', paddingLeft: 2 }}
onScroll={Animated.event([{ nativeEvent: { contentOffset: { y: this.scrollY } } }], {
useNativeDriver: true,
})}
renderItem={({ item }) =>
(<ImageItem
selectImage={this.selectImage.bind(this)}
selectImageItem={this.state.selectImage}
item={item}
/>)}
/>
<Animated.View
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
backgroundColor: '#000',
overflow: 'hidden',
transform: [{ translateY: imageTranslate }],
}}
>
<View style={{ width, height: 50, backgroundColor: 'red' }}>
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}
>
<View style={{ flex: 0 }}>
<TouchableOpacity
onPress={() => {}}
style={{ paddingTop: 5, paddingLeft: 10, paddingRight: 15 }}
>
<Icon name="ios-close" size={35} color="#FFF" />
</TouchableOpacity>
</View>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text
style={{ flex: 0, color: '#FFF', fontSize: 17, fontWeight: '500', paddingTop: 5 }}
>
Foto Galeri
</Text>
</View>
<View style={{ flex: 0 }}>
<TouchableOpacity
onPress={() => {}}
style={{ paddingTop: 5, paddingLeft: 15, paddingRight: 10 }}
>
<Icon name="ios-checkmark" size={35} color="#FFF" />
</TouchableOpacity>
</View>
</View>
</View>
<View
onStartShouldSetResponder={(e) => {
if (width - 50 <= e.nativeEvent.locationY) {
this.setAnimate();
}
}}
style={{
width,
height: width,
marginBottom: 4,
}}
>
{this.gridRender()}
<MaskedViewIOS
style={{ flex: 1 }}
maskElement={
<View
style={{
flex: 1,
backgroundColor: 'rgba(0,0,0,0.4)',
alignItems: 'center',
justifyContent: 'center',
}}
>
<View
style={{
width,
height: width,
borderRadius: width / 2,
backgroundColor: '#FFF',
}}
/>
</View>
}
>
<ScrollView
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
horizontal
contentContainerStyle={{
alignItems: 'center',
justifyContent: 'center',
}}
>
<ScrollView
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
contentContainerStyle={{
alignItems: 'center',
justifyContent: 'center',
}}
maximumZoomScale={3}
minimumZoomScale={1}
>
{this.imageRender(this.state.selectImage.node.image)}
</ScrollView>
</ScrollView>
</MaskedViewIOS>
</View>
</Animated.View>
</View>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment