/** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * The examples provided by Facebook are for non-commercial testing and * evaluation purposes only. * * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * @flow */ 'use strict'; const React = require('react'); const ReactNative = require('react-native'); const { Alert, CameraRoll, Image, ImageEditor, Linking, Platform, StyleSheet, Text, TextInput, TouchableHighlight, View, } = ReactNative; const PAGE_SIZE = 20; class XHRExampleFormData extends React.Component { 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; } var edges = data.edges; var edge = edges[Math.floor(Math.random() * edges.length)]; var 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 = () => { var textParams = this.state.textParams; textParams.push({name: '', value: ''}); this.setState({textParams}); }; _onTextParamNameChange(index, text) { var textParams = this.state.textParams; textParams[index].name = text; this.setState({textParams}); } _onTextParamValueChange(index, text) { var textParams = this.state.textParams; textParams[index].value = text; this.setState({textParams}); } _upload = () => { var xhr = new XMLHttpRequest(); xhr.open('POST', 'http://posttestserver.com/post.php'); xhr.onload = () => { this.setState({isUploading: false}); if (xhr.status !== 200) { Alert.alert( 'Upload failed', 'Expected HTTP 200 OK response, got ' + xhr.status ); return; } if (!xhr.responseText) { Alert.alert( 'Upload failed', 'No response payload.' ); return; } var index = xhr.responseText.indexOf('http://www.posttestserver.com/'); if (index === -1) { Alert.alert( 'Upload failed', 'Invalid response payload.' ); return; } var url = xhr.responseText.slice(index).split('\n')[0]; console.log('Upload successful: ' + url); Linking.openURL(url); }; var 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() { var image = null; if (this.state.randomPhoto) { image = ( ); } var textItems = this.state.textParams.map((item, index) => ( = )); var uploadButtonLabel = this.state.isUploading ? 'Uploading...' : 'Upload'; var uploadProgress = this.state.uploadProgress; if (uploadProgress !== null) { uploadButtonLabel += ' ' + Math.round(uploadProgress * 100) + '%'; } var uploadButton = ( {uploadButtonLabel} ); if (!this.state.isUploading) { uploadButton = ( {uploadButton} ); } return ( Random photo from your library ( update ) {image} {textItems} Add a text param {uploadButton} ); } } 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;