PageRenderTime 45ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Examples/UIExplorer/XHRExample.ios.js

https://gitlab.com/akashshinde/react-native
JavaScript | 391 lines | 351 code | 25 blank | 15 comment | 26 complexity | 898e8dab8c8b335ffbbc950413da3352 MD5 | raw file
  1. /**
  2. * The examples provided by Facebook are for non-commercial testing and
  3. * evaluation purposes only.
  4. *
  5. * Facebook reserves all rights not expressly granted.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  8. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  9. * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
  10. * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  11. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  12. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  13. *
  14. * @flow
  15. */
  16. 'use strict';
  17. var React = require('react');
  18. var ReactNative = require('react-native');
  19. var {
  20. AlertIOS,
  21. CameraRoll,
  22. Image,
  23. LinkingIOS,
  24. ProgressViewIOS,
  25. StyleSheet,
  26. Text,
  27. TextInput,
  28. TouchableHighlight,
  29. View,
  30. } = ReactNative;
  31. var XHRExampleHeaders = require('./XHRExampleHeaders');
  32. var XHRExampleFetch = require('./XHRExampleFetch');
  33. class Downloader extends React.Component {
  34. state: any;
  35. xhr: XMLHttpRequest;
  36. cancelled: boolean;
  37. constructor(props) {
  38. super(props);
  39. this.cancelled = false;
  40. this.state = {
  41. downloading: false,
  42. contentSize: 1,
  43. downloaded: 0,
  44. };
  45. }
  46. download() {
  47. this.xhr && this.xhr.abort();
  48. var xhr = this.xhr || new XMLHttpRequest();
  49. xhr.onreadystatechange = () => {
  50. if (xhr.readyState === xhr.HEADERS_RECEIVED) {
  51. var contentSize = parseInt(xhr.getResponseHeader('Content-Length'), 10);
  52. this.setState({
  53. contentSize: contentSize,
  54. downloaded: 0,
  55. });
  56. } else if (xhr.readyState === xhr.LOADING) {
  57. this.setState({
  58. downloaded: xhr.responseText.length,
  59. });
  60. } else if (xhr.readyState === xhr.DONE) {
  61. this.setState({
  62. downloading: false,
  63. });
  64. if (this.cancelled) {
  65. this.cancelled = false;
  66. return;
  67. }
  68. if (xhr.status === 200) {
  69. alert('Download complete!');
  70. } else if (xhr.status !== 0) {
  71. alert('Error: Server returned HTTP status of ' + xhr.status + ' ' + xhr.responseText);
  72. } else {
  73. alert('Error: ' + xhr.responseText);
  74. }
  75. }
  76. };
  77. xhr.open('GET', 'http://www.gutenberg.org/cache/epub/100/pg100.txt');
  78. xhr.send();
  79. this.xhr = xhr;
  80. this.setState({downloading: true});
  81. }
  82. componentWillUnmount() {
  83. this.cancelled = true;
  84. this.xhr && this.xhr.abort();
  85. }
  86. render() {
  87. var button = this.state.downloading ? (
  88. <View style={styles.wrapper}>
  89. <View style={styles.button}>
  90. <Text>Downloading...</Text>
  91. </View>
  92. </View>
  93. ) : (
  94. <TouchableHighlight
  95. style={styles.wrapper}
  96. onPress={this.download.bind(this)}>
  97. <View style={styles.button}>
  98. <Text>Download 5MB Text File</Text>
  99. </View>
  100. </TouchableHighlight>
  101. );
  102. return (
  103. <View>
  104. {button}
  105. <ProgressViewIOS progress={(this.state.downloaded / this.state.contentSize)}/>
  106. </View>
  107. );
  108. }
  109. }
  110. var PAGE_SIZE = 20;
  111. class FormUploader extends React.Component {
  112. state: any;
  113. _isMounted: boolean;
  114. _fetchRandomPhoto: () => void;
  115. _addTextParam: () => void;
  116. _upload: () => void;
  117. constructor(props) {
  118. super(props);
  119. this.state = {
  120. isUploading: false,
  121. uploadProgress: null,
  122. randomPhoto: null,
  123. textParams: [],
  124. };
  125. this._isMounted = true;
  126. this._fetchRandomPhoto = this._fetchRandomPhoto.bind(this);
  127. this._addTextParam = this._addTextParam.bind(this);
  128. this._upload = this._upload.bind(this);
  129. this._fetchRandomPhoto();
  130. }
  131. _fetchRandomPhoto() {
  132. CameraRoll.getPhotos(
  133. {first: PAGE_SIZE}
  134. ).then(
  135. (data) => {
  136. if (!this._isMounted) {
  137. return;
  138. }
  139. var edges = data.edges;
  140. var edge = edges[Math.floor(Math.random() * edges.length)];
  141. var randomPhoto = edge && edge.node && edge.node.image;
  142. if (randomPhoto) {
  143. this.setState({randomPhoto});
  144. }
  145. },
  146. (error) => undefined
  147. );
  148. }
  149. _addTextParam() {
  150. var textParams = this.state.textParams;
  151. textParams.push({name: '', value: ''});
  152. this.setState({textParams});
  153. }
  154. componentWillUnmount() {
  155. this._isMounted = false;
  156. }
  157. _onTextParamNameChange(index, text) {
  158. var textParams = this.state.textParams;
  159. textParams[index].name = text;
  160. this.setState({textParams});
  161. }
  162. _onTextParamValueChange(index, text) {
  163. var textParams = this.state.textParams;
  164. textParams[index].value = text;
  165. this.setState({textParams});
  166. }
  167. _upload() {
  168. var xhr = new XMLHttpRequest();
  169. xhr.open('POST', 'http://posttestserver.com/post.php');
  170. xhr.onload = () => {
  171. this.setState({isUploading: false});
  172. if (xhr.status !== 200) {
  173. AlertIOS.alert(
  174. 'Upload failed',
  175. 'Expected HTTP 200 OK response, got ' + xhr.status
  176. );
  177. return;
  178. }
  179. if (!xhr.responseText) {
  180. AlertIOS.alert(
  181. 'Upload failed',
  182. 'No response payload.'
  183. );
  184. return;
  185. }
  186. var index = xhr.responseText.indexOf('http://www.posttestserver.com/');
  187. if (index === -1) {
  188. AlertIOS.alert(
  189. 'Upload failed',
  190. 'Invalid response payload.'
  191. );
  192. return;
  193. }
  194. var url = xhr.responseText.slice(index).split('\n')[0];
  195. LinkingIOS.openURL(url);
  196. };
  197. var formdata = new FormData();
  198. if (this.state.randomPhoto) {
  199. formdata.append('image', {...this.state.randomPhoto, name: 'image.jpg'});
  200. }
  201. this.state.textParams.forEach(
  202. (param) => formdata.append(param.name, param.value)
  203. );
  204. if (xhr.upload) {
  205. xhr.upload.onprogress = (event) => {
  206. console.log('upload onprogress', event);
  207. if (event.lengthComputable) {
  208. this.setState({uploadProgress: event.loaded / event.total});
  209. }
  210. };
  211. }
  212. xhr.send(formdata);
  213. this.setState({isUploading: true});
  214. }
  215. render() {
  216. var image = null;
  217. if (this.state.randomPhoto) {
  218. image = (
  219. <Image
  220. source={this.state.randomPhoto}
  221. style={styles.randomPhoto}
  222. />
  223. );
  224. }
  225. var textItems = this.state.textParams.map((item, index) => (
  226. <View style={styles.paramRow}>
  227. <TextInput
  228. autoCapitalize="none"
  229. autoCorrect={false}
  230. onChangeText={this._onTextParamNameChange.bind(this, index)}
  231. placeholder="name..."
  232. style={styles.textInput}
  233. />
  234. <Text style={styles.equalSign}>=</Text>
  235. <TextInput
  236. autoCapitalize="none"
  237. autoCorrect={false}
  238. onChangeText={this._onTextParamValueChange.bind(this, index)}
  239. placeholder="value..."
  240. style={styles.textInput}
  241. />
  242. </View>
  243. ));
  244. var uploadButtonLabel = this.state.isUploading ? 'Uploading...' : 'Upload';
  245. var uploadProgress = this.state.uploadProgress;
  246. if (uploadProgress !== null) {
  247. uploadButtonLabel += ' ' + Math.round(uploadProgress * 100) + '%';
  248. }
  249. var uploadButton = (
  250. <View style={styles.uploadButtonBox}>
  251. <Text style={styles.uploadButtonLabel}>{uploadButtonLabel}</Text>
  252. </View>
  253. );
  254. if (!this.state.isUploading) {
  255. uploadButton = (
  256. <TouchableHighlight onPress={this._upload}>
  257. {uploadButton}
  258. </TouchableHighlight>
  259. );
  260. }
  261. return (
  262. <View>
  263. <View style={[styles.paramRow, styles.photoRow]}>
  264. <Text style={styles.photoLabel}>
  265. Random photo from your library
  266. (<Text style={styles.textButton} onPress={this._fetchRandomPhoto}>
  267. update
  268. </Text>)
  269. </Text>
  270. {image}
  271. </View>
  272. {textItems}
  273. <View>
  274. <Text
  275. style={[styles.textButton, styles.addTextParamButton]}
  276. onPress={this._addTextParam}>
  277. Add a text param
  278. </Text>
  279. </View>
  280. <View style={styles.uploadButton}>
  281. {uploadButton}
  282. </View>
  283. </View>
  284. );
  285. }
  286. }
  287. exports.framework = 'React';
  288. exports.title = 'XMLHttpRequest';
  289. exports.description = 'XMLHttpRequest';
  290. exports.examples = [{
  291. title: 'File Download',
  292. render() {
  293. return <Downloader/>;
  294. }
  295. }, {
  296. title: 'multipart/form-data Upload',
  297. render() {
  298. return <FormUploader/>;
  299. }
  300. }, {
  301. title: 'Fetch Test',
  302. render() {
  303. return <XHRExampleFetch/>;
  304. }
  305. }, {
  306. title: 'Headers',
  307. render() {
  308. return <XHRExampleHeaders/>;
  309. }
  310. }];
  311. var styles = StyleSheet.create({
  312. wrapper: {
  313. borderRadius: 5,
  314. marginBottom: 5,
  315. },
  316. button: {
  317. backgroundColor: '#eeeeee',
  318. padding: 8,
  319. },
  320. paramRow: {
  321. flexDirection: 'row',
  322. paddingVertical: 8,
  323. alignItems: 'center',
  324. borderBottomWidth: StyleSheet.hairlineWidth,
  325. borderBottomColor: 'grey',
  326. },
  327. photoLabel: {
  328. flex: 1,
  329. },
  330. randomPhoto: {
  331. width: 50,
  332. height: 50,
  333. },
  334. textButton: {
  335. color: 'blue',
  336. },
  337. addTextParamButton: {
  338. marginTop: 8,
  339. },
  340. textInput: {
  341. flex: 1,
  342. borderRadius: 3,
  343. borderColor: 'grey',
  344. borderWidth: 1,
  345. height: 30,
  346. paddingLeft: 8,
  347. },
  348. equalSign: {
  349. paddingHorizontal: 4,
  350. },
  351. uploadButton: {
  352. marginTop: 16,
  353. },
  354. uploadButtonBox: {
  355. flex: 1,
  356. paddingVertical: 12,
  357. alignItems: 'center',
  358. backgroundColor: 'blue',
  359. borderRadius: 4,
  360. },
  361. uploadButtonLabel: {
  362. color: 'white',
  363. fontSize: 16,
  364. fontWeight: '500',
  365. },
  366. });