my fork of the bluesky client

Patch RCTScrollView to fix centerContent (#6298)

authored by danabra.mov and committed by

GitHub 3bab7f75 017b7647

+125 -12
+125 -12
patches/react-native+0.74.1.patch
··· 9 9 - type != nil && [type length] > 0 ? type : @"application/octet-stream", 10 10 + ![type isEqual:[NSNull null]] && [type length] > 0 ? type : @"application/octet-stream", 11 11 [data base64EncodedStringWithOptions:0]]; 12 - 12 + 13 13 resolve(text); 14 14 diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm 15 15 index b0d71dc..41b9a0e 100644 ··· 18 18 @@ -377,10 +377,6 @@ - (void)textInputDidBeginEditing 19 19 self.backedTextInputView.attributedText = [NSAttributedString new]; 20 20 } 21 - 21 + 22 22 - if (_selectTextOnFocus) { 23 23 - [self.backedTextInputView selectAll:nil]; 24 24 - } ··· 35 35 + [self.backedTextInputView selectAll:nil]; 36 36 + } 37 37 } 38 - 38 + 39 39 - (void)reactBlur 40 40 diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h 41 41 index e9b330f..ec5f58c 100644 ··· 48 48 +@property (nonatomic, copy) UIColor *customTintColor; 49 49 + 50 50 +- (void)forwarderBeginRefreshing; 51 - 51 + 52 52 @end 53 53 diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m 54 - index b09e653..288e60c 100644 54 + index b09e653..d2b4e05 100644 55 55 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m 56 56 +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m 57 57 @@ -22,6 +22,7 @@ @implementation RCTRefreshControl { ··· 60 60 CGFloat _progressViewOffset; 61 61 + UIColor *_customTintColor; 62 62 } 63 - 63 + 64 64 - (instancetype)init 65 65 @@ -56,6 +57,12 @@ - (void)layoutSubviews 66 66 _isInitialRender = false; 67 67 } 68 - 68 + 69 69 +- (void)didMoveToSuperview 70 70 +{ 71 71 + [super didMoveToSuperview]; ··· 78 78 @@ -203,4 +210,58 @@ - (void)refreshControlValueChanged 79 79 } 80 80 } 81 - 81 + 82 82 +- (void)setCustomTintColor:(UIColor *)customTintColor 83 83 +{ 84 84 + _customTintColor = customTintColor; ··· 139 139 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m 140 140 +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m 141 141 @@ -22,11 +22,12 @@ - (UIView *)view 142 - 142 + 143 143 RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock) 144 144 RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL) 145 145 -RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor) 146 146 RCT_EXPORT_VIEW_PROPERTY(title, NSString) 147 147 RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor) 148 148 RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat) 149 - 149 + 150 150 +RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor) 151 151 + 152 152 RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing) 153 153 { 154 154 [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) { 155 + diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m 156 + index 1aead51..39e6244 100644 157 + --- a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m 158 + +++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m 159 + @@ -159,31 +159,6 @@ - (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view 160 + return !shouldDisableScrollInteraction; 161 + } 162 + 163 + -/* 164 + - * Automatically centers the content such that if the content is smaller than the 165 + - * ScrollView, we force it to be centered, but when you zoom or the content otherwise 166 + - * becomes larger than the ScrollView, there is no padding around the content but it 167 + - * can still fill the whole view. 168 + - */ 169 + -- (void)setContentOffset:(CGPoint)contentOffset 170 + -{ 171 + - UIView *contentView = [self contentView]; 172 + - if (contentView && _centerContent && !CGSizeEqualToSize(contentView.frame.size, CGSizeZero)) { 173 + - CGSize subviewSize = contentView.frame.size; 174 + - CGSize scrollViewSize = self.bounds.size; 175 + - if (subviewSize.width <= scrollViewSize.width) { 176 + - contentOffset.x = -(scrollViewSize.width - subviewSize.width) / 2.0; 177 + - } 178 + - if (subviewSize.height <= scrollViewSize.height) { 179 + - contentOffset.y = -(scrollViewSize.height - subviewSize.height) / 2.0; 180 + - } 181 + - } 182 + - 183 + - super.contentOffset = CGPointMake( 184 + - RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"), 185 + - RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y")); 186 + -} 187 + - 188 + - (void)setFrame:(CGRect)frame 189 + { 190 + // Preserving and revalidating `contentOffset`. 191 + @@ -427,6 +402,11 @@ - (void)setRemoveClippedSubviews:(__unused BOOL)removeClippedSubviews 192 + // Does nothing 193 + } 194 + 195 + +- (void)setFrame:(CGRect)frame { 196 + + [super setFrame:frame]; 197 + + [self centerContentIfNeeded]; 198 + +} 199 + + 200 + - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex 201 + { 202 + [super insertReactSubview:view atIndex:atIndex]; 203 + @@ -444,6 +424,8 @@ - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex 204 + RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection); 205 + [_scrollView addSubview:view]; 206 + } 207 + + 208 + + [self centerContentIfNeeded]; 209 + } 210 + 211 + - (void)removeReactSubview:(UIView *)subview 212 + @@ -652,9 +634,46 @@ -(void)delegateMethod : (UIScrollView *)scrollView \ 213 + } 214 + 215 + RCT_SCROLL_EVENT_HANDLER(scrollViewWillBeginDecelerating, onMomentumScrollBegin) 216 + -RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll) 217 + RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop) 218 + 219 + +-(void)scrollViewDidZoom : (UIScrollView *)scrollView 220 + +{ 221 + + [self centerContentIfNeeded]; 222 + + 223 + + RCT_SEND_SCROLL_EVENT(onScroll, nil); 224 + + RCT_FORWARD_SCROLL_EVENT(scrollViewDidZoom : scrollView); 225 + +} 226 + + 227 + +/* 228 + + * Automatically centers the content such that if the content is smaller than the 229 + + * ScrollView, we force it to be centered, but when you zoom or the content otherwise 230 + + * becomes larger than the ScrollView, there is no padding around the content but it 231 + + * can still fill the whole view. 232 + + * 233 + + * PATCHED: This deviates from the original React Native implementation to fix two issues: 234 + + * 235 + + * - The scroll view was swallowing any taps immediately after pinching 236 + + * - The scroll view was jittering when crossing the full screen threshold while pinching 237 + + * 238 + + * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/. 239 + + */ 240 + +-(void)centerContentIfNeeded 241 + +{ 242 + + if (_scrollView.centerContent && 243 + + !CGSizeEqualToSize(self.contentSize, CGSizeZero) && 244 + + !CGSizeEqualToSize(self.bounds.size, CGSizeZero) 245 + + ) { 246 + + CGFloat top = 0, left = 0; 247 + + if (self.contentSize.width < self.bounds.size.width) { 248 + + left = (self.bounds.size.width - self.contentSize.width) * 0.5f; 249 + + } 250 + + if (self.contentSize.height < self.bounds.size.height) { 251 + + top = (self.bounds.size.height - self.contentSize.height) * 0.5f; 252 + + } 253 + + _scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left); 254 + + } 255 + +} 256 + + 257 + - (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener 258 + { 259 + [_scrollListeners addObject:scrollListener]; 260 + @@ -913,6 +932,7 @@ - (void)updateContentSizeIfNeeded 261 + CGSize contentSize = self.contentSize; 262 + if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) { 263 + _scrollView.contentSize = contentSize; 264 + + [self centerContentIfNeeded]; 265 + } 266 + } 267 + 155 268 diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java 156 269 index 5f5e1ab..aac00b6 100644 157 270 --- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java 158 271 +++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java 159 272 @@ -99,8 +99,9 @@ public class JavaTimerManager { 160 273 } 161 - 274 + 162 275 // If the JS thread is busy for multiple frames we cancel any other pending runnable. 163 276 - if (mCurrentIdleCallbackRunnable != null) { 164 277 - mCurrentIdleCallbackRunnable.cancel(); ··· 166 279 + if (currentRunnable != null) { 167 280 + currentRunnable.cancel(); 168 281 } 169 - 282 + 170 283 mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);