UNPKG

elephant-com

Version:

the general component for elephant washing shoes

264 lines (246 loc) 6.51 kB
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, };