Skip to content

Commit

Permalink
Fix iOS progress implementation to conform to React Native's image.
Browse files Browse the repository at this point in the history
Includes:

- onLoadStart
- onProgress
- onError
- onLoad
- onLoadEnd

Also changes to use the prop-types package.
  • Loading branch information
DylanVann committed Jul 24, 2017
1 parent 7e0b966 commit 6c720f5
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 16 deletions.
46 changes: 37 additions & 9 deletions FastImage.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types';
import {
requireNativeComponent,
Image,
NativeModules,
requireNativeComponent,
View,
} from 'react-native'

Expand All @@ -15,8 +16,16 @@ class FastImage extends Component {
this._root.setNativeProps(nativeProps)
}

render() {
const { source, onError, onLoad, onProgress, ...props } = this.props
render () {
const {
source,
onLoadStart,
onProgress,
onLoad,
onError,
onLoadEnd,
...props,
} = this.props

// If there's no source or source uri just fallback to Image.
if (!source || !source.uri) {
Expand All @@ -25,9 +34,11 @@ class FastImage extends Component {
ref={e => (this._root = e)}
{...props}
source={source}
onLoadStart={onLoadStart}
onProgress={onProgress}
onError={onError}
onLoad={onLoad}
onError={onError}
onLoadEnd={onLoadEnd}
/>
)
}
Expand All @@ -38,9 +49,11 @@ class FastImage extends Component {
ref={e => (this._root = e)}
{...props}
source={resolvedSource}
onFastImageLoadStart={onLoadStart}
onFastImageProgress={onProgress}
onFastImageError={onError}
onFastImageLoad={onLoad}
onFastImageError={onError}
onFastImageLoadEnd={onLoadEnd}
/>
)
}
Expand All @@ -65,16 +78,31 @@ FastImage.preload = sources => {

FastImage.defaultProps = {
resizeMode: FastImage.resizeMode.cover,
onProgress: Function.prototype,
onLoad: Function.prototype,
onError: Function.prototype,
}

const FastImageSourcePropType = PropTypes.shape({
uri: PropTypes.string,
headers: PropTypes.objectOf(PropTypes.string),
priority: PropTypes.oneOf(Object.keys(FastImage.priority)),
})

FastImage.propTypes = {
...View.propTypes,
source: FastImageSourcePropType,
onLoadStart: PropTypes.func,
onProgress: PropTypes.func,
onLoad: PropTypes.func,
onError: PropTypes.func,
onLoadEnd: PropTypes.func,
}

const FastImageView = requireNativeComponent('FastImageView', FastImage, {
nativeOnly: {
onFastImageLoadStart: true,
onFastImageProgress: true,
onFastImageError: true,
onFastImageLoad: true,
onFastImageError: true,
onFastImageLoadEnd: true,
},
})

Expand Down
6 changes: 5 additions & 1 deletion example/FastImageExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ class FastImageExample extends Component {
},
priority: FastImage.priority.low,
}}
onProgress={e => console.log('progress', e.nativeEvent.progress)}
/>
<FastImage
style={styles.image}
Expand All @@ -111,6 +110,11 @@ class FastImageExample extends Component {
},
priority: FastImage.priority.high,
}}
onLoadStart={() => console.log('onLoadStart')}
onProgress={e => console.log(e.nativeEvent.progress)}
onLoad={() => console.log('onLoad')}
onError={() => console.log('onError')}
onLoadEnd={() => console.log('onLoadEnd')}
/>
</ScrollView>
</View>
Expand Down
4 changes: 3 additions & 1 deletion ios/FastImage/FFFastImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

@interface FFFastImageView : FLAnimatedImageView

@property (nonatomic, copy) RCTBubblingEventBlock onFastImageProgress;
@property (nonatomic, copy) RCTDirectEventBlock onFastImageLoadStart;
@property (nonatomic, copy) RCTDirectEventBlock onFastImageProgress;
@property (nonatomic, copy) RCTDirectEventBlock onFastImageError;
@property (nonatomic, copy) RCTDirectEventBlock onFastImageLoad;
@property (nonatomic, copy) RCTDirectEventBlock onFastImageLoadEnd;
@property (nonatomic, assign) RCTResizeMode resizeMode;
@property (nonatomic, strong) FFFastImageSource *source;

Expand Down
35 changes: 31 additions & 4 deletions ios/FastImage/FFFastImageView.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#import "FFFastImageView.h"

@implementation FFFastImageView
@implementation FFFastImageView {
BOOL hasSentOnLoadStart;
}

- (void)setResizeMode:(RCTResizeMode)resizeMode
{
Expand All @@ -10,18 +12,30 @@ - (void)setResizeMode:(RCTResizeMode)resizeMode
}
}

- (void)setOnFastImageLoadStart:(RCTBubblingEventBlock)onFastImageLoadStart {
if (_source && !hasSentOnLoadStart) {
_onFastImageLoadStart = onFastImageLoadStart;
onFastImageLoadStart(@{});
hasSentOnLoadStart = YES;
} else {
_onFastImageLoadStart = onFastImageLoadStart;
hasSentOnLoadStart = NO;
}
}

- (void)setSource:(FFFastImageSource *)source {
if (_source != source) {
_source = source;

// Set headers.
[source.headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString* header, BOOL *stop) {
[_source.headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString* header, BOOL *stop) {
[[SDWebImageDownloader sharedDownloader] setValue:header forHTTPHeaderField:key];
}];

// Set priority.
SDWebImageOptions options = 0;
options |= SDWebImageRetryFailed;
switch (source.priority) {
switch (_source.priority) {
case FFFPriorityLow:
options |= SDWebImageLowPriority;
break;
Expand All @@ -33,8 +47,15 @@ - (void)setSource:(FFFastImageSource *)source {
break;
}

if (_onFastImageLoadStart) {
_onFastImageLoadStart(@{});
hasSentOnLoadStart = YES;
} {
hasSentOnLoadStart = NO;
}

// Load the new source.
[self sd_setImageWithURL:source.uri
[self sd_setImageWithURL:_source.uri
placeholderImage:nil
options:options
progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
Expand All @@ -50,10 +71,16 @@ - (void)setSource:(FFFastImageSource *)source {
if (error) {
if (_onFastImageError) {
_onFastImageError(@{});
if (_onFastImageLoadEnd) {
_onFastImageLoadEnd(@{});
}
}
} else {
if (_onFastImageLoad) {
_onFastImageLoad(@{});
if (_onFastImageLoadEnd) {
_onFastImageLoadEnd(@{});
}
}
}
}];
Expand Down
4 changes: 3 additions & 1 deletion ios/FastImage/FFFastImageViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ - (FFFastImageView*)view {

RCT_EXPORT_VIEW_PROPERTY(source, FFFastImageSource)
RCT_EXPORT_VIEW_PROPERTY(resizeMode, RCTResizeMode)
RCT_EXPORT_VIEW_PROPERTY(onFastImageProgress, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadStart, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageProgress, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageError, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageLoad, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadEnd, RCTDirectEventBlock)

RCT_EXPORT_METHOD(preload:(nonnull NSArray<FFFastImageSource *> *)sources)
{
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@
"example",
"server"
]
},
"dependencies": {
"prop-types": "^15.5.10"
}
}

0 comments on commit 6c720f5

Please sign in to comment.