react-native-fast-image/index.js

147 lines
3.7 KiB
JavaScript
Raw Normal View History

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
2018-05-06 23:04:28 +00:00
Platform,
View,
Image,
NativeModules,
requireNativeComponent,
ViewPropTypes,
StyleSheet,
} from 'react-native'
2017-04-13 04:13:44 +00:00
const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource')
const FastImageViewNativeModule = NativeModules.FastImageView
2018-04-20 18:03:37 +00:00
const useLocalImage = source => {
2018-05-06 23:04:28 +00:00
// No source.
if (!source) return true
// No uri.
if (!source.uri) return true
// Is a local Android image.
if (source.uri.startsWith('file://')) return true
// Content URI.
if (source.uri.startsWith('content://')) return true
// Smart album.
if (source.uri.startsWith('photos://')) return true
// From asset library / camera roll.
if (source.uri.startsWith('assets-library://')) return true
// We have a remote source.
return false
2018-04-20 18:03:37 +00:00
}
class FastImage extends Component {
2018-05-06 23:04:28 +00:00
setNativeProps(nativeProps) {
this._root.setNativeProps(nativeProps)
}
2018-05-06 23:04:28 +00:00
captureRef = e => (this._root = e)
render() {
const {
source,
onLoadStart,
onProgress,
onLoad,
onError,
onLoadEnd,
style,
children,
...props
} = this.props
// If there's no source or source uri just fallback to Image.
if (useLocalImage(source)) {
return (
<Image
ref={this.captureRef}
{...props}
style={style}
source={source}
onLoadStart={onLoadStart}
onProgress={onProgress}
onLoad={onLoad}
onError={onError}
onLoadEnd={onLoadEnd}
/>
)
}
const resolvedSource = resolveAssetSource(source)
return (
<View style={[style, styles.imageContainer]} ref={this.captureRef}>
<FastImageView
{...props}
style={StyleSheet.absoluteFill}
source={resolvedSource}
onFastImageLoadStart={onLoadStart}
onFastImageProgress={onProgress}
onFastImageLoad={onLoad}
onFastImageError={onError}
onFastImageLoadEnd={onLoadEnd}
/>
{children && (
<View style={StyleSheet.absoluteFill}>{children}</View>
)}
</View>
)
}
2017-04-13 04:13:44 +00:00
}
const styles = StyleSheet.create({
2018-05-06 23:04:28 +00:00
imageContainer: {
overflow: 'hidden',
},
})
2017-04-13 04:13:44 +00:00
FastImage.resizeMode = {
2018-05-06 23:04:28 +00:00
contain: 'contain',
cover: 'cover',
stretch: 'stretch',
center: 'center',
2017-04-13 04:13:44 +00:00
}
FastImage.priority = {
2018-05-06 23:04:28 +00:00
low: 'low',
normal: 'normal',
high: 'high',
2017-04-13 04:13:44 +00:00
}
FastImage.preload = sources => {
2018-05-06 23:04:28 +00:00
FastImageViewNativeModule.preload(sources)
2017-06-08 21:13:19 +00:00
}
2017-04-13 04:13:44 +00:00
FastImage.defaultProps = {
2018-05-06 23:04:28 +00:00
resizeMode: FastImage.resizeMode.cover,
}
const FastImageSourcePropType = PropTypes.shape({
2018-05-06 23:04:28 +00:00
uri: PropTypes.string,
headers: PropTypes.objectOf(PropTypes.string),
priority: PropTypes.oneOf(Object.keys(FastImage.priority)),
})
FastImage.propTypes = {
2018-05-06 23:04:28 +00:00
...ViewPropTypes,
source: PropTypes.oneOfType([FastImageSourcePropType, PropTypes.number]),
onLoadStart: PropTypes.func,
onProgress: PropTypes.func,
onLoad: PropTypes.func,
onError: PropTypes.func,
onLoadEnd: PropTypes.func,
2017-04-13 04:13:44 +00:00
}
const FastImageView = requireNativeComponent('FastImageView', FastImage, {
2018-05-06 23:04:28 +00:00
nativeOnly: {
onFastImageLoadStart: true,
onFastImageProgress: true,
onFastImageLoad: true,
onFastImageError: true,
onFastImageLoadEnd: true,
},
2017-04-13 04:13:44 +00:00
})
export default FastImage