1313#import < react/components/image/ImageShadowNode.h>
1414#import < react/imagemanager/ImageRequest.h>
1515#import < react/imagemanager/ImageResponse.h>
16+ #import < react/imagemanager/ImageResponseObserver.h>
1617#import < react/imagemanager/RCTImagePrimitivesConversions.h>
1718
1819#import " RCTConversions.h"
1920#import " MainQueueExecutor.h"
2021
2122using namespace facebook ::react;
2223
24+ class ImageResponseObserverProxy : public ImageResponseObserver {
25+ public:
26+ ImageResponseObserverProxy (void * delegate): delegate_((__bridge id <RCTImageResponseDelegate>)delegate) {}
27+
28+ void didReceiveImage (const ImageResponse &imageResponse) override {
29+ UIImage *image = (__bridge UIImage *)imageResponse.getImage ().get ();
30+ void *this_ = this ;
31+ dispatch_async (dispatch_get_main_queue (), ^{
32+ [delegate_ didReceiveImage: image fromObserver: this_];
33+ });
34+ }
35+
36+ void didReceiveProgress (float p) override {
37+ void *this_ = this ;
38+ dispatch_async (dispatch_get_main_queue (), ^{
39+ [delegate_ didReceiveProgress: p fromObserver: this_];
40+ });
41+ }
42+ void didReceiveFailure () override {
43+ void *this_ = this ;
44+ dispatch_async (dispatch_get_main_queue (), ^{
45+ [delegate_ didReceiveFailureFromObserver: this_];
46+ });
47+ }
48+
49+ private:
50+ id <RCTImageResponseDelegate> delegate_;
51+ };
52+
2353@implementation RCTImageComponentView {
2454 UIImageView *_imageView;
2555 SharedImageLocalData _imageLocalData;
56+ std::shared_ptr<const ImageResponseObserverCoordinator> _coordinator;
57+ std::unique_ptr<ImageResponseObserverProxy> _imageResponseObserverProxy;
2658}
2759
2860- (instancetype )initWithFrame : (CGRect)frame
@@ -35,6 +67,8 @@ - (instancetype)initWithFrame:(CGRect)frame
3567 _imageView.clipsToBounds = YES ;
3668
3769 _imageView.contentMode = (UIViewContentMode)RCTResizeModeFromImageResizeMode (defaultProps->resizeMode );
70+
71+ _imageResponseObserverProxy = std::make_unique<ImageResponseObserverProxy>((__bridge void *)self);
3872
3973 self.contentView = _imageView;
4074 }
@@ -78,23 +112,42 @@ - (void)updateLocalData:(SharedLocalData)localData
78112{
79113 _imageLocalData = std::static_pointer_cast<const ImageLocalData>(localData);
80114 assert (_imageLocalData);
81- auto future = _imageLocalData->getImageRequest ().getResponseFuture ();
82- future.via (&MainQueueExecutor::instance ()).thenValue ([self ](ImageResponse &&imageResponse) {
83- self.image = (__bridge UIImage *)imageResponse.getImage ().get ();
84- });
115+ self.coordinator = _imageLocalData->getImageRequest ().getObserverCoordinator ();
116+
117+ // Loading actually starts a little before this
118+ std::static_pointer_cast<const ImageEventEmitter>(_eventEmitter)->onLoadStart ();
119+ }
120+
121+ - (void )setCoordinator : (std::shared_ptr<const ImageResponseObserverCoordinator>)coordinator {
122+ if (_coordinator) {
123+ _coordinator->removeObserver (_imageResponseObserverProxy.get ());
124+ }
125+ _coordinator = coordinator;
126+ if (_coordinator != nullptr ) {
127+ _coordinator->addObserver (_imageResponseObserverProxy.get ());
128+ }
85129}
86130
87131- (void )prepareForRecycle
88132{
89133 [super prepareForRecycle ];
134+ self.coordinator = nullptr ;
90135 _imageView.image = nil ;
91136 _imageLocalData.reset ();
92137}
93138
94- #pragma mark - Other
139+ -(void )dealloc
140+ {
141+ self.coordinator = nullptr ;
142+ _imageResponseObserverProxy.reset ();
143+ }
144+
145+ #pragma mark - RCTImageResponseDelegate
95146
96- - (void )setImage : (UIImage *)image
147+ - (void )didReceiveImage : (UIImage *)image fromObserver : ( void *) observer
97148{
149+ std::static_pointer_cast<const ImageEventEmitter>(_eventEmitter)->onLoad ();
150+
98151 const auto &imageProps = *std::static_pointer_cast<const ImageProps>(_props);
99152
100153 if (imageProps.tintColor ) {
@@ -110,11 +163,22 @@ - (void)setImage:(UIImage *)image
110163 resizingMode: UIImageResizingModeStretch];
111164 }
112165
113- _imageView.image = image;
114-
166+ self-> _imageView .image = image;
167+
115168 // Apply trilinear filtering to smooth out mis-sized images.
116- _imageView.layer .minificationFilter = kCAFilterTrilinear ;
117- _imageView.layer .magnificationFilter = kCAFilterTrilinear ;
169+ self->_imageView .layer .minificationFilter = kCAFilterTrilinear ;
170+ self->_imageView .layer .magnificationFilter = kCAFilterTrilinear ;
171+
172+ std::static_pointer_cast<const ImageEventEmitter>(self->_eventEmitter )->onLoadEnd ();
118173}
119174
175+ - (void )didReceiveProgress : (float )progress fromObserver : (void *)observer {
176+ std::static_pointer_cast<const ImageEventEmitter>(_eventEmitter)->onProgress (progress);
177+ }
178+
179+ - (void )didReceiveFailureFromObserver : (void *)observer {
180+ std::static_pointer_cast<const ImageEventEmitter>(_eventEmitter)->onError ();
181+ }
182+
183+
120184@end
0 commit comments