|
11 | 11 | #import <React/RCTConversions.h> |
12 | 12 | #import <React/RCTImageBlurUtils.h> |
13 | 13 | #import <React/RCTImageResponseObserverProxy.h> |
| 14 | +#import <react/featureflags/ReactNativeFeatureFlags.h> |
14 | 15 | #import <react/renderer/components/image/ImageComponentDescriptor.h> |
15 | 16 | #import <react/renderer/components/image/ImageEventEmitter.h> |
16 | 17 | #import <react/renderer/components/image/ImageProps.h> |
|
19 | 20 |
|
20 | 21 | using namespace facebook::react; |
21 | 22 |
|
| 23 | +static NSString *const RCTImageRequestPriorityDebugOverlayEnabledEnvironmentVariable = |
| 24 | + @"RCT_IMAGE_REQUEST_PRIORITY_DEBUG_OVERLAY"; |
| 25 | + |
| 26 | +static BOOL RCTImageRequestPriorityDebugOverlayEnabled() |
| 27 | +{ |
| 28 | + if (ReactNativeFeatureFlags::enableImageRequestDowngradingForNonVisibleImages()) { |
| 29 | + static BOOL enabled = NO; |
| 30 | + static dispatch_once_t onceToken; |
| 31 | + dispatch_once(&onceToken, ^{ |
| 32 | + NSDictionary<NSString *, NSString *> *environment = [[NSProcessInfo processInfo] environment]; |
| 33 | + enabled = [environment[RCTImageRequestPriorityDebugOverlayEnabledEnvironmentVariable] boolValue]; |
| 34 | + }); |
| 35 | + return enabled; |
| 36 | + } else { |
| 37 | + return NO; |
| 38 | + } |
| 39 | +} |
| 40 | + |
| 41 | +static NSString *RCTImageRequestPriorityDebugLabel(ImageRequestPriority priority) |
| 42 | +{ |
| 43 | + switch (priority) { |
| 44 | + case ImageRequestPriority::Immediate: |
| 45 | + return @"immediate"; |
| 46 | + case ImageRequestPriority::Prefetch: |
| 47 | + return @"offscreen"; |
| 48 | + default: |
| 49 | + return @"unknown"; |
| 50 | + } |
| 51 | +} |
| 52 | + |
22 | 53 | @implementation RCTImageComponentView { |
23 | 54 | ImageShadowNode::ConcreteState::Shared _state; |
24 | 55 | std::shared_ptr<RCTImageResponseObserverProxy> _imageResponseObserverProxy; |
| 56 | + UILabel *_requestPriorityLabel; |
25 | 57 | } |
26 | 58 |
|
27 | 59 | - (instancetype)initWithFrame:(CGRect)frame |
@@ -85,6 +117,7 @@ - (void)updateState:(const State::Shared &)state oldState:(const State::Shared & |
85 | 117 | auto newImageState = std::static_pointer_cast<const ImageShadowNode::ConcreteState>(state); |
86 | 118 |
|
87 | 119 | [self _setStateAndResubscribeImageResponseObserver:newImageState]; |
| 120 | + [self _updateRequestPriorityLabelWithState:newImageState]; |
88 | 121 |
|
89 | 122 | bool havePreviousData = oldImageState && oldImageState->getData().getImageSource() != ImageSource{}; |
90 | 123 |
|
@@ -115,10 +148,53 @@ - (void)_setStateAndResubscribeImageResponseObserver:(const ImageShadowNode::Con |
115 | 148 | } |
116 | 149 | } |
117 | 150 |
|
| 151 | +- (UILabel *)_requestPriorityLabel |
| 152 | +{ |
| 153 | + if (!_requestPriorityLabel) { |
| 154 | + _requestPriorityLabel = [UILabel new]; |
| 155 | + _requestPriorityLabel.accessibilityElementsHidden = YES; |
| 156 | + _requestPriorityLabel.backgroundColor = [UIColor colorWithWhite:0 alpha:0.65]; |
| 157 | + _requestPriorityLabel.clipsToBounds = YES; |
| 158 | + _requestPriorityLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightSemibold]; |
| 159 | + _requestPriorityLabel.hidden = YES; |
| 160 | + _requestPriorityLabel.isAccessibilityElement = NO; |
| 161 | + _requestPriorityLabel.layer.cornerRadius = 3; |
| 162 | + _requestPriorityLabel.textAlignment = NSTextAlignmentCenter; |
| 163 | + _requestPriorityLabel.textColor = UIColor.whiteColor; |
| 164 | + [_imageView addSubview:_requestPriorityLabel]; |
| 165 | + } |
| 166 | + |
| 167 | + return _requestPriorityLabel; |
| 168 | +} |
| 169 | + |
| 170 | +- (void)_updateRequestPriorityLabelWithState:(const ImageShadowNode::ConcreteState::Shared &)state |
| 171 | +{ |
| 172 | + if (!state || !RCTImageRequestPriorityDebugOverlayEnabled()) { |
| 173 | + if (_requestPriorityLabel) { |
| 174 | + _requestPriorityLabel.hidden = YES; |
| 175 | + _requestPriorityLabel.text = nil; |
| 176 | + } |
| 177 | + return; |
| 178 | + } |
| 179 | + |
| 180 | + UILabel *requestPriorityLabel = [self _requestPriorityLabel]; |
| 181 | + requestPriorityLabel.text = RCTImageRequestPriorityDebugLabel(state->getData().getImageRequestParams().priority); |
| 182 | + [requestPriorityLabel sizeToFit]; |
| 183 | + |
| 184 | + CGRect frame = requestPriorityLabel.frame; |
| 185 | + frame.origin = CGPointMake(2, 2); |
| 186 | + frame.size.width += 8; |
| 187 | + frame.size.height += 4; |
| 188 | + requestPriorityLabel.frame = frame; |
| 189 | + requestPriorityLabel.hidden = NO; |
| 190 | + [_imageView bringSubviewToFront:requestPriorityLabel]; |
| 191 | +} |
| 192 | + |
118 | 193 | - (void)prepareForRecycle |
119 | 194 | { |
120 | 195 | [super prepareForRecycle]; |
121 | 196 | [self _setStateAndResubscribeImageResponseObserver:nullptr]; |
| 197 | + [self _updateRequestPriorityLabelWithState:nullptr]; |
122 | 198 | _imageView.image = nil; |
123 | 199 | } |
124 | 200 |
|
|
0 commit comments