imgView.js 10.5 KB
/**
 * Created by Cassie on 18/06/15
 */
import React, {Component} from "react";
import {
    Image,
    StyleSheet,
    Text,
    TouchableOpacity,
    View,
    InteractionManager,
    Animated,
    CameraRoll,
    Modal
} from "react-native";
import Carousel from "react-native-looped-carousel";
import RNFS from "react-native-fs";

import {width, height, zoomW, zoomH} from "../../utils/getSize";
import {getTopHeight,NoDoublePress} from "../../utils/utils";

const del = require('../../img/close.png');
const ddd = require('../../img/ddd.png');
const done = require('../../img/done.png');

export default class ImgView extends Component {
    constructor(props) {
        super(props);
        this.state = {
            imgList:[],
            currentIndex:0,
            picBottom: new Animated.Value(-(320 / zoomH)),
            download: false,
            startDown: false,
            downloadProgress:0
        };
    }

    /*保存图片*/
    savePic() {
        Animated.timing(this.state.picBottom, {toValue: -(320 / zoomH)}).start();
        InteractionManager.runAfterInteractions(() => {
            this.setState({
                startDown: true,
                download: false,
                downloadProgress: 0
            });
            let currentIndex = this.currentIndex ?  this.currentIndex:this.props.currentIndex;
            const filePath = this.props.imgList[currentIndex].filePath;
            const downloadPath = filePath + '?x-oss-process=image/resize,w_1000';
            const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);
            const downloadDest = RNFS.CachesDirectoryPath + '/' + fileName;

            console.log(filePath);

            try {
                RNFS.downloadFile({
                    fromUrl: downloadPath,
                    toFile: downloadDest,
                    background: true,
                    progress: (progress) => {
                        this.setState({
                            downloadProgress: parseInt((progress.bytesWritten / progress.contentLength) * 100)
                        })
                    }
                }).promise.then((response) => {
                    this.setState({
                        download: true
                    }, function () {
                    setTimeout(() => {
                        this.setState({
                            startDown: false,
                            download: false
                        })
                    }, 1000)
                });
                return CameraRoll.saveToCameraRoll(downloadDest, 'photo');
            }).catch((error) => {
                    this.setState({
                        startDown: false
                    });
                    console.log(error);
                    alert('保存图片出错,请稍后再试')
                });
            } catch (error) {
                this.setState({
                    startDown: false
                });
                alert(JSON.stringify(error))
            }
        })
    };

    componentWillUnmount(){
        this.setState = (state, callback) => {
            return;
        };
    };

    render(){
        return (
            <View style={styles.background}>
                <TouchableOpacity activeOpacity={1} style={styles.viewBg} onPress={() => this.props.closePic()}>
                    <View style={{
                        width: width,
                        height: getTopHeight(),
                        display: 'flex',
                        flexDirection: 'row',
                        alignItems: 'center',
                        position: 'absolute',
                        top: 0
                    }}>
                        <TouchableOpacity activeOpacity={0.8} style={{
                            height: '100%',
                            display: 'flex',
                            justifyContent: 'center',
                            paddingLeft: (15 / zoomW),
                            paddingRight: (38 / zoomW)
                        }} onPress={() => NoDoublePress.onPress(() => this.props.closePic())}>
                            <Image source={del} style={{width: (12 / zoomW), height: (12 / zoomH)}}
                                   resizeMode="contain"/>
                        </TouchableOpacity>
                        <View style={{flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center'}} />
                        {this.props.savePic ?
                            <TouchableOpacity activeOpacity={0.8} style={{
                                height: '100%',
                                display: 'flex',
                                justifyContent: 'center',
                                paddingLeft: (20 / zoomW),
                                paddingRight: (15 / zoomW)
                            }}
                                              onPress={() => NoDoublePress.onPress(() => Animated.timing(this.state.picBottom, {toValue: 0,duration:350}).start())}>
                                <Image source={ddd} style={{width: (30 / zoomW), height: (20 / zoomH)}}
                                       resizeMode="contain"/>
                            </TouchableOpacity>
                            :
                            <View style={{width: (65 / zoomW)}}/>
                        }
                    </View>
                    <Carousel
                        style={{height: height - (getTopHeight()), width: width, paddingBottom: getTopHeight()}}
                        bullets={false}
                        isLooped={false}
                        autoplay={false}
                        currentPage={this.props.currentIndex}
                        onAnimateNextPage={(index) => this.currentIndex = index}
                        >
                        {this.props.imgList.map((item, index) =>
                            <TouchableOpacity activeOpacity={1} key={index} style={{
                                width: width,
                                height: (height - 2 * (getTopHeight())),
                                display: 'flex',
                                justifyContent: 'center',
                                alignItems: 'center'
                            }} onLongPress={() =>
                                __ANDROID__ ? Animated.timing(this.state.picBottom, {toValue: 0,duration:350}).start():null
                            }>
                                <Image
                                    source={{uri: item.filePath ? item.filePath + '?x-oss-process=image/resize,w_500' : item.storagePath + '?x-oss-process=image/resize,w_500'}}
                                    style={{width: width, height: height - (getTopHeight())}} resizeMode="contain"/>
                            </TouchableOpacity>
                        )}
                    </Carousel>
                </TouchableOpacity>
                {this.props.savePic && this.state.startDown && <View style={{
                    height: height - (getTopHeight()),
                    width: width,
                    paddingBottom: getTopHeight(),
                    backgroundColor: 'rgba(0,0,0,0)',
                    position: 'absolute',
                    top: getTopHeight(),
                    display: 'flex',
                    justifyContent: 'center',
                    alignItems: 'center'
                }}>
                    <View style={[styles.loadingBox, {backgroundColor: 'rgba(0,0,0,.8)'}]}>
                        {!this.state.download &&
                        <Text style={{fontSize: 16, color: '#fff'}}>{this.state.downloadProgress + '%'}</Text>}
                        {this.state.download && <View style={{display: 'flex', alignItems: 'center'}}>
                            <Image source={done} resizeMode="contain"/>
                            <Text style={{fontSize: 16, color: '#fff'}}>已保存</Text>
                        </View>}
                    </View>
                </View>}
                {this.props.savePic && <Animated.View style={{
                    width: '100%',
                    position: 'absolute',
                    left: 0,
                    bottom: this.state.picBottom,
                    backgroundColor: '#dedede'
                }}>
                    <View style={{width: '100%', backgroundColor: '#fff'}}>
                        <TouchableOpacity activeOpacity={0.8} style={styles.picItem}
                                          onPress={() => NoDoublePress.onPress(() => {
                                              this.savePic()
                                          })}>
                            <Text style={{fontSize: 18, color: '#000'}}>保存到手机</Text>
                        </TouchableOpacity>
                    </View>
                    <View style={{width: '100%', backgroundColor: '#fff', marginTop: (8 / zoomH)}}>
                        <TouchableOpacity activeOpacity={0.8} style={[styles.picItem, {borderBottomWidth: 0}]}
                                          onPress={() => NoDoublePress.onPress(() => {
                                              Animated.timing(this.state.picBottom, {toValue: -(320 / zoomH)}).start();
                                          })}>
                            <Text style={{fontSize: 18, color: '#000'}}>取消</Text>
                        </TouchableOpacity>
                    </View>
                </Animated.View>}
            </View>
        );
    }
}

const styles = StyleSheet.create({
    background: {
        flex: 1,
        backgroundColor: '#fff',
        display: 'flex'
    },
    viewBg: {
        width: width,
        height: height,
        backgroundColor: '#000',
        display: 'flex',
        justifyContent: 'flex-end'
    },
    picItem: {
        width: '100%',
        height: (50 / zoomH),
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        borderStyle: 'solid',
        borderBottomColor: '#eee',
        borderBottomWidth: StyleSheet.hairlineWidth
    },
    delBtn: {
        width: (50 / zoomW),
        height: (45 / zoomH),
        marginTop: (1 / zoomH),
        marginRight: (1 / zoomW),
        display: 'flex',
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#ea281a',
        position: 'absolute',
        right: 0,
        borderRadius: 7
    },
    loadingBox: {
        width: (100 / zoomW),
        height: (120 / zoomH),
        backgroundColor: 'rgba(0,0,0,.5)',
        borderRadius: 8,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center'
    }
});