/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * @flow */ 'use strict'; const React = require('react'); const ReactNative = require('react-native'); const { CameraRoll, Image, ImageEditor, Platform, StyleSheet, Text, TextInput, TouchableHighlight, View, } = ReactNative; const XHRExampleBinaryUpload = require('./XHRExampleBinaryUpload'); const PAGE_SIZE = 20; class XHRExampleFormData extends React.Component<Object, Object> { state: Object = { isUploading: false, uploadProgress: null, randomPhoto: null, textParams: [], }; _isMounted: boolean = true; constructor(props: Object) { super(props); this._fetchRandomPhoto(); } componentWillUnmount() { this._isMounted = false; } _fetchRandomPhoto = () => { CameraRoll.getPhotos({first: PAGE_SIZE}).then(data => { if (!this._isMounted) { return; } const edges = data.edges; const edge = edges[Math.floor(Math.random() * edges.length)]; const randomPhoto = edge && edge.node && edge.node.image; if (randomPhoto) { let {width, height} = randomPhoto; width *= 0.25; height *= 0.25; ImageEditor.cropImage( randomPhoto.uri, {offset: {x: 0, y: 0}, size: {width, height}}, uri => this.setState({randomPhoto: {uri}}), error => undefined, ); } }, error => undefined); }; _addTextParam = () => { const textParams = this.state.textParams; textParams.push({name: '', value: ''}); this.setState({textParams}); }; _onTextParamNameChange(index, text) { const textParams = this.state.textParams; textParams[index].name = text; this.setState({textParams}); } _onTextParamValueChange(index, text) { const textParams = this.state.textParams; textParams[index].value = text; this.setState({textParams}); } _upload = () => { const xhr = new XMLHttpRequest(); xhr.open('POST', 'http://posttestserver.com/post.php'); xhr.onload = () => { this.setState({isUploading: false}); XHRExampleBinaryUpload.handlePostTestServerUpload(xhr); }; const formdata = new FormData(); if (this.state.randomPhoto) { formdata.append('image', { ...this.state.randomPhoto, type: 'image/jpg', name: 'image.jpg', }); } this.state.textParams.forEach(param => formdata.append(param.name, param.value), ); xhr.upload.onprogress = event => { if (event.lengthComputable) { this.setState({uploadProgress: event.loaded / event.total}); } }; xhr.send(formdata); this.setState({isUploading: true}); }; render() { let image = null; if (this.state.randomPhoto) { image = ( <Image source={this.state.randomPhoto} style={styles.randomPhoto} /> ); } const textItems = this.state.textParams.map((item, index) => ( <View style={styles.paramRow}> <TextInput autoCapitalize="none" autoCorrect={false} onChangeText={this._onTextParamNameChange.bind(this, index)} placeholder="name..." style={styles.textInput} /> <Text style={styles.equalSign}>=</Text> <TextInput autoCapitalize="none" autoCorrect={false} onChangeText={this._onTextParamValueChange.bind(this, index)} placeholder="value..." style={styles.textInput} /> </View> )); let uploadButtonLabel = this.state.isUploading ? 'Uploading...' : 'Upload'; const uploadProgress = this.state.uploadProgress; if (uploadProgress !== null) { uploadButtonLabel += ' ' + Math.round(uploadProgress * 100) + '%'; } let uploadButton = ( <View style={styles.uploadButtonBox}> <Text style={styles.uploadButtonLabel}>{uploadButtonLabel}</Text> </View> ); if (!this.state.isUploading) { uploadButton = ( <TouchableHighlight onPress={this._upload}> {uploadButton} </TouchableHighlight> ); } return ( <View> <View style={styles.paramRow}> <Text style={styles.photoLabel}> Random photo from your library (<Text style={styles.textButton} onPress={this._fetchRandomPhoto}> update </Text>) </Text> {image} </View> {textItems} <View> <Text style={[styles.textButton, styles.addTextParamButton]} onPress={this._addTextParam}> Add a text param </Text> </View> <View style={styles.uploadButton}>{uploadButton}</View> </View> ); } } const styles = StyleSheet.create({ paramRow: { flexDirection: 'row', paddingVertical: 8, alignItems: 'center', borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: 'grey', }, photoLabel: { flex: 1, }, randomPhoto: { width: 50, height: 50, }, textButton: { color: 'blue', }, addTextParamButton: { marginTop: 8, }, textInput: { flex: 1, borderRadius: 3, borderColor: 'grey', borderWidth: 1, height: Platform.OS === 'android' ? 50 : 30, paddingLeft: 8, }, equalSign: { paddingHorizontal: 4, }, uploadButton: { marginTop: 16, }, uploadButtonBox: { flex: 1, paddingVertical: 12, alignItems: 'center', backgroundColor: 'blue', borderRadius: 4, }, uploadButtonLabel: { color: 'white', fontSize: 16, fontWeight: '500', }, }); module.exports = XHRExampleFormData;