about summary refs log tree commit diff
path: root/patches/react-native+0.74.1.patch
blob: 5d2900a73136b86c894d953682f073a7c1af1bdf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
index e9b330f..1ecdf0a 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
@@ -16,4 +16,6 @@
 @property (nonatomic, copy) RCTDirectEventBlock onRefresh;
 @property (nonatomic, weak) UIScrollView *scrollView;
 
+- (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..4c32b31 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
@@ -198,9 +198,53 @@ - (void)refreshControlValueChanged
   [self setCurrentRefreshingState:super.refreshing];
   _refreshingProgrammatically = NO;
 
+  if (@available(iOS 17.4, *)) {
+    if (_currentRefreshingState) {
+      UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
+      [feedbackGenerator prepare];
+      [feedbackGenerator impactOccurred];
+    }
+  }
+
   if (_onRefresh) {
     _onRefresh(nil);
   }
 }
 
+/*
+ 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/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();
+      IdleCallbackRunnable currentRunnable = mCurrentIdleCallbackRunnable;
+      if (currentRunnable != null) {
+        currentRunnable.cancel();
       }
 
       mCurrentIdleCallbackRunnable = new IdleCallbackRunnable(frameTimeNanos);