From 7202f5c523247417f0a8946ddf9fb0be203704c4 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 13 Feb 2019 17:36:09 +0400 Subject: [PATCH 1/4] add `placeholder` functionality --- ios/Vendor/SDWebImage | 2 +- src/index.js | 76 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/ios/Vendor/SDWebImage b/ios/Vendor/SDWebImage index ccb8b533c..dc5c974b8 160000 --- a/ios/Vendor/SDWebImage +++ b/ios/Vendor/SDWebImage @@ -1 +1 @@ -Subproject commit ccb8b533c65a0e6dde9e8b34129c3c6fb73b11f4 +Subproject commit dc5c974b89509992d6c6e0d0510344fd0e35baa6 diff --git a/src/index.js b/src/index.js index ea2187e98..9502a9363 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import React, { forwardRef } from 'react' +import React, { Component } from 'react' import PropTypes from 'prop-types' import { View, @@ -11,9 +11,31 @@ import { const FastImageViewNativeModule = NativeModules.FastImageView -const FastImage = forwardRef( - ( - { +class FastImage extends Component { + componentDidUpdate(prevProps, prevState) { + if (this.props.source === prevProps.source) { + return + } + + this.setState({ + loaded: false, + error: null, + }) + } + + state = { + loaded: false, + error: null, + } + + setNativeProps(nativeProps) { + this._root.setNativeProps(nativeProps) + } + + captureRef = e => (this._root = e) + + render() { + const { source, onLoadStart, onProgress, @@ -23,16 +45,21 @@ const FastImage = forwardRef( style, children, fallback, + placeholder, ...props - }, - ref, - ) => { + } = this.props + + const { loaded, error } = this.state const resolvedSource = Image.resolveAssetSource(source) if (fallback) { return ( - - + {(!loaded || error) && placeholder} + + + {(!loaded || error) && placeholder} { + this.setState({ + error: true, + }) + + onError(data) + }} + onFastImageLoadEnd={data => { + this.setState({ + loaded: true, + }) + + onLoadEnd(data) + }} /> {children} ) - }, -) - -FastImage.displayName = 'FastImage' + } +} const styles = StyleSheet.create({ imageContainer: { @@ -104,6 +142,11 @@ FastImage.preload = sources => { FastImage.defaultProps = { resizeMode: FastImage.resizeMode.cover, + onLoadStart: () => {}, + onProgress: () => {}, + onLoad: () => {}, + onError: () => {}, + onLoadEnd: () => {}, } const FastImageSourcePropType = PropTypes.shape({ @@ -122,6 +165,7 @@ FastImage.propTypes = { onError: PropTypes.func, onLoadEnd: PropTypes.func, fallback: PropTypes.bool, + placeholder: PropTypes.node, } const FastImageView = requireNativeComponent('FastImageView', FastImage, { From 7cce28a1abbd2982f9d1a19cad2242b23a6f835f Mon Sep 17 00:00:00 2001 From: Kafil Uddin Kiron Date: Thu, 28 Feb 2019 19:14:02 +0600 Subject: [PATCH 2/4] fix: avatar placeholder issue --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 9502a9363..147f5ce88 100644 --- a/src/index.js +++ b/src/index.js @@ -13,7 +13,7 @@ const FastImageViewNativeModule = NativeModules.FastImageView class FastImage extends Component { componentDidUpdate(prevProps, prevState) { - if (this.props.source === prevProps.source) { + if (this.props.source.uri === prevProps.source.uri) { return } From b286d2f6eb0bd5347b91e9334d8e00ad8a3a977f Mon Sep 17 00:00:00 2001 From: John Date: Fri, 15 Mar 2019 15:53:21 +0400 Subject: [PATCH 3/4] update type definitions --- src/__snapshots__/index.test.js.snap | 17 ++++++++++++++++- src/index.d.ts | 1 + src/index.js | 2 +- src/index.js.flow | 4 +++- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/__snapshots__/index.test.js.snap b/src/__snapshots__/index.test.js.snap index 7a59c68f3..aadb6a025 100644 --- a/src/__snapshots__/index.test.js.snap +++ b/src/__snapshots__/index.test.js.snap @@ -15,6 +15,11 @@ exports[`FastImage renders correctly. 1`] = ` } > - void, source: FastImageSource | number, - + placeholder?: Node, + resizeMode?: ?ResizeModes, fallback?: ?boolean, testID?: ?string, From de6ece4adcf4ba4c3d469493f093e54679a03f8c Mon Sep 17 00:00:00 2001 From: John Date: Mon, 18 Mar 2019 11:26:30 +0400 Subject: [PATCH 4/4] show placeholder when timer is expired --- .eslintrc.js | 2 ++ src/index.js | 34 +++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 37e1db3fa..df865c2bb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,6 +2,8 @@ module.exports = { parser: 'babel-eslint', env: { es6: true, + browser: true, + node: true, }, plugins: ['jest'], overrides: { diff --git a/src/index.js b/src/index.js index 478735f26..fef0fccc3 100644 --- a/src/index.js +++ b/src/index.js @@ -12,20 +12,36 @@ import { const FastImageViewNativeModule = NativeModules.FastImageView class FastImage extends Component { + componentDidMount() { + this.runTimer() + } + componentDidUpdate(prevProps) { - if (this.props.source.uri === prevProps.source.uri) { - return + if (this.props.source.uri !== prevProps.source.uri) { + this.setState({ + loaded: false, + error: null, + expired: false, + }) + + this.runTimer() } + } + + componentWillUnmount() { + clearTimeout(this.timeout) + } - this.setState({ - loaded: false, - error: null, - }) + runTimer() { + this.timeout = setTimeout(() => { + this.setState({ expired: true }) + }, 1000) } state = { loaded: false, error: null, + expired: false, } setNativeProps(nativeProps) { @@ -49,7 +65,7 @@ class FastImage extends Component { ...props } = this.props - const { loaded, error } = this.state + const { expired, loaded, error } = this.state const resolvedSource = Image.resolveAssetSource(source) if (fallback) { @@ -58,7 +74,7 @@ class FastImage extends Component { style={[styles.imageContainer, style]} ref={this.captureRef} > - {(!loaded || error) && placeholder} + {expired && (!loaded || error) && placeholder} - {(!loaded || error) && placeholder} + {expired && (!loaded || error) && placeholder}