From 74f8055692893ddc8e756f1a262c0488a205d529 Mon Sep 17 00:00:00 2001 From: Dmitriy Loktev Date: Tue, 14 Jul 2015 13:56:55 -0700 Subject: [PATCH] [Image] Add examples to UIExplorer, fix some bugs Summary: Add two simple examples. ![image](https://cloud.githubusercontent.com/assets/1004115/8674092/03052652-2a55-11e5-8531-8f01c7970af4.png) Also: - do not start the task at DownloadTaskWrapper (it starts from ImageDowloader if image isn't cached yet); - fire `onLoadAbor`t event; - send more readable `error.localizedDescription` with `onLoadError`; - rename `onLoaded` to `onLoadEnd` Closes https://github.com/facebook/react-native/pull/1987 Github Author: Dmitriy Loktev --- Examples/UIExplorer/ImageExample.js | 53 ++++++++++++++++++++ Libraries/Image/RCTDownloadTaskWrapper.m | 1 - Libraries/Image/RCTImageDownloader.m | 2 +- Libraries/Image/RCTNetworkImageView.m | 6 ++- Libraries/Image/RCTNetworkImageViewManager.m | 2 +- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/Examples/UIExplorer/ImageExample.js b/Examples/UIExplorer/ImageExample.js index faa3267a1..b886bf861 100644 --- a/Examples/UIExplorer/ImageExample.js +++ b/Examples/UIExplorer/ImageExample.js @@ -21,10 +21,41 @@ var { StyleSheet, Text, View, + ActivityIndicatorIOS } = React; var ImageCapInsetsExample = require('./ImageCapInsetsExample'); +var NetworkImageExample = React.createClass({ + watchID: (null: ?number), + + getInitialState: function() { + return { + error: false, + loading: true, + progress: 0 + }; + }, + render: function() { + var loader = this.state.loading ? + + {this.state.progress}% + + : null; + return this.state.error ? + {this.state.error} : + this.setState({error: e.nativeEvent.error})} + onLoadProgress={(e) => this.setState({progress: Math.max(0, Math.round(100 * e.nativeEvent.written / e.nativeEvent.total))}) } + onLoadEnd={() => this.setState({loading: false, error: false})} + onLoadAbort={() => this.setState({error: 'Loading has aborted'})} > + {loader} + ; + } +}); + exports.displayName = (undefined: ?string); exports.framework = 'React'; exports.title = ''; @@ -59,6 +90,22 @@ exports.examples = [ ); }, }, + { + title: 'Error Handler', + render: function() { + return ( + + ); + }, + }, + { + title: 'Image Download Progress', + render: function() { + return ( + + ); + }, + }, { title: 'Border Color', render: function() { @@ -300,6 +347,12 @@ var styles = StyleSheet.create({ width: 38, height: 38, }, + progress: { + flex: 1, + alignItems: 'center', + flexDirection: 'row', + width: 100 + }, leftMargin: { marginLeft: 10, }, diff --git a/Libraries/Image/RCTDownloadTaskWrapper.m b/Libraries/Image/RCTDownloadTaskWrapper.m index b910cb476..e9a64369b 100644 --- a/Libraries/Image/RCTDownloadTaskWrapper.m +++ b/Libraries/Image/RCTDownloadTaskWrapper.m @@ -66,7 +66,6 @@ static void *const RCTDownloadTaskWrapperProgressBlockKey = (void *)&RCTDownload task.rct_completionBlock = completionBlock; task.rct_progressBlock = progressBlock; - [task resume]; return task; } diff --git a/Libraries/Image/RCTImageDownloader.m b/Libraries/Image/RCTImageDownloader.m index bf6a33e4d..f32d895cb 100644 --- a/Libraries/Image/RCTImageDownloader.m +++ b/Libraries/Image/RCTImageDownloader.m @@ -110,7 +110,7 @@ CGRect RCTClipRect(CGSize, CGFloat, CGSize, CGFloat, UIViewContentMode); runBlocks(NO, response, data, error); } - if (response) { + if (response && !error) { RCTImageDownloader *strongSelf = weakSelf; NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data userInfo:nil storagePolicy:NSURLCacheStorageAllowed]; [strongSelf->_cache storeCachedResponse:cachedResponse forRequest:request]; diff --git a/Libraries/Image/RCTNetworkImageView.m b/Libraries/Image/RCTNetworkImageView.m index f8dc28157..20d297b46 100644 --- a/Libraries/Image/RCTNetworkImageView.m +++ b/Libraries/Image/RCTNetworkImageView.m @@ -86,6 +86,8 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) { if (![_imageURL isEqual:imageURL] && _downloadToken) { [_imageDownloader cancelDownload:_downloadToken]; + NSDictionary *event = @{ @"target": self.reactTag }; + [_eventDispatcher sendInputEventWithName:@"loadAbort" body:event]; _downloadToken = nil; } @@ -146,7 +148,7 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) loadEndHandler(); }); } else if (error) { - errorHandler([error description]); + errorHandler([error localizedDescription]); } }]; } else { @@ -170,7 +172,7 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder) loadEndHandler(); }); } else if (error) { - errorHandler([error description]); + errorHandler([error localizedDescription]); } }]; } diff --git a/Libraries/Image/RCTNetworkImageViewManager.m b/Libraries/Image/RCTNetworkImageViewManager.m index 29d990b27..f42ef48f1 100644 --- a/Libraries/Image/RCTNetworkImageViewManager.m +++ b/Libraries/Image/RCTNetworkImageViewManager.m @@ -47,7 +47,7 @@ RCT_CUSTOM_VIEW_PROPERTY(tintColor, UIColor, RCTNetworkImageView) return @{ @"loadStart": @{ @"registrationName": @"onLoadStart" }, @"loadProgress": @{ @"registrationName": @"onLoadProgress" }, - @"loaded": @{ @"registrationName": @"onLoaded" }, + @"loaded": @{ @"registrationName": @"onLoadEnd" }, @"loadError": @{ @"registrationName": @"onLoadError" }, @"loadAbort": @{ @"registrationName": @"onLoadAbort" }, };