Skip to content

Commit d98f4e1

Browse files
committed
feat: add events on iOS
1 parent 63b7fa5 commit d98f4e1

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed

ios/FastImage/FFFastImageView.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#import <React/RCTResizeMode.h>
88

99
#import "FFFastImageSource.h"
10+
#ifdef RCT_NEW_ARCH_ENABLED
11+
#import <react/renderer/components/rnfastimage/EventEmitters.h>
12+
#endif
1013

1114
@interface FFFastImageView : SDAnimatedImageView
1215

@@ -27,6 +30,9 @@
2730
@property(nonatomic, assign) BOOL needsReload;
2831

2932
@property(nonatomic, strong) NSDictionary* onLoadEvent;
33+
#ifdef RCT_NEW_ARCH_ENABLED
34+
@property(nonatomic) facebook::react::SharedViewEventEmitter eventEmitter;
35+
#endif
3036

3137
- (void)reloadImage;
3238
- (void)didSetProps:(NSArray<NSString*>*)changedProps;

ios/FastImage/FFFastImageView.m renamed to ios/FastImage/FFFastImageView.mm

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,18 @@ - (void) sendOnLoad: (UIImage*)image {
8282
@"width": [NSNumber numberWithDouble: image.size.width],
8383
@"height": [NSNumber numberWithDouble: image.size.height]
8484
};
85+
// all the setters of RCTDirectEventBlock aren't called on Fabric so we don't
86+
// need the logic of checking if the values are there already etc
87+
#ifdef RCT_NEW_ARCH_ENABLED
88+
if (_eventEmitter != nullptr) {
89+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(_eventEmitter)
90+
->onFastImageLoad(facebook::react::FastImageViewEventEmitter::OnFastImageLoad{.width = image.size.width, .height = image.size.height});
91+
}
92+
#else
8593
if (self.onFastImageLoad) {
8694
self.onFastImageLoad(self.onLoadEvent);
8795
}
96+
#endif
8897
}
8998

9099
- (void) setSource: (FFFastImageSource*)source {
@@ -114,27 +123,48 @@ - (void) reloadImage {
114123
// Load base64 images.
115124
NSString* url = [_source.url absoluteString];
116125
if (url && [url hasPrefix: @"data:image"]) {
126+
#ifdef RCT_NEW_ARCH_ENABLED
127+
if (_eventEmitter != nullptr) {
128+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(_eventEmitter)
129+
->onFastImageLoadStart(facebook::react::FastImageViewEventEmitter::OnFastImageLoadStart{});
130+
}
131+
#else
117132
if (self.onFastImageLoadStart) {
118133
self.onFastImageLoadStart(@{});
119134
self.hasSentOnLoadStart = YES;
120135
} else {
121136
self.hasSentOnLoadStart = NO;
122137
}
138+
#endif
123139
// Use SDWebImage API to support external format like WebP images
124140
UIImage* image = [UIImage sd_imageWithData: [NSData dataWithContentsOfURL: _source.url]];
125141
[self setImage: image];
142+
#ifdef RCT_NEW_ARCH_ENABLED
143+
if (_eventEmitter != nullptr) {
144+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(_eventEmitter)
145+
->onFastImageProgress(facebook::react::FastImageViewEventEmitter::OnFastImageProgress{.loaded = 1, .total = 1});
146+
}
147+
#else
126148
if (self.onFastImageProgress) {
127149
self.onFastImageProgress(@{
128150
@"loaded": @(1),
129151
@"total": @(1)
130152
});
131153
}
154+
#endif
132155
self.hasCompleted = YES;
133156
[self sendOnLoad: image];
134157

158+
#ifdef RCT_NEW_ARCH_ENABLED
159+
if (_eventEmitter != nullptr) {
160+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(_eventEmitter)
161+
->onFastImageLoadEnd(facebook::react::FastImageViewEventEmitter::OnFastImageLoadEnd{});
162+
}
163+
#else
135164
if (self.onFastImageLoadEnd) {
136165
self.onFastImageLoadEnd(@{});
137166
}
167+
#endif
138168
return;
139169
}
140170

@@ -175,12 +205,19 @@ - (void) reloadImage {
175205
break;
176206
}
177207

208+
#ifdef RCT_NEW_ARCH_ENABLED
209+
if (_eventEmitter != nullptr) {
210+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(_eventEmitter)
211+
->onFastImageLoadStart(facebook::react::FastImageViewEventEmitter::OnFastImageLoadStart{});
212+
}
213+
#else
178214
if (self.onFastImageLoadStart) {
179215
self.onFastImageLoadStart(@{});
180216
self.hasSentOnLoadStart = YES;
181217
} else {
182218
self.hasSentOnLoadStart = NO;
183219
}
220+
#endif
184221
self.hasCompleted = NO;
185222
self.hasErrored = NO;
186223

@@ -191,36 +228,66 @@ - (void) reloadImage {
191228
}
192229

193230
- (void) downloadImage: (FFFastImageSource*)source options: (SDWebImageOptions)options context: (SDWebImageContext*)context {
194-
__weak typeof(self) weakSelf = self; // Always use a weak reference to self in blocks
231+
__weak FFFastImageView *weakSelf = self; // Always use a weak reference to self in blocks
195232
[self sd_setImageWithURL: _source.url
196233
placeholderImage: _defaultSource
197234
options: options
198235
context: context
199236
progress: ^(NSInteger receivedSize, NSInteger expectedSize, NSURL* _Nullable targetURL) {
200-
if (weakSelf.onFastImageProgress) {
237+
#ifdef RCT_NEW_ARCH_ENABLED
238+
if (weakSelf.eventEmitter != nullptr) {
239+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(weakSelf.eventEmitter)
240+
->onFastImageProgress(facebook::react::FastImageViewEventEmitter::OnFastImageProgress{.loaded = static_cast<int>(receivedSize), .total = static_cast<int>(expectedSize)});
241+
}
242+
#else
243+
if (weakSelf.onFastImageProgress) {
201244
weakSelf.onFastImageProgress(@{
202245
@"loaded": @(receivedSize),
203246
@"total": @(expectedSize)
204247
});
205248
}
249+
#endif
250+
206251
} completed: ^(UIImage* _Nullable image,
207252
NSError* _Nullable error,
208253
SDImageCacheType cacheType,
209254
NSURL* _Nullable imageURL) {
210255
if (error) {
211256
weakSelf.hasErrored = YES;
257+
#ifdef RCT_NEW_ARCH_ENABLED
258+
if (weakSelf.eventEmitter != nullptr) {
259+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(weakSelf.eventEmitter)
260+
->onFastImageError(facebook::react::FastImageViewEventEmitter::OnFastImageError{});
261+
}
262+
#else
212263
if (weakSelf.onFastImageError) {
213264
weakSelf.onFastImageError(@{});
214265
}
266+
#endif
267+
268+
#ifdef RCT_NEW_ARCH_ENABLED
269+
if (weakSelf.eventEmitter != nullptr) {
270+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(weakSelf.eventEmitter)
271+
->onFastImageLoadEnd(facebook::react::FastImageViewEventEmitter::OnFastImageLoadEnd{});
272+
}
273+
#else
215274
if (weakSelf.onFastImageLoadEnd) {
216275
weakSelf.onFastImageLoadEnd(@{});
217276
}
277+
#endif
218278
} else {
219279
weakSelf.hasCompleted = YES;
220280
[weakSelf sendOnLoad: image];
281+
#ifdef RCT_NEW_ARCH_ENABLED
282+
if (weakSelf.eventEmitter != nullptr) {
283+
std::dynamic_pointer_cast<const facebook::react::FastImageViewEventEmitter>(weakSelf.eventEmitter)
284+
->onFastImageLoadEnd(facebook::react::FastImageViewEventEmitter::OnFastImageLoadEnd{});
285+
}
286+
#else
221287
if (weakSelf.onFastImageLoadEnd) {
222288
weakSelf.onFastImageLoadEnd(@{});
223289
}
290+
#endif
224291
}
225292
}];
226293
}

ios/FastImage/FFFastImageViewComponentView.mm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ - (instancetype)initWithFrame:(CGRect)frame
3434

3535
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps{
3636

37+
// TODO: not sure if it is the right place to do it.
38+
[fastImageView setEventEmitter:_eventEmitter];
3739
const auto &newViewProps = *std::static_pointer_cast<FastImageViewProps const>(props);
3840

3941
NSMutableDictionary *imageSourcePropsDict = [NSMutableDictionary new];
@@ -110,6 +112,7 @@ - (void)prepareForRecycle
110112
{
111113
[super prepareForRecycle];
112114
fastImageView = [[FFFastImageView alloc] initWithFrame:self.bounds];
115+
self.contentView = fastImageView;
113116
}
114117

115118
@end

0 commit comments

Comments
 (0)