about summary refs log tree commit diff
path: root/patches
diff options
context:
space:
mode:
authordan <dan.abramov@gmail.com>2024-11-13 16:34:24 +0000
committerGitHub <noreply@github.com>2024-11-13 16:34:24 +0000
commit3bab7f7540273a50501780b2f92076fbe41c8022 (patch)
tree4df9c6a323063bb08be46496ef0fa763b196a2d2 /patches
parent017b7647b18cc67201c5b4e9c5da36a53257daa9 (diff)
downloadvoidsky-3bab7f7540273a50501780b2f92076fbe41c8022.tar.zst
Patch RCTScrollView to fix centerContent (#6298)
Diffstat (limited to 'patches')
-rw-r--r--patches/react-native+0.74.1.patch137
1 files changed, 125 insertions, 12 deletions
diff --git a/patches/react-native+0.74.1.patch b/patches/react-native+0.74.1.patch
index ea6161e2f..d9f55aa30 100644
--- a/patches/react-native+0.74.1.patch
+++ b/patches/react-native+0.74.1.patch
@@ -9,7 +9,7 @@ index caa5540..c5d4e67 100644
 -                                                  type != nil && [type length] > 0 ? type : @"application/octet-stream",
 +                                                  ![type isEqual:[NSNull null]] && [type length] > 0 ? type : @"application/octet-stream",
                                                    [data base64EncodedStringWithOptions:0]];
-
+ 
        resolve(text);
 diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
 index b0d71dc..41b9a0e 100644
@@ -18,7 +18,7 @@ index b0d71dc..41b9a0e 100644
 @@ -377,10 +377,6 @@ - (void)textInputDidBeginEditing
      self.backedTextInputView.attributedText = [NSAttributedString new];
    }
-
+ 
 -  if (_selectTextOnFocus) {
 -    [self.backedTextInputView selectAll:nil];
 -  }
@@ -35,7 +35,7 @@ index b0d71dc..41b9a0e 100644
 +    [self.backedTextInputView selectAll:nil];
 +  }
  }
-
+ 
  - (void)reactBlur
 diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
 index e9b330f..ec5f58c 100644
@@ -48,10 +48,10 @@ index e9b330f..ec5f58c 100644
 +@property (nonatomic, copy) UIColor *customTintColor;
 +
 +- (void)forwarderBeginRefreshing;
-
+ 
  @end
 diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
-index b09e653..288e60c 100644
+index b09e653..d2b4e05 100644
 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
 +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
 @@ -22,6 +22,7 @@ @implementation RCTRefreshControl {
@@ -60,12 +60,12 @@ index b09e653..288e60c 100644
    CGFloat _progressViewOffset;
 +  UIColor *_customTintColor;
  }
-
+ 
  - (instancetype)init
 @@ -56,6 +57,12 @@ - (void)layoutSubviews
    _isInitialRender = false;
  }
-
+ 
 +- (void)didMoveToSuperview
 +{
 +  [super didMoveToSuperview];
@@ -78,7 +78,7 @@ index b09e653..288e60c 100644
 @@ -203,4 +210,58 @@ - (void)refreshControlValueChanged
    }
  }
-
+ 
 +- (void)setCustomTintColor:(UIColor *)customTintColor
 +{
 +  _customTintColor = customTintColor;
@@ -139,26 +139,139 @@ index 40aaf9c..1c60164 100644
 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
 +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
 @@ -22,11 +22,12 @@ - (UIView *)view
-
+ 
  RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
  RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
 -RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
  RCT_EXPORT_VIEW_PROPERTY(title, NSString)
  RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
  RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat)
-
+ 
 +RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor)
 +
  RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
  {
    [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
+diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
+index 1aead51..39e6244 100644
+--- a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
++++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
+@@ -159,31 +159,6 @@ - (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view
+   return !shouldDisableScrollInteraction;
+ }
+ 
+-/*
+- * Automatically centers the content such that if the content is smaller than the
+- * ScrollView, we force it to be centered, but when you zoom or the content otherwise
+- * becomes larger than the ScrollView, there is no padding around the content but it
+- * can still fill the whole view.
+- */
+-- (void)setContentOffset:(CGPoint)contentOffset
+-{
+-  UIView *contentView = [self contentView];
+-  if (contentView && _centerContent && !CGSizeEqualToSize(contentView.frame.size, CGSizeZero)) {
+-    CGSize subviewSize = contentView.frame.size;
+-    CGSize scrollViewSize = self.bounds.size;
+-    if (subviewSize.width <= scrollViewSize.width) {
+-      contentOffset.x = -(scrollViewSize.width - subviewSize.width) / 2.0;
+-    }
+-    if (subviewSize.height <= scrollViewSize.height) {
+-      contentOffset.y = -(scrollViewSize.height - subviewSize.height) / 2.0;
+-    }
+-  }
+-
+-  super.contentOffset = CGPointMake(
+-      RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
+-      RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
+-}
+-
+ - (void)setFrame:(CGRect)frame
+ {
+   // Preserving and revalidating `contentOffset`.
+@@ -427,6 +402,11 @@ - (void)setRemoveClippedSubviews:(__unused BOOL)removeClippedSubviews
+   // Does nothing
+ }
+ 
++- (void)setFrame:(CGRect)frame {
++  [super setFrame:frame];
++  [self centerContentIfNeeded];
++}
++
+ - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
+ {
+   [super insertReactSubview:view atIndex:atIndex];
+@@ -444,6 +424,8 @@ - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
+     RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection);
+     [_scrollView addSubview:view];
+   }
++
++  [self centerContentIfNeeded];
+ }
+ 
+ - (void)removeReactSubview:(UIView *)subview
+@@ -652,9 +634,46 @@ -(void)delegateMethod : (UIScrollView *)scrollView        \
+   }
+ 
+ RCT_SCROLL_EVENT_HANDLER(scrollViewWillBeginDecelerating, onMomentumScrollBegin)
+-RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
+ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
+ 
++-(void)scrollViewDidZoom : (UIScrollView *)scrollView
++{
++  [self centerContentIfNeeded];
++
++  RCT_SEND_SCROLL_EVENT(onScroll, nil);
++  RCT_FORWARD_SCROLL_EVENT(scrollViewDidZoom : scrollView);
++}
++
++/*
++ * Automatically centers the content such that if the content is smaller than the
++ * ScrollView, we force it to be centered, but when you zoom or the content otherwise
++ * becomes larger than the ScrollView, there is no padding around the content but it
++ * can still fill the whole view.
++ *
++ * PATCHED: This deviates from the original React Native implementation to fix two issues:
++ *
++ * - The scroll view was swallowing any taps immediately after pinching
++ * - The scroll view was jittering when crossing the full screen threshold while pinching
++ *
++ * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
++ */
++-(void)centerContentIfNeeded
++{
++  if (_scrollView.centerContent &&
++      !CGSizeEqualToSize(self.contentSize, CGSizeZero) &&
++      !CGSizeEqualToSize(self.bounds.size, CGSizeZero)
++  ) {
++    CGFloat top = 0, left = 0;
++    if (self.contentSize.width < self.bounds.size.width) {
++      left = (self.bounds.size.width - self.contentSize.width) * 0.5f;
++    }
++    if (self.contentSize.height < self.bounds.size.height) {
++      top = (self.bounds.size.height - self.contentSize.height) * 0.5f;
++    }
++    _scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left);
++  }
++}
++
+ - (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener
+ {
+   [_scrollListeners addObject:scrollListener];
+@@ -913,6 +932,7 @@ - (void)updateContentSizeIfNeeded
+   CGSize contentSize = self.contentSize;
+   if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) {
+     _scrollView.contentSize = contentSize;
++    [self centerContentIfNeeded];
+   }
+ }
+ 
 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
 index 5f5e1ab..aac00b6 100644
 --- 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
 @@ -99,8 +99,9 @@ public class JavaTimerManager {
        }
-
+ 
        // If the JS thread is busy for multiple frames we cancel any other pending runnable.
 -      if (mCurrentIdleCallbackRunnable != null) {
 -        mCurrentIdleCallbackRunnable.cancel();
@@ -166,5 +279,5 @@ index 5f5e1ab..aac00b6 100644
 +      if (currentRunnable != null) {
 +        currentRunnable.cancel();
        }
-
+ 
        mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);