Added RCTImageSource

Summary:
public

The +[RCTConvert UIImage:] function, while convenient, is inherently limited by being synchronous, which means that it cannot be used to load remote images, and may not be efficient for local images either. It's also unable to access the bridge, which means that it cannot take advantage of the modular image-loading pipeline.

This diff introduces a new RCTImageSource class which can be used to pass image source objects over the bridge and defer loading until later.

I've also added automatic application of the `resolveAssetSource()` function based on prop type, and fixed up the image logic in NavigatorIOS and TabBarIOS.

Reviewed By: javache

Differential Revision: D2631541

fb-gh-sync-id: 6604635e8bb5394425102487f1ee7cd729321877
This commit is contained in:
Nick Lockwood
2015-12-08 03:29:08 -08:00
committed by facebook-github-bot-4
parent dcebe8cd37
commit b672294858
23 changed files with 434 additions and 276 deletions

View File

@@ -69,13 +69,16 @@ var Image = React.createClass({
PropTypes.number,
]),
/**
* A static image to display while downloading the final image off the
* network.
* A static image to display while loading the image source.
* @platform ios
*/
defaultSource: PropTypes.shape({
uri: PropTypes.string,
}),
defaultSource: PropTypes.oneOfType([
PropTypes.shape({
uri: PropTypes.string,
}),
// Opaque type returned by require('./image.jpg')
PropTypes.number,
]),
/**
* When true, indicates the image is an accessibility element.
* @platform ios
@@ -155,23 +158,10 @@ var Image = React.createClass({
},
render: function() {
for (var prop in cfg.nativeOnly) {
if (this.props[prop] !== undefined) {
console.warn('Prop `' + prop + ' = ' + this.props[prop] + '` should ' +
'not be set directly on Image.');
}
}
var source = resolveAssetSource(this.props.source) || {};
var defaultSource = (this.props.defaultSource && resolveAssetSource(this.props.defaultSource)) || {};
var {width, height} = source;
var style = flattenStyle([{width, height}, styles.base, this.props.style]) || {};
if (source.uri === '') {
console.warn('source.uri should not be an empty string');
return <View {...this.props} style={style} />;
}
var isNetwork = source.uri && source.uri.match(/^https?:/);
var RawImage = isNetwork ? RCTNetworkImageView : RCTImageView;
var resizeMode = this.props.resizeMode || (style || {}).resizeMode || 'cover'; // Workaround for flow bug t7737108
@@ -192,8 +182,7 @@ var Image = React.createClass({
style={style}
resizeMode={resizeMode}
tintColor={tintColor}
src={source.uri}
defaultImageSrc={defaultSource.uri}
source={source}
/>
);
}
@@ -206,16 +195,8 @@ var styles = StyleSheet.create({
},
});
var cfg = {
nativeOnly: {
src: true,
defaultImageSrc: true,
imageTag: true,
progressHandlerRegistered: true,
},
};
var RCTImageView = requireNativeComponent('RCTImageView', Image, cfg);
var RCTNetworkImageView = NativeModules.NetworkImageViewManager ? requireNativeComponent('RCTNetworkImageView', Image, cfg) : RCTImageView;
var RCTImageView = requireNativeComponent('RCTImageView', Image);
var RCTNetworkImageView = NativeModules.NetworkImageViewManager ? requireNativeComponent('RCTNetworkImageView', Image) : RCTImageView;
var RCTVirtualImage = requireNativeComponent('RCTVirtualImage', Image);
module.exports = Image;