From 872fcd1d20e2e3981eca77190b3eaa380b9aca76 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 7 Apr 2025 20:29:41 -0500 Subject: Update patches (#8151) * Update patches after #8133 * Bump deps * Revert @react-native-picker/picker downgrade * Migrate RN patch --- patches/react-native+0.76.9.patch | 366 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 patches/react-native+0.76.9.patch (limited to 'patches/react-native+0.76.9.patch') diff --git a/patches/react-native+0.76.9.patch b/patches/react-native+0.76.9.patch new file mode 100644 index 000000000..7e96d875c --- /dev/null +++ b/patches/react-native+0.76.9.patch @@ -0,0 +1,366 @@ +diff --git a/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +index 62f52a7..ca30165 100644 +--- a/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts ++++ b/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +@@ -426,9 +426,10 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle { + */ + pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto' | undefined; + isolation?: 'auto' | 'isolate' | undefined; +- cursor?: CursorValue | undefined; ++ cursor?: CursorValue | string | undefined; + boxShadow?: ReadonlyArray | string | undefined; + filter?: ReadonlyArray | string | undefined; ++ transformOrigin?: string | (string | number)[] | undefined; + } + + export type FontVariant = +@@ -536,7 +537,11 @@ export interface TextStyle extends TextStyleIOS, TextStyleAndroid, ViewStyle { + textShadowOffset?: {width: number; height: number} | undefined; + textShadowRadius?: number | undefined; + textTransform?: 'none' | 'capitalize' | 'uppercase' | 'lowercase' | undefined; +- userSelect?: 'auto' | 'none' | 'text' | 'contain' | 'all' | undefined; ++ userSelect?: 'auto' | 'none' | 'text' | 'contain' | 'all' | string | undefined; ++ cursor?: CursorValue | string | undefined; ++ boxShadow?: ReadonlyArray | string | undefined; ++ filter?: ReadonlyArray | string | undefined; ++ transformOrigin?: string | (string | number)[] | undefined; + } + + /** +@@ -558,5 +563,8 @@ export interface ImageStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle { + tintColor?: ColorValue | undefined; + opacity?: AnimatableNumericValue | undefined; + objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | undefined; +- cursor?: CursorValue | undefined; ++ cursor?: CursorValue | string | undefined; ++ boxShadow?: ReadonlyArray | string | undefined; ++ filter?: ReadonlyArray | string | undefined; ++ transformOrigin?: string | (string | number)[] | undefined; + } +diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm +index 93af874..106f8ec 100644 +--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm ++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm +@@ -66,28 +66,51 @@ + * 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. ++ * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/. + */ +-- (void)setContentOffset:(CGPoint)contentOffset ++-(void)centerContentIfNeeded + { +- if (_isSetContentOffsetDisabled) { ++ if (!_centerContent) { + return; + } + +- if (_centerContent && !CGSizeEqualToSize(self.contentSize, CGSizeZero)) { +- CGSize scrollViewSize = self.bounds.size; +- if (self.contentSize.width <= scrollViewSize.width) { +- contentOffset.x = -(scrollViewSize.width - self.contentSize.width) / 2.0; +- } +- if (self.contentSize.height <= scrollViewSize.height) { +- contentOffset.y = -(scrollViewSize.height - self.contentSize.height) / 2.0; +- } ++ CGSize contentSize = self.contentSize; ++ CGSize boundsSize = self.bounds.size; ++ if (CGSizeEqualToSize(contentSize, CGSizeZero) || ++ CGSizeEqualToSize(boundsSize, CGSizeZero)) { ++ return; + } + ++ CGFloat top = 0, left = 0; ++ if (contentSize.width < boundsSize.width) { ++ left = (boundsSize.width - contentSize.width) * 0.5f; ++ } ++ if (contentSize.height < boundsSize.height) { ++ top = (boundsSize.height - contentSize.height) * 0.5f; ++ } ++ self.contentInset = UIEdgeInsetsMake(top, left, top, left); ++} ++ ++- (void)setContentOffset:(CGPoint)contentOffset ++{ ++ if (_isSetContentOffsetDisabled) { ++ return; ++ } + super.contentOffset = CGPointMake( + RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"), + RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y")); + } + ++- (void)setFrame:(CGRect)frame { ++ [super setFrame:frame]; ++ [self centerContentIfNeeded]; ++} ++ ++- (void)didAddSubview:(UIView *)subview { ++ [super didAddSubview:subview]; ++ [self centerContentIfNeeded]; ++} ++ + - (BOOL)touchesShouldCancelInContentView:(UIView *)view + { + if ([_overridingDelegate respondsToSelector:@selector(touchesShouldCancelInContentView:)]) { +@@ -257,6 +280,10 @@ + } + } + ++- (void)scrollViewDidZoom:(__unused UIScrollView *)scrollView { ++ [self centerContentIfNeeded]; ++} ++ + #pragma mark - + + - (BOOL)isHorizontal:(UIScrollView *)scrollView +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 +--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h ++++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h +@@ -15,5 +15,8 @@ + @property (nonatomic, copy) NSString *title; + @property (nonatomic, copy) RCTDirectEventBlock onRefresh; + @property (nonatomic, weak) UIScrollView *scrollView; ++@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 53bfd04..ff1b1ed 100644 +--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m ++++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +@@ -23,6 +23,7 @@ + UIColor *_titleColor; + CGFloat _progressViewOffset; + BOOL _hasMovedToWindow; ++ UIColor *_customTintColor; + } + + - (instancetype)init +@@ -58,6 +59,12 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) + _isInitialRender = false; + } + ++- (void)didMoveToSuperview ++{ ++ [super didMoveToSuperview]; ++ [self setTintColor:_customTintColor]; ++} ++ + - (void)didMoveToWindow + { + [super didMoveToWindow]; +@@ -221,4 +228,50 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) + } + } + ++// Fix for https://github.com/facebook/react-native/issues/43388 ++// A bug in iOS 17.4 causes the haptic to not play when refreshing if the tintColor ++// is set before the refresh control gets added to the scrollview. We'll call this ++// function whenever the superview changes. We'll also call it if the value of customTintColor ++// changes. ++- (void)setTintColor:(UIColor *)tintColor ++{ ++ if ([self.superview isKindOfClass:[UIScrollView class]] && self.tintColor != tintColor) { ++ [super setTintColor:tintColor]; ++ } ++} ++ ++// This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native ++// libraries to perform a refresh of a scrollview and access the refresh control's onRefresh ++// function. ++- (void)forwarderBeginRefreshing ++{ ++ _refreshingProgrammatically = NO; ++ ++ [self sizeToFit]; ++ ++ if (!self.scrollView) { ++ return; ++ } ++ ++ UIScrollView *scrollView = (UIScrollView *)self.scrollView; ++ ++ [UIView animateWithDuration:0.3 ++ delay:0 ++ options:UIViewAnimationOptionBeginFromCurrentState ++ animations:^(void) { ++ // Whenever we call this method, the scrollview will always be at a position of ++ // -130 or less. Scrolling back to -65 simulates the default behavior of RCTRefreshControl ++ [scrollView setContentOffset:CGPointMake(0, -65)]; ++ } ++ completion:^(__unused BOOL finished) { ++ [super beginRefreshing]; ++ [self setCurrentRefreshingState:super.refreshing]; ++ ++ if (self->_onRefresh) { ++ self->_onRefresh(nil); ++ } ++ } ++ ]; ++} ++ + @end +diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m +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 @@ RCT_EXPORT_MODULE() + + 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 *viewRegistry) { +diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m +index 6f41b5c..9b4f77f 100644 +--- a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m ++++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m +@@ -159,26 +159,8 @@ + 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")); +@@ -433,6 +415,11 @@ static inline void RCTApplyTransformationAccordingLayoutDirection( + // Does nothing + } + ++- (void)setFrame:(CGRect)frame { ++ [super setFrame:frame]; ++ [self centerContentIfNeeded]; ++} ++ + - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex + { + [super insertReactSubview:view atIndex:atIndex]; +@@ -449,6 +436,8 @@ static inline void RCTApplyTransformationAccordingLayoutDirection( + _contentView = view; + RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection); + [_scrollView addSubview:view]; ++ ++ [self centerContentIfNeeded]; + } + } + +@@ -658,9 +647,46 @@ static inline void RCTApplyTransformationAccordingLayoutDirection( + } + + 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. ++ * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/. ++ */ ++-(void)centerContentIfNeeded ++{ ++ if (!_scrollView.centerContent) { ++ return; ++ } ++ ++ CGSize contentSize = self.contentSize; ++ CGSize boundsSize = self.bounds.size; ++ if (CGSizeEqualToSize(contentSize, CGSizeZero) || ++ CGSizeEqualToSize(boundsSize, CGSizeZero)) { ++ return; ++ } ++ ++ CGFloat top = 0, left = 0; ++ if (contentSize.width < boundsSize.width) { ++ left = (boundsSize.width - contentSize.width) * 0.5f; ++ } ++ if (contentSize.height < boundsSize.height) { ++ top = (boundsSize.height - contentSize.height) * 0.5f; ++ } ++ _scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left); ++} ++ + - (void)addScrollListener:(NSObject *)scrollListener + { + [_scrollListeners addObject:scrollListener]; +@@ -939,6 +965,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop) + CGSize contentSize = self.contentSize; + if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) { + _scrollView.contentSize = contentSize; ++ [self centerContentIfNeeded]; + } + } + +@@ -1061,6 +1088,22 @@ RCT_SET_AND_PRESERVE_OFFSET(setShowsHorizontalScrollIndicator, showsHorizontalSc + RCT_SET_AND_PRESERVE_OFFSET(setShowsVerticalScrollIndicator, showsVerticalScrollIndicator, BOOL) + RCT_SET_AND_PRESERVE_OFFSET(setZoomScale, zoomScale, CGFloat); + ++- (void)setScrollIndicatorInsets:(UIEdgeInsets)value ++{ ++ [_scrollView setScrollIndicatorInsets:value]; ++} ++ ++- (UIEdgeInsets)scrollIndicatorInsets ++{ ++ UIEdgeInsets verticalScrollIndicatorInsets = [_scrollView verticalScrollIndicatorInsets]; ++ UIEdgeInsets horizontalScrollIndicatorInsets = [_scrollView horizontalScrollIndicatorInsets]; ++ return UIEdgeInsetsMake( ++ verticalScrollIndicatorInsets.top, ++ horizontalScrollIndicatorInsets.left, ++ verticalScrollIndicatorInsets.bottom, ++ horizontalScrollIndicatorInsets.right); ++} ++ + - (void)setAutomaticallyAdjustsScrollIndicatorInsets:(BOOL)automaticallyAdjusts API_AVAILABLE(ios(13.0)) + { + // `automaticallyAdjustsScrollIndicatorInsets` is available since iOS 13. +diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m +index cd1e7eb..c1d0172 100644 +--- a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m ++++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m +@@ -83,6 +83,7 @@ RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL) + RCT_EXPORT_VIEW_PROPERTY(scrollEventThrottle, NSTimeInterval) + RCT_EXPORT_VIEW_PROPERTY(zoomScale, CGFloat) + RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) ++RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets, UIEdgeInsets) + RCT_EXPORT_VIEW_PROPERTY(verticalScrollIndicatorInsets, UIEdgeInsets) + RCT_EXPORT_VIEW_PROPERTY(scrollToOverflowEnabled, BOOL) + RCT_EXPORT_VIEW_PROPERTY(snapToInterval, int) -- cgit 1.4.1