elephant-com
Version:
the general component for elephant washing shoes
264 lines (246 loc) • 6.51 kB
JavaScript
import React from 'react';
import {Text, Icon} from 'antd-mobile';
import {
View,
StyleSheet, TouchableWithoutFeedback, Image,
} from 'react-native';
import varibles from 'antd-mobile/lib/style/themes/default';
import {Bars} from 'react-native-loader';
import PropTypes from 'prop-types';
import * as uuid from 'uuid';
import {ImagePickerCustom} from './ImagePickerCustom';
import {ImagePreview} from './ImagePreview';
function getRandomName(fileName) {
const pos = fileName.lastIndexOf('.');
const suffix = pos === -1 ? '' : fileName.substring(pos);
return uuid.v4().replace(/-/g, '') + suffix;
}
export default class OssUpload extends React.Component {
constructor(props) {
super(props);
this.state = {
files: (this.props.files || []).map(f => ({uploaded: true, url: f})),
visible: false,
index: 0,
};
}
/* eslint-disable */
getFormDate(file) {
const sign = this.props.sign;
const dir = sign.OssDir.endsWith('/') ? sign.OssDir : `${sign.OssDir}/`;
const action = sign.action.endsWith('/') ? sign.action : `${sign.action}/`;
const fileKey = `${dir}${getRandomName(file.filename)}`;
const curFileUrl = `${action}${fileKey}`;
const data = {
signature: sign.OssSignature,
OSSAccessKeyId: sign.OssAccessId,
policy: sign.OssPolicy,
key: fileKey,
success_action_status: 200,
};
return {data, url: curFileUrl}
}
onStartUpload(file) {
const {data, url} = this.getFormDate(file);
const formData = new FormData();
if (data) {
Object.keys(data).map((key) => {
formData.append(key, data[key]);
});
}
formData.append('file', {uri: file.path, type: 'image/jpg', name: 'image.jpg'});
fetch(this.props.sign.action, {
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
body: formData
}).then(() => {
file.uploaded = true;
file.url = url;
this.setState({
files: this.state.files,
});
if (this.props.onChange) {
this.props.onChange(this.state.files.map(f => f.url));
}
}).catch(() => {
const index = this.state.files.indexOf(file);
this.state.files.splice(index, 1);
this.setState({
files: this.state.files,
});
});
}
onAddImageClick = () => {
ImagePickerCustom({
title: '选择',
options: {},
callback: (x) => {
const file = {
...x,
uploaded: false,
};
this.setState({
files: this.state.files.concat(file),
});
this.onStartUpload(file);
},
});
};
preImage(key) {
this.setState({
index: key,
visible: true,
})
}
hidePreImage() {
this.setState({
visible: false,
});
}
removeImage(index) {
this.state.files.splice(index, 1);
this.setState({
files: this.state.files,
});
if (this.props.onChange) {
this.props.onChange(this.state.files.map(f => f.url));
}
}
render() {
const {files, index, visible} = this.state;
const filesView = files.map((item, index) => (
<View key={item.uploaded ? item.url : item.path} style={[styles.item, styles.size]}>
<Image
source={{uri: item.uploaded ? item.url : item.path}}
style={[styles.size, styles.image]}
/>
{
item.uploaded &&
<TouchableWithoutFeedback onPress={() => this.removeImage(index)}>
<View style={styles.closeWrap}>
<Text style={styles.closeText}>×</Text>
</View>
</TouchableWithoutFeedback>
}
{
item.uploaded &&
<TouchableWithoutFeedback onPress={() => this.preImage(index)}>
<View style={styles.preImageWrap}/>
</TouchableWithoutFeedback>
}
{
!item.uploaded &&
<View style={styles.preImageWrap}>
<Bars size={10} color="#f00"/>
</View>
}
</View>
));
let rest = (filesView.length + 1) % 3;
let restHolder = null;
if (rest) {
rest = 3 - rest;
restHolder = <Text style={{width: rest * 100}}/>
}
return (
<View>
<View style={styles.container}>
{filesView}
<TouchableWithoutFeedback
onPress={this.onAddImageClick.bind(this)}
>
<View
ref={conponent => this.plusWrap = conponent}
style={[styles.item, styles.size, styles.plusWrap, styles.plusWrapNormal]}
>
<Icon type={'\uE627'} size={40} color="#B9B7B8"/>
</View>
</TouchableWithoutFeedback>
{restHolder}
</View>
<ImagePreview
visible={visible}
index={index}
images={files}
onPress={this.hidePreImage.bind(this)}
/>
</View>
);
}
}
OssUpload.propsTypes = {
OssSignature: PropTypes.string.isRequired,
OssAccessId: PropTypes.string.isRequired,
OssPolicy: PropTypes.string.isRequired,
OssDir: PropTypes.string.isRequired,
};
const styles = StyleSheet.create({
container: {
flexWrap: 'wrap',
flexDirection: 'row',
justifyContent: 'space-between',
},
size: {
width: 80,
height: 80,
},
item: {
marginRight: varibles.h_spacing_sm,
marginBottom: varibles.v_spacing_sm,
},
image: {
overflow: 'hidden',
borderWidth: 4,
borderColor: '#fff',
},
closeWrap: {
width: 20,
height: 20,
backgroundColor: '#f00',
borderRadius: 10,
position: 'absolute',
top: -5,
right: -5,
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
},
preImageWrap: {
width: 80,
height: 80,
backgroundColor: 'transparent',
position: 'absolute',
marginTop: 20,
marginRight: 20,
justifyContent: 'center',
alignItems: 'center',
},
closeText: {
color: varibles.color_text_base_inverse,
backgroundColor: 'transparent',
fontSize: 20,
height: 20,
marginTop: -8,
fontWeight: '300',
},
plusWrap: {
borderRadius: 0,
borderWidth: 3,
borderColor: '#ffffff',
justifyContent: 'center',
alignItems: 'center',
},
plusWrapNormal: {
backgroundColor: '#ecebec',
borderColor: '#fff',
},
plusWrapHighlight: {
backgroundColor: varibles.fill_tap,
borderColor: varibles.border_color_base,
},
});
OssUpload.defaultProps = {
onChange: null,
};