react-native-tvos 0.77.2-2 → 0.77.3-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +2 -2
  2. package/Libraries/Network/RCTDataRequestHandler.mm +17 -3
  3. package/Libraries/Network/RCTFileRequestHandler.mm +17 -3
  4. package/React/Base/RCTVersion.m +2 -2
  5. package/React/DevSupport/RCTPausedInDebuggerOverlayController.mm +3 -5
  6. package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +18 -4
  7. package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +8 -7
  8. package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +22 -3
  9. package/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm +1 -1
  10. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm +1 -1
  11. package/React/Fabric/Surface/RCTFabricSurface.mm +1 -0
  12. package/ReactAndroid/gradle.properties +1 -1
  13. package/ReactAndroid/publish.gradle +1 -1
  14. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +2 -2
  15. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +13 -8
  16. package/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.kt +3 -16
  17. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +2 -2
  18. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt +13 -0
  19. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +0 -3
  20. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt +2 -2
  21. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +43 -0
  22. package/ReactCommon/React-FabricComponents.podspec +1 -1
  23. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  24. package/ReactCommon/react/renderer/components/modal/CMakeLists.txt +4 -1
  25. package/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h +3 -2
  26. package/ReactCommon/react/renderer/components/modal/ModalHostViewState.h +4 -12
  27. package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.h +2 -2
  28. package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.mm +1 -1
  29. package/ReactCommon/react/renderer/components/modal/platform/android/JReactModalHostView.h +38 -0
  30. package/ReactCommon/react/renderer/components/modal/platform/android/ModalHostViewUtils.cpp +18 -0
  31. package/ReactCommon/react/renderer/components/modal/platform/cxx/ModalHostViewUtils.cpp +17 -0
  32. package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp +33 -0
  33. package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h +17 -0
  34. package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp +3 -2
  35. package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h +2 -1
  36. package/ReactCommon/react/runtime/TimerManager.cpp +6 -4
  37. package/ReactCommon/react/runtime/TimerManager.h +3 -1
  38. package/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +9 -5
  39. package/package.json +10 -10
  40. package/sdks/hermesc/osx-bin/hermes +0 -0
  41. package/sdks/hermesc/osx-bin/hermesc +0 -0
  42. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  43. package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
  44. package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
  45. package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
@@ -16,8 +16,8 @@ const version: $ReadOnly<{
16
16
  }> = {
17
17
  major: 0,
18
18
  minor: 77,
19
- patch: 2,
20
- prerelease: '2',
19
+ patch: 3,
20
+ prerelease: '0',
21
21
  };
22
22
 
23
23
  module.exports = {version};
@@ -8,6 +8,8 @@
8
8
  #import <React/RCTDataRequestHandler.h>
9
9
  #import <ReactCommon/RCTTurboModule.h>
10
10
 
11
+ #import <mutex>
12
+
11
13
  #import "RCTNetworkPlugins.h"
12
14
 
13
15
  @interface RCTDataRequestHandler () <RCTTurboModule>
@@ -15,14 +17,22 @@
15
17
 
16
18
  @implementation RCTDataRequestHandler {
17
19
  NSOperationQueue *_queue;
20
+ std::mutex _operationHandlerMutexLock;
18
21
  }
19
22
 
20
23
  RCT_EXPORT_MODULE()
21
24
 
22
25
  - (void)invalidate
23
26
  {
24
- [_queue cancelAllOperations];
25
- _queue = nil;
27
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
28
+ if (_queue) {
29
+ for (NSOperation *operation in _queue.operations) {
30
+ if (!operation.isCancelled && !operation.isFinished) {
31
+ [operation cancel];
32
+ }
33
+ }
34
+ _queue = nil;
35
+ }
26
36
  }
27
37
 
28
38
  - (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -32,6 +42,7 @@ RCT_EXPORT_MODULE()
32
42
 
33
43
  - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
34
44
  {
45
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
35
46
  // Lazy setup
36
47
  if (!_queue) {
37
48
  _queue = [NSOperationQueue new];
@@ -69,7 +80,10 @@ RCT_EXPORT_MODULE()
69
80
 
70
81
  - (void)cancelRequest:(NSOperation *)op
71
82
  {
72
- [op cancel];
83
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
84
+ if (!op.isCancelled && !op.isFinished) {
85
+ [op cancel];
86
+ }
73
87
  }
74
88
 
75
89
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -7,6 +7,8 @@
7
7
 
8
8
  #import <React/RCTFileRequestHandler.h>
9
9
 
10
+ #import <mutex>
11
+
10
12
  #import <MobileCoreServices/MobileCoreServices.h>
11
13
 
12
14
  #import <React/RCTUtils.h>
@@ -19,14 +21,22 @@
19
21
 
20
22
  @implementation RCTFileRequestHandler {
21
23
  NSOperationQueue *_fileQueue;
24
+ std::mutex _operationHandlerMutexLock;
22
25
  }
23
26
 
24
27
  RCT_EXPORT_MODULE()
25
28
 
26
29
  - (void)invalidate
27
30
  {
28
- [_fileQueue cancelAllOperations];
29
- _fileQueue = nil;
31
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
32
+ if (_fileQueue) {
33
+ for (NSOperation *operation in _fileQueue.operations) {
34
+ if (!operation.isCancelled && !operation.isFinished) {
35
+ [operation cancel];
36
+ }
37
+ }
38
+ _fileQueue = nil;
39
+ }
30
40
  }
31
41
 
32
42
  - (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -36,6 +46,7 @@ RCT_EXPORT_MODULE()
36
46
 
37
47
  - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
38
48
  {
49
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
39
50
  // Lazy setup
40
51
  if (!_fileQueue) {
41
52
  _fileQueue = [NSOperationQueue new];
@@ -83,7 +94,10 @@ RCT_EXPORT_MODULE()
83
94
 
84
95
  - (void)cancelRequest:(NSOperation *)op
85
96
  {
86
- [op cancel];
97
+ std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
98
+ if (!op.isCancelled && !op.isFinished) {
99
+ [op cancel];
100
+ }
87
101
  }
88
102
 
89
103
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
@@ -23,8 +23,8 @@ NSDictionary* RCTGetReactNativeVersion(void)
23
23
  __rnVersion = @{
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(77),
26
- RCTVersionPatch: @(2),
27
- RCTVersionPrerelease: @"2",
26
+ RCTVersionPatch: @(3),
27
+ RCTVersionPrerelease: @"0",
28
28
  };
29
29
  });
30
30
  return __rnVersion;
@@ -54,13 +54,11 @@
54
54
  ]];
55
55
 
56
56
  UIButton *resumeButton = [UIButton buttonWithType:UIButtonTypeCustom];
57
- [resumeButton setImage:[UIImage systemImageNamed:@"forward.frame.fill"] forState:UIControlStateNormal];
57
+ UIImage *image = [UIImage systemImageNamed:@"forward.frame.fill"];
58
+ [resumeButton setImage:image forState:UIControlStateNormal];
59
+ [resumeButton setImage:image forState:UIControlStateDisabled];
58
60
  resumeButton.tintColor = [UIColor colorWithRed:0.37 green:0.37 blue:0.37 alpha:1];
59
61
 
60
- resumeButton.configurationUpdateHandler = ^(UIButton *button) {
61
- button.imageView.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
62
- };
63
-
64
62
  resumeButton.enabled = NO;
65
63
  [NSLayoutConstraint activateConstraints:@[
66
64
  [resumeButton.widthAnchor constraintEqualToConstant:48],
@@ -170,10 +170,24 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
170
170
 
171
171
  - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
172
172
  {
173
- [_viewsToBeMounted addObject:@{
174
- kRCTLegacyInteropChildIndexKey : [NSNumber numberWithInteger:index],
175
- kRCTLegacyInteropChildComponentKey : childComponentView
176
- }];
173
+ if (_adapter && index == _adapter.paperView.reactSubviews.count) {
174
+ // This is a new child view that is being added to the end of the children array.
175
+ // After the children is added, we need to call didUpdateReactSubviews to make sure that it is rendered.
176
+ // Without this change, the new child will not be rendered right away because the didUpdateReactSubviews is not
177
+ // called and the `finalizeUpdate` is not invoked.
178
+ if ([childComponentView isKindOfClass:[RCTLegacyViewManagerInteropComponentView class]]) {
179
+ UIView *target = ((RCTLegacyViewManagerInteropComponentView *)childComponentView).contentView;
180
+ [_adapter.paperView insertReactSubview:target atIndex:index];
181
+ } else {
182
+ [_adapter.paperView insertReactSubview:childComponentView atIndex:index];
183
+ }
184
+ [_adapter.paperView didUpdateReactSubviews];
185
+ } else {
186
+ [_viewsToBeMounted addObject:@{
187
+ kRCTLegacyInteropChildIndexKey : [NSNumber numberWithInteger:index],
188
+ kRCTLegacyInteropChildComponentKey : childComponentView
189
+ }];
190
+ }
177
191
  }
178
192
 
179
193
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
@@ -118,7 +118,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
118
118
  BOOL _shouldAnimatePresentation;
119
119
  BOOL _shouldPresent;
120
120
  BOOL _isPresented;
121
- UIView *_modalContentsSnapshot;
122
121
  #if TARGET_OS_TV
123
122
  UITapGestureRecognizer *_menuButtonGestureRecognizer;
124
123
  RCTTVRemoteHandler *_tvRemoteHandler;
@@ -144,12 +143,16 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
144
143
 
145
144
  #if TARGET_OS_TV
146
145
  - (void)menuButtonPressed {
147
- UIView *snapshot = _modalContentsSnapshot;
148
- [self.viewController.view addSubview:snapshot];
146
+ _isPresented = NO;
147
+ // To animate dismissal of view controller, snapshot of
148
+ // view hierarchy needs to be added to the UIViewController.
149
+ UIView *snapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
150
+ if (_shouldPresent) {
151
+ [self.viewController.view addSubview:snapshot];
152
+ }
149
153
  [self dismissViewController:self.viewController
150
154
  animated:_shouldAnimatePresentation
151
155
  completion:^{
152
- [snapshot removeFromSuperview];
153
156
  auto eventEmitter = [self modalEventEmitter];
154
157
  if (eventEmitter) {
155
158
  eventEmitter->onDismiss(ModalHostViewEventEmitter::OnDismiss{});
@@ -196,7 +199,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
196
199
  animated:(BOOL)animated
197
200
  completion:(void (^)(void))completion
198
201
  {
199
- _modalContentsSnapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
200
202
  [modalViewController dismissViewControllerAnimated:animated completion:completion];
201
203
  }
202
204
 
@@ -222,8 +224,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
222
224
  _isPresented = NO;
223
225
  // To animate dismissal of view controller, snapshot of
224
226
  // view hierarchy needs to be added to the UIViewController.
225
- UIView *snapshot = _modalContentsSnapshot;
226
-
227
+ UIView *snapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
227
228
  if (_shouldPresent) {
228
229
  [self.viewController.view addSubview:snapshot];
229
230
  }
@@ -565,6 +565,17 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
565
565
  return metrics;
566
566
  }
567
567
 
568
+ - (ScrollViewEventEmitter::EndDragMetrics)_scrollViewMetricsWithVelocity:(CGPoint)velocity
569
+ andTargetContentOffset:(CGPoint)targetContentOffset
570
+ {
571
+ ScrollViewEventEmitter::EndDragMetrics metrics = [self _scrollViewMetrics];
572
+ metrics.targetContentOffset.x = targetContentOffset.x;
573
+ metrics.targetContentOffset.y = targetContentOffset.y;
574
+ metrics.velocity.x = velocity.x;
575
+ metrics.velocity.y = velocity.y;
576
+ return metrics;
577
+ }
578
+
568
579
  - (void)_updateStateWithContentOffset
569
580
  {
570
581
  if (!_state) {
@@ -620,6 +631,14 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
620
631
  targetContentOffset->y = scrollView.contentOffset.y + travel * _endDraggingSensitivityMultiplier;
621
632
  }
622
633
  }
634
+
635
+ if (!_eventEmitter) {
636
+ return;
637
+ }
638
+
639
+ auto metrics = [self _scrollViewMetricsWithVelocity:velocity andTargetContentOffset:*targetContentOffset];
640
+
641
+ static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag(metrics);
623
642
  }
624
643
 
625
644
  - (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view
@@ -690,8 +709,6 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
690
709
  return;
691
710
  }
692
711
 
693
- static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag([self _scrollViewMetrics]);
694
-
695
712
  [self _updateStateWithContentOffset];
696
713
 
697
714
  if (!decelerate) {
@@ -788,7 +805,9 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
788
805
  return;
789
806
  }
790
807
 
791
- static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag([self _scrollViewMetrics]);
808
+ auto metrics = [self _scrollViewMetricsWithVelocity:{} andTargetContentOffset:{}];
809
+ static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag(metrics);
810
+
792
811
  [self _updateStateWithContentOffset];
793
812
  }
794
813
 
@@ -68,7 +68,7 @@ using namespace facebook::react;
68
68
  const auto &newSwitchProps = static_cast<const SwitchProps &>(*props);
69
69
 
70
70
  // `value`
71
- if (oldSwitchProps.value != newSwitchProps.value) {
71
+ if (!_isInitialValueSet || oldSwitchProps.value != newSwitchProps.value) {
72
72
  BOOL shouldAnimate = _isInitialValueSet == YES;
73
73
  [_switchView setOn:newSwitchProps.value animated:shouldAnimate];
74
74
  }
@@ -223,7 +223,7 @@ UITextContentType RCTUITextContentTypeFromString(const std::string &contentType)
223
223
  }
224
224
 
225
225
  #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 170000 /* __IPHONE_17_0 */
226
- if (@available(iOS 17.0, *)) {
226
+ if (@available(iOS 17.0, tvOS 17.0, *)) {
227
227
  [mutableContentTypeMap addEntriesFromDictionary:@{
228
228
  @"creditCardExpiration" : UITextContentTypeCreditCardExpiration,
229
229
  @"creditCardExpirationMonth" : UITextContentTypeCreditCardExpirationMonth,
@@ -143,6 +143,7 @@ using namespace facebook::react;
143
143
 
144
144
  if (!_view) {
145
145
  _view = [[RCTSurfaceView alloc] initWithSurface:(RCTSurface *)self];
146
+ [self _updateLayoutContext];
146
147
  _touchHandler = [RCTSurfaceTouchHandler new];
147
148
  [_touchHandler attachToView:_view];
148
149
  }
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.77.2-2
1
+ VERSION_NAME=0.77.3-0
2
2
  react.internal.publishingGroup=io.github.react-native-tvos
3
3
 
4
4
  android.useAndroidX=true
@@ -20,7 +20,7 @@ def sonatypeUsername = findProperty('SONATYPE_USERNAME')
20
20
  def sonatypePassword = findProperty('SONATYPE_PASSWORD')
21
21
 
22
22
  def reactAndroidProjectDir = project(':packages:react-native:ReactAndroid').projectDir
23
- def mavenTempLocalUrl = 'file:///Users/expo/workingdir/build/maven_local'
23
+ def mavenTempLocalUrl = 'file:///var/folders/xp/yw_lp59x05d2mp0g0n2f_d240000gn/T/eas-build-workingdir/build/maven_local'
24
24
  // Rewritten when copying this to ReactAndroid/publish.gradle
25
25
 
26
26
  publishing {
@@ -1409,14 +1409,14 @@ public class ReactInstanceManager {
1409
1409
  new RuntimeException(
1410
1410
  "detachRootViewFromInstance called with ReactRootView with invalid id"));
1411
1411
  }
1412
-
1413
- clearReactRoot(reactRoot);
1414
1412
  } else {
1415
1413
  reactContext
1416
1414
  .getCatalystInstance()
1417
1415
  .getJSModule(AppRegistry.class)
1418
1416
  .unmountApplicationComponentAtRootTag(reactRoot.getRootViewTag());
1419
1417
  }
1418
+
1419
+ clearReactRoot(reactRoot);
1420
1420
  }
1421
1421
 
1422
1422
  @ThreadConfined(UI)
@@ -171,7 +171,7 @@ public class FabricUIManager
171
171
  private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
172
172
 
173
173
  private boolean mMountNotificationScheduled = false;
174
- private final List<Integer> mMountedSurfaceIds = new ArrayList<>();
174
+ private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
175
175
 
176
176
  @ThreadConfined(UI)
177
177
  @NonNull
@@ -1261,12 +1261,15 @@ public class FabricUIManager
1261
1261
 
1262
1262
  // Collect surface IDs for all the mount items
1263
1263
  for (MountItem mountItem : mountItems) {
1264
- if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) {
1265
- mMountedSurfaceIds.add(mountItem.getSurfaceId());
1264
+ if (mountItem != null
1265
+ && !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
1266
+ mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
1266
1267
  }
1267
1268
  }
1268
1269
 
1269
- if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) {
1270
+ if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
1271
+ mMountNotificationScheduled = true;
1272
+
1270
1273
  // Notify mount when the effects are visible and prevent mount hooks to
1271
1274
  // delay paint.
1272
1275
  UiThreadUtil.getUiThreadHandler()
@@ -1276,17 +1279,19 @@ public class FabricUIManager
1276
1279
  public void run() {
1277
1280
  mMountNotificationScheduled = false;
1278
1281
 
1282
+ // Create a copy in case mount hooks trigger more mutations
1283
+ final List<Integer> surfaceIdsToReportMount =
1284
+ mSurfaceIdsWithPendingMountNotification;
1285
+ mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
1286
+
1279
1287
  final @Nullable FabricUIManagerBinding binding = mBinding;
1280
1288
  if (binding == null || mDestroyed) {
1281
- mMountedSurfaceIds.clear();
1282
1289
  return;
1283
1290
  }
1284
1291
 
1285
- for (int surfaceId : mMountedSurfaceIds) {
1292
+ for (int surfaceId : surfaceIdsToReportMount) {
1286
1293
  binding.reportMount(surfaceId);
1287
1294
  }
1288
-
1289
- mMountedSurfaceIds.clear();
1290
1295
  }
1291
1296
  });
1292
1297
  }
@@ -13,8 +13,6 @@ import android.os.Build
13
13
  import android.view.View
14
14
  import android.view.WindowInsetsController
15
15
  import android.view.WindowManager
16
- import androidx.core.view.ViewCompat
17
- import androidx.core.view.WindowInsetsCompat
18
16
  import com.facebook.common.logging.FLog
19
17
  import com.facebook.fbreact.specs.NativeStatusBarManagerAndroidSpec
20
18
  import com.facebook.react.bridge.GuardedRunnable
@@ -23,6 +21,7 @@ import com.facebook.react.bridge.ReactApplicationContext
23
21
  import com.facebook.react.bridge.UiThreadUtil
24
22
  import com.facebook.react.common.ReactConstants
25
23
  import com.facebook.react.module.annotations.ReactModule
24
+ import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
26
25
  import com.facebook.react.uimanager.PixelUtil
27
26
  import com.facebook.react.views.view.setStatusBarTranslucency
28
27
  import com.facebook.react.views.view.setStatusBarVisibility
@@ -34,29 +33,17 @@ public class StatusBarModule(reactContext: ReactApplicationContext?) :
34
33
 
35
34
  @Suppress("DEPRECATION")
36
35
  override fun getTypedExportedConstants(): Map<String, Any> {
36
+ val currentActivity = reactApplicationContext.currentActivity
37
37
  val statusBarColor =
38
38
  currentActivity?.window?.statusBarColor?.let { color ->
39
39
  String.format("#%06X", 0xFFFFFF and color)
40
40
  } ?: "black"
41
41
  return mapOf(
42
- HEIGHT_KEY to PixelUtil.toDIPFromPixel(getStatusBarHeightPx()),
42
+ HEIGHT_KEY to PixelUtil.toDIPFromPixel(getStatusBarHeightPx(currentActivity).toFloat()),
43
43
  DEFAULT_BACKGROUND_COLOR_KEY to statusBarColor,
44
44
  )
45
45
  }
46
46
 
47
- @Suppress("DEPRECATION")
48
- private fun getStatusBarHeightPx(): Float {
49
- val windowInsets =
50
- currentActivity?.window?.decorView?.let(ViewCompat::getRootWindowInsets) ?: return 0f
51
- return windowInsets
52
- .getInsets(
53
- WindowInsetsCompat.Type.statusBars() or
54
- WindowInsetsCompat.Type.navigationBars() or
55
- WindowInsetsCompat.Type.displayCutout())
56
- .top
57
- .toFloat()
58
- }
59
-
60
47
  @Suppress("DEPRECATION")
61
48
  override fun setColor(colorDouble: Double, animated: Boolean) {
62
49
  val color = colorDouble.toInt()
@@ -17,6 +17,6 @@ public class ReactNativeVersion {
17
17
  public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
18
18
  "major", 0,
19
19
  "minor", 77,
20
- "patch", 2,
21
- "prerelease", "2");
20
+ "patch", 3,
21
+ "prerelease", "0");
22
22
  }
@@ -7,9 +7,12 @@
7
7
 
8
8
  package com.facebook.react.uimanager
9
9
 
10
+ import android.app.Activity
10
11
  import android.content.Context
11
12
  import android.util.DisplayMetrics
12
13
  import android.view.WindowManager
14
+ import androidx.core.view.ViewCompat
15
+ import androidx.core.view.WindowInsetsCompat
13
16
  import com.facebook.react.bridge.WritableMap
14
17
  import com.facebook.react.bridge.WritableNativeMap
15
18
 
@@ -99,4 +102,14 @@ public object DisplayMetricsHolder {
99
102
  putDouble("fontScale", fontScale)
100
103
  putDouble("densityDpi", displayMetrics.densityDpi.toDouble())
101
104
  }
105
+
106
+ internal fun getStatusBarHeightPx(activity: Activity?): Int {
107
+ val windowInsets = activity?.window?.decorView?.let(ViewCompat::getRootWindowInsets) ?: return 0
108
+ return windowInsets
109
+ .getInsets(
110
+ WindowInsetsCompat.Type.statusBars() or
111
+ WindowInsetsCompat.Type.navigationBars() or
112
+ WindowInsetsCompat.Type.displayCutout())
113
+ .top
114
+ }
102
115
  }
@@ -671,9 +671,6 @@ public class NativeViewHierarchyManager {
671
671
  View rootView = mTagsToViews.get(rootViewTag);
672
672
  dropView(rootView);
673
673
  mRootTags.delete(rootViewTag);
674
- if (rootView != null) {
675
- rootView.setId(View.NO_ID);
676
- }
677
674
  }
678
675
 
679
676
  /**
@@ -136,10 +136,10 @@ public data class BorderRadiusStyle(
136
136
  (startStart ?: topStart ?: topLeft ?: uniform)?.resolve(width, height)
137
137
  ?: zeroRadii,
138
138
  bottomLeft =
139
- (endEnd ?: bottomStart ?: bottomRight ?: uniform)?.resolve(width, height)
139
+ (endEnd ?: bottomEnd ?: bottomRight ?: uniform)?.resolve(width, height)
140
140
  ?: zeroRadii,
141
141
  bottomRight =
142
- (startEnd ?: bottomEnd ?: bottomLeft ?: uniform)?.resolve(width, height)
142
+ (startEnd ?: bottomStart ?: bottomLeft ?: uniform)?.resolve(width, height)
143
143
  ?: zeroRadii,
144
144
  width = width,
145
145
  height = height,
@@ -40,6 +40,8 @@ import com.facebook.react.common.ReactConstants
40
40
  import com.facebook.react.common.annotations.VisibleForTesting
41
41
  import com.facebook.react.config.ReactFeatureFlags
42
42
  import com.facebook.react.modules.core.ReactAndroidHWInputDeviceHelper
43
+ import com.facebook.react.uimanager.DisplayMetricsHolder
44
+ import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
43
45
  import com.facebook.react.uimanager.JSPointerDispatcher
44
46
  import com.facebook.react.uimanager.JSTouchDispatcher
45
47
  import com.facebook.react.uimanager.PixelUtil.pxToDp
@@ -52,6 +54,7 @@ import com.facebook.react.views.common.ContextUtils
52
54
  import com.facebook.react.views.view.setStatusBarTranslucency
53
55
  import com.facebook.react.views.modal.ReactModalHostView.DialogRootViewGroup
54
56
  import com.facebook.react.views.view.ReactViewGroup
57
+ import com.facebook.yoga.annotations.DoNotStrip
55
58
  import java.util.Objects
56
59
 
57
60
 
@@ -118,6 +121,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
118
121
 
119
122
  init {
120
123
  context.addLifecycleEventListener(this)
124
+ initStatusBarHeight(context)
121
125
  dialogRootViewGroup = DialogRootViewGroup(context)
122
126
  }
123
127
 
@@ -214,6 +218,15 @@ public class ReactModalHostView(context: ThemedReactContext) :
214
218
 
215
219
  private fun getCurrentActivity(): Activity? = (context as ThemedReactContext).currentActivity
216
220
 
221
+ private fun isFlagSecureSet(activity: Activity?): Boolean {
222
+ if (activity == null) {
223
+ return false
224
+ }
225
+
226
+ val flags = activity.window.attributes.flags
227
+ return (flags and WindowManager.LayoutParams.FLAG_SECURE) != 0
228
+ }
229
+
217
230
  /**
218
231
  * showOrUpdate will display the Dialog. It is called by the manager once all properties are set
219
232
  * because we need to know all of them before creating the Dialog. It is also smart during updates
@@ -309,6 +322,11 @@ public class ReactModalHostView(context: ThemedReactContext) :
309
322
  if (hardwareAccelerated) {
310
323
  newDialog.window?.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
311
324
  }
325
+ val flagSecureSet = isFlagSecureSet(currentActivity)
326
+ if (flagSecureSet) {
327
+ newDialog.window?.setFlags(
328
+ WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
329
+ }
312
330
  if (currentActivity?.isFinishing == false) {
313
331
  newDialog.show()
314
332
  updateSystemAppearance()
@@ -404,6 +422,30 @@ public class ReactModalHostView(context: ThemedReactContext) :
404
422
  public fun onRequestClose(dialog: DialogInterface?)
405
423
  }
406
424
 
425
+ private companion object {
426
+ private const val TAG = "ReactModalHost"
427
+
428
+ // We store the status bar height to be able to properly position
429
+ // the modal on the first render.
430
+ private var statusBarHeight = 0
431
+
432
+ private fun initStatusBarHeight(reactContext: ReactContext) {
433
+ statusBarHeight = getStatusBarHeightPx(reactContext.currentActivity)
434
+ }
435
+
436
+ @JvmStatic
437
+ @DoNotStrip
438
+ private fun getScreenDisplayMetricsWithoutInsets(): Long {
439
+ val displayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics()
440
+ return encodeFloatsToLong(
441
+ displayMetrics.widthPixels.toFloat().pxToDp(),
442
+ (displayMetrics.heightPixels - statusBarHeight).toFloat().pxToDp())
443
+ }
444
+
445
+ private fun encodeFloatsToLong(width: Float, height: Float): Long =
446
+ (width.toRawBits().toLong()) shl 32 or (height.toRawBits().toLong())
447
+ }
448
+
407
449
  /**
408
450
  * DialogRootViewGroup is the ViewGroup which contains all the children of a Modal. It gets all
409
451
  * child information forwarded from [ReactModalHostView] and uses that to create children. It is
@@ -417,6 +459,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
417
459
  */
418
460
  public class DialogRootViewGroup internal constructor(context: Context?) :
419
461
  ReactViewGroup(context), RootView {
462
+
420
463
  internal var stateWrapper: StateWrapper? = null
421
464
  internal var eventDispatcher: EventDispatcher? = null
422
465
 
@@ -112,7 +112,7 @@ Pod::Spec.new do |s|
112
112
  ss.subspec "modal" do |sss|
113
113
  sss.dependency folly_dep_name, folly_version
114
114
  sss.compiler_flags = folly_compiler_flags
115
- sss.source_files = "react/renderer/components/modal/**/*.{m,mm,cpp,h}"
115
+ sss.source_files = "react/renderer/components/modal/*.{m,mm,cpp,h}"
116
116
  sss.exclude_files = "react/renderer/components/modal/tests"
117
117
  sss.header_dir = "react/renderer/components/modal"
118
118
  end
@@ -17,8 +17,8 @@ namespace facebook::react {
17
17
  constexpr struct {
18
18
  int32_t Major = 0;
19
19
  int32_t Minor = 77;
20
- int32_t Patch = 2;
21
- std::string_view Prerelease = "2";
20
+ int32_t Patch = 3;
21
+ std::string_view Prerelease = "0";
22
22
  } ReactNativeVersion;
23
23
 
24
24
  } // namespace facebook::react
@@ -14,7 +14,10 @@ add_compile_options(
14
14
  -Wpedantic
15
15
  -DLOG_TAG=\"Fabric\")
16
16
 
17
- file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS *.cpp)
17
+ file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS
18
+ *.cpp
19
+ platform/android/*.cpp)
20
+
18
21
  add_library(rrc_modal STATIC ${rrc_modal_SRC})
19
22
 
20
23
  target_include_directories(rrc_modal PUBLIC ${REACT_COMMON_DIR})
@@ -30,8 +30,9 @@ class ModalHostViewComponentDescriptor final
30
30
  *shadowNode.getState())
31
31
  .getData();
32
32
 
33
- layoutableShadowNode.setSize(
34
- Size{stateData.screenSize.width, stateData.screenSize.height});
33
+ layoutableShadowNode.setSize(Size{
34
+ .width = stateData.screenSize.width,
35
+ .height = stateData.screenSize.height});
35
36
  layoutableShadowNode.setPositionType(YGPositionTypeAbsolute);
36
37
 
37
38
  ConcreteComponentDescriptor::adopt(shadowNode);
@@ -9,15 +9,12 @@
9
9
 
10
10
  #include <react/renderer/core/graphicsConversions.h>
11
11
  #include <react/renderer/graphics/Float.h>
12
+ #include "ModalHostViewUtils.h"
12
13
 
13
14
  #ifdef ANDROID
14
15
  #include <folly/dynamic.h>
15
16
  #endif
16
17
 
17
- #if defined(__APPLE__) && TARGET_OS_IOS
18
- #include "ModalHostViewUtils.h"
19
- #endif
20
-
21
18
  namespace facebook::react {
22
19
 
23
20
  /*
@@ -27,12 +24,7 @@ class ModalHostViewState final {
27
24
  public:
28
25
  using Shared = std::shared_ptr<const ModalHostViewState>;
29
26
 
30
- #if defined(__APPLE__) && TARGET_OS_IOS
31
- ModalHostViewState() : screenSize(RCTModalHostViewScreenSize()) {
32
- #else
33
- ModalHostViewState(){
34
- #endif
35
- };
27
+ ModalHostViewState() : screenSize(ModalHostViewScreenSize()) {}
36
28
  ModalHostViewState(Size screenSize_) : screenSize(screenSize_){};
37
29
 
38
30
  #ifdef ANDROID
@@ -40,8 +32,8 @@ class ModalHostViewState final {
40
32
  const ModalHostViewState& previousState,
41
33
  folly::dynamic data)
42
34
  : screenSize(Size{
43
- (Float)data["screenWidth"].getDouble(),
44
- (Float)data["screenHeight"].getDouble()}){};
35
+ .width = (Float)data["screenWidth"].getDouble(),
36
+ .height = (Float)data["screenHeight"].getDouble()}){};
45
37
  #endif
46
38
 
47
39
  const Size screenSize{};
@@ -7,10 +7,10 @@
7
7
 
8
8
  #pragma once
9
9
 
10
- #include <react/renderer/core/graphicsConversions.h>
10
+ #include <react/renderer/graphics/Size.h>
11
11
 
12
12
  namespace facebook::react {
13
13
 
14
- Size RCTModalHostViewScreenSize(void);
14
+ Size ModalHostViewScreenSize(void);
15
15
 
16
16
  } // namespace facebook::react
@@ -11,7 +11,7 @@
11
11
 
12
12
  namespace facebook::react {
13
13
 
14
- Size RCTModalHostViewScreenSize(void)
14
+ Size ModalHostViewScreenSize(void)
15
15
  {
16
16
  CGSize screenSize = RCTScreenSize();
17
17
  return {screenSize.width, screenSize.height};
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <react/renderer/graphics/Size.h>
12
+
13
+ namespace facebook::react {
14
+
15
+ class JReactModalHostView
16
+ : public facebook::jni::JavaClass<JReactModalHostView> {
17
+ public:
18
+ static auto constexpr kJavaDescriptor =
19
+ "Lcom/facebook/react/views/modal/ReactModalHostView;";
20
+
21
+ static Size getDisplayMetrics() {
22
+ static auto method =
23
+ JReactModalHostView::javaClassStatic()->getStaticMethod<jlong()>(
24
+ "getScreenDisplayMetricsWithoutInsets");
25
+ auto result = method(javaClassStatic());
26
+
27
+ // Inspired from yogaMeassureToSize from conversions.h
28
+ int32_t wBits = 0xFFFFFFFF & (result >> 32);
29
+ int32_t hBits = 0xFFFFFFFF & result;
30
+
31
+ auto* measuredWidth = reinterpret_cast<float*>(&wBits);
32
+ auto* measuredHeight = reinterpret_cast<float*>(&hBits);
33
+
34
+ return Size{.width = *measuredWidth, .height = *measuredHeight};
35
+ }
36
+ };
37
+
38
+ } // namespace facebook::react
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include <react/renderer/components/modal/ModalHostViewUtils.h>
9
+ #include <react/renderer/graphics/Size.h>
10
+ #include "JReactModalHostView.h"
11
+
12
+ namespace facebook::react {
13
+
14
+ Size ModalHostViewScreenSize() {
15
+ return JReactModalHostView::getDisplayMetrics();
16
+ }
17
+
18
+ } // namespace facebook::react
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include <react/renderer/components/modal/ModalHostViewUtils.h>
9
+ #include <react/renderer/graphics/Size.h>
10
+
11
+ namespace facebook::react {
12
+
13
+ Size ModalHostViewScreenSize() {
14
+ return Size{0, 0};
15
+ }
16
+
17
+ } // namespace facebook::react
@@ -76,6 +76,39 @@ EventPayloadType ScrollEvent::getType() const {
76
76
  return EventPayloadType::ScrollEvent;
77
77
  }
78
78
 
79
+ jsi::Value ScrollEndDragEvent::asJSIValue(jsi::Runtime& runtime) const {
80
+ auto payload = ScrollEvent::asJSIValue(runtime).asObject(runtime);
81
+
82
+ {
83
+ auto targetContentOffsetObj = jsi::Object(runtime);
84
+ targetContentOffsetObj.setProperty(runtime, "x", targetContentOffset.x);
85
+ targetContentOffsetObj.setProperty(runtime, "y", targetContentOffset.y);
86
+ payload.setProperty(runtime, "targetContentOffset", targetContentOffsetObj);
87
+ }
88
+
89
+ {
90
+ auto velocityObj = jsi::Object(runtime);
91
+ velocityObj.setProperty(runtime, "x", velocity.x);
92
+ velocityObj.setProperty(runtime, "y", velocity.y);
93
+ payload.setProperty(runtime, "velocity", velocityObj);
94
+ }
95
+
96
+ return payload;
97
+ }
98
+
99
+ folly::dynamic ScrollEndDragEvent::asDynamic() const {
100
+ auto metrics = ScrollEvent::asDynamic();
101
+
102
+ auto targetContentOffsetObj = folly::dynamic::object(
103
+ "x", targetContentOffset.x)("y", targetContentOffset.y);
104
+ metrics["targetContentOffset"] = std::move(targetContentOffsetObj);
105
+
106
+ auto velocityObj = folly::dynamic::object("x", velocity.x)("y", velocity.y);
107
+ metrics["velocity"] = std::move(velocityObj);
108
+
109
+ return metrics;
110
+ };
111
+
79
112
  #if RN_DEBUG_STRING_CONVERTIBLE
80
113
 
81
114
  std::string getDebugName(const ScrollEvent& /*scrollEvent*/) {
@@ -37,6 +37,23 @@ struct ScrollEvent : public EventPayload {
37
37
  EventPayloadType getType() const override;
38
38
  };
39
39
 
40
+ struct ScrollEndDragEvent : public ScrollEvent {
41
+ Point targetContentOffset;
42
+ Point velocity;
43
+
44
+ ScrollEndDragEvent() = default;
45
+
46
+ ScrollEndDragEvent(const ScrollEvent& scrollEvent)
47
+ : ScrollEvent(scrollEvent), targetContentOffset({}), velocity({}) {}
48
+
49
+ folly::dynamic asDynamic() const;
50
+
51
+ /*
52
+ * EventPayload implementations
53
+ */
54
+ jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
55
+ };
56
+
40
57
  #if RN_DEBUG_STRING_CONVERTIBLE
41
58
 
42
59
  std::string getDebugName(const ScrollEvent& scrollEvent);
@@ -25,8 +25,9 @@ void ScrollViewEventEmitter::onScrollBeginDrag(
25
25
  }
26
26
 
27
27
  void ScrollViewEventEmitter::onScrollEndDrag(
28
- const ScrollEvent& scrollEvent) const {
29
- dispatchScrollViewEvent("scrollEndDrag", scrollEvent);
28
+ const ScrollEndDragEvent& scrollEvent) const {
29
+ dispatchEvent(
30
+ "scrollEndDrag", std::make_shared<ScrollEndDragEvent>(scrollEvent));
30
31
  }
31
32
 
32
33
  void ScrollViewEventEmitter::onMomentumScrollBegin(
@@ -21,10 +21,11 @@ class ScrollViewEventEmitter : public ViewEventEmitter {
21
21
  using ViewEventEmitter::ViewEventEmitter;
22
22
 
23
23
  using Metrics = ScrollEvent;
24
+ using EndDragMetrics = ScrollEndDragEvent;
24
25
 
25
26
  void onScroll(const ScrollEvent& scrollEvent) const;
26
27
  void onScrollBeginDrag(const ScrollEvent& scrollEvent) const;
27
- void onScrollEndDrag(const ScrollEvent& scrollEvent) const;
28
+ void onScrollEndDrag(const ScrollEndDragEvent& scrollEvent) const;
28
29
  void onMomentumScrollBegin(const ScrollEvent& scrollEvent) const;
29
30
  void onMomentumScrollEnd(const ScrollEvent& scrollEvent) const;
30
31
  void onScrollToTop(const ScrollEvent& scrollEvent) const;
@@ -300,8 +300,9 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
300
300
  }
301
301
 
302
302
  if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) {
303
- // Do not throw any error to match web spec
304
- return timerIndex_++;
303
+ // Do not throw any error to match web spec; instead return 0, an
304
+ // invalid timer id
305
+ return 0;
305
306
  }
306
307
 
307
308
  auto callback = args[0].getObject(rt).getFunction(rt);
@@ -358,8 +359,9 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
358
359
  }
359
360
 
360
361
  if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) {
361
- throw jsi::JSError(
362
- rt, "The first argument to setInterval must be a function.");
362
+ // Do not throw any error to match web spec; instead return 0, an
363
+ // invalid timer id
364
+ return 0;
363
365
  }
364
366
  auto callback = args[0].getObject(rt).getFunction(rt);
365
367
  auto delay = count > 1
@@ -93,7 +93,9 @@ class TimerManager {
93
93
 
94
94
  // Each timeout that is registered on this queue gets a sequential id. This
95
95
  // is the global count from which those are assigned.
96
- TimerHandle timerIndex_{0};
96
+ // As per WHATWG HTML 8.6.1 (Timers) ids must be greater than zero, i.e. start
97
+ // at 1
98
+ TimerHandle timerIndex_{1};
97
99
 
98
100
  // The React Native microtask queue is used to back public APIs including
99
101
  // `queueMicrotask`, `clearImmediate`, and `setImmediate` (which is used by
@@ -266,7 +266,9 @@ TEST_F(ReactInstanceTest, testSetTimeoutWithoutDelay) {
266
266
  EXPECT_CALL(
267
267
  *mockRegistry_,
268
268
  createTimer(_, 0)); // If delay is not provided, it should use 0
269
- eval("setTimeout(() => {});");
269
+ auto val = eval("setTimeout(() => {});");
270
+ expectNoError();
271
+ EXPECT_EQ(val.asNumber(), 1); // First timer id should start at 1
270
272
  }
271
273
 
272
274
  TEST_F(ReactInstanceTest, testSetTimeoutWithPassThroughArgs) {
@@ -298,8 +300,9 @@ TEST_F(ReactInstanceTest, testSetTimeoutWithInvalidArgs) {
298
300
  getErrorMessage("setTimeout();"),
299
301
  "setTimeout must be called with at least one argument (the function to call).");
300
302
 
301
- eval("setTimeout('invalid');");
303
+ auto val = eval("setTimeout('invalid')");
302
304
  expectNoError();
305
+ EXPECT_EQ(val.asNumber(), 0);
303
306
 
304
307
  eval("setTimeout(() => {}, 'invalid');");
305
308
  expectNoError();
@@ -416,9 +419,10 @@ TEST_F(ReactInstanceTest, testSetIntervalWithInvalidArgs) {
416
419
  EXPECT_EQ(
417
420
  getErrorMessage("setInterval();"),
418
421
  "setInterval must be called with at least one argument (the function to call).");
419
- EXPECT_EQ(
420
- getErrorMessage("setInterval('invalid', 100);"),
421
- "The first argument to setInterval must be a function.");
422
+
423
+ auto val = eval("setInterval('invalid', 100)");
424
+ expectNoError();
425
+ EXPECT_EQ(val.asNumber(), 0);
422
426
  }
423
427
 
424
428
  TEST_F(ReactInstanceTest, testClearInterval) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-tvos",
3
- "version": "0.77.2-2",
3
+ "version": "0.77.3-0",
4
4
  "description": "A framework for building native apps using React",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -112,13 +112,13 @@
112
112
  },
113
113
  "dependencies": {
114
114
  "@jest/create-cache-key-function": "^29.6.3",
115
- "@react-native/assets-registry": "0.77.2",
116
- "@react-native/codegen": "0.77.2",
117
- "@react-native/community-cli-plugin": "0.77.2",
118
- "@react-native/gradle-plugin": "0.77.2",
119
- "@react-native/js-polyfills": "0.77.2",
120
- "@react-native/normalize-colors": "0.77.2",
121
- "@react-native-tvos/virtualized-lists": "0.77.2-2",
115
+ "@react-native/assets-registry": "0.77.3",
116
+ "@react-native/codegen": "0.77.3",
117
+ "@react-native/community-cli-plugin": "0.77.3",
118
+ "@react-native/gradle-plugin": "0.77.3",
119
+ "@react-native/js-polyfills": "0.77.3",
120
+ "@react-native/normalize-colors": "0.77.3",
121
+ "@react-native-tvos/virtualized-lists": "0.77.3-0",
122
122
  "abort-controller": "^3.0.0",
123
123
  "anser": "^1.4.9",
124
124
  "ansi-regex": "^5.0.0",
@@ -134,8 +134,8 @@
134
134
  "jest-environment-node": "^29.6.3",
135
135
  "jsc-android": "^250231.0.0",
136
136
  "memoize-one": "^5.0.0",
137
- "metro-runtime": "^0.81.3",
138
- "metro-source-map": "^0.81.3",
137
+ "metro-runtime": "^0.81.5",
138
+ "metro-source-map": "^0.81.5",
139
139
  "nullthrows": "^1.1.1",
140
140
  "pretty-format": "^29.7.0",
141
141
  "promise": "^8.3.0",
Binary file
Binary file
Binary file
Binary file