react-native 0.77.1 → 0.77.3

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 (55) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Image/Image.android.js +2 -0
  3. package/Libraries/Image/ImageViewNativeComponent.js +3 -4
  4. package/Libraries/Network/RCTDataRequestHandler.mm +17 -3
  5. package/Libraries/Network/RCTFileRequestHandler.mm +17 -3
  6. package/React/Base/RCTVersion.m +1 -1
  7. package/React/DevSupport/RCTPausedInDebuggerOverlayController.mm +3 -5
  8. package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +18 -4
  9. package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +1 -4
  10. package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +22 -3
  11. package/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm +1 -1
  12. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +1 -7
  13. package/React/Fabric/Surface/RCTFabricSurface.mm +1 -0
  14. package/ReactAndroid/gradle.properties +1 -1
  15. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +2 -2
  16. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +21 -10
  17. package/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.kt +3 -16
  18. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  19. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt +13 -0
  20. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +0 -3
  21. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt +2 -2
  22. package/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.kt +1 -1
  23. package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +39 -0
  24. package/ReactCommon/React-FabricComponents.podspec +1 -1
  25. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  26. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm +9 -0
  27. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +24 -13
  28. package/ReactCommon/react/renderer/components/modal/CMakeLists.txt +4 -1
  29. package/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h +3 -2
  30. package/ReactCommon/react/renderer/components/modal/ModalHostViewState.h +4 -12
  31. package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.h +2 -2
  32. package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.mm +1 -1
  33. package/ReactCommon/react/renderer/components/modal/platform/android/JReactModalHostView.h +38 -0
  34. package/ReactCommon/react/renderer/components/modal/platform/android/ModalHostViewUtils.cpp +18 -0
  35. package/ReactCommon/react/renderer/components/modal/platform/cxx/ModalHostViewUtils.cpp +17 -0
  36. package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp +33 -0
  37. package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h +17 -0
  38. package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp +3 -2
  39. package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h +2 -1
  40. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h +24 -3
  41. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +1 -43
  42. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +4 -5
  43. package/ReactCommon/react/runtime/TimerManager.cpp +6 -4
  44. package/ReactCommon/react/runtime/TimerManager.h +3 -1
  45. package/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +9 -5
  46. package/package.json +10 -10
  47. package/react-native.config.js +11 -21
  48. package/scripts/codegen/generate-artifacts-executor.js +8 -4
  49. package/scripts/generate-codegen-artifacts.js +6 -1
  50. package/sdks/hermesc/osx-bin/hermes +0 -0
  51. package/sdks/hermesc/osx-bin/hermesc +0 -0
  52. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  53. package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
  54. package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
  55. package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
@@ -16,7 +16,7 @@ const version: $ReadOnly<{
16
16
  }> = {
17
17
  major: 0,
18
18
  minor: 77,
19
- patch: 1,
19
+ patch: 3,
20
20
  prerelease: null,
21
21
  };
22
22
 
@@ -133,6 +133,7 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
133
133
  width: undefined,
134
134
  height: undefined,
135
135
  };
136
+ const defaultSource = resolveAssetSource(props.defaultSource);
136
137
  const loadingIndicatorSource = resolveAssetSource(
137
138
  props.loadingIndicatorSource,
138
139
  );
@@ -178,6 +179,7 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
178
179
  /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
179
180
  * when making Flow check .android.js files. */
180
181
  headers: (source?.[0]?.headers || source?.headers: ?{[string]: string}),
182
+ defaultSource: defaultSource ? defaultSource.uri : null,
181
183
  loadingIndicatorSrc: loadingIndicatorSource
182
184
  ? loadingIndicatorSource.uri
183
185
  : null,
@@ -21,6 +21,7 @@ import type {
21
21
  } from '../StyleSheet/StyleSheet';
22
22
  import type {ResolvedAssetSource} from './AssetSourceResolver';
23
23
  import type {ImageProps} from './ImageProps';
24
+ import type {ImageSource} from './ImageSource';
24
25
 
25
26
  import * as NativeComponentRegistry from '../NativeComponent/NativeComponentRegistry';
26
27
  import {ConditionallyIgnoredEventHandlers} from '../NativeComponent/ViewConfigIgnore';
@@ -42,7 +43,7 @@ type Props = $ReadOnly<{
42
43
  | ?ResolvedAssetSource
43
44
  | ?$ReadOnlyArray<?$ReadOnly<{uri?: ?string, ...}>>,
44
45
  headers?: ?{[string]: string},
45
- defaultSrc?: ?string,
46
+ defaultSource?: ?ImageSource | ?string,
46
47
  loadingIndicatorSrc?: ?string,
47
48
  }>;
48
49
 
@@ -82,9 +83,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
82
83
  },
83
84
  validAttributes: {
84
85
  blurRadius: true,
85
- defaultSource: {
86
- process: require('./resolveAssetSource'),
87
- },
86
+ defaultSource: true,
88
87
  internal_analyticTag: true,
89
88
  resizeMethod: true,
90
89
  resizeMode: true,
@@ -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,7 +23,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
23
23
  __rnVersion = @{
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(77),
26
- RCTVersionPatch: @(1),
26
+ RCTVersionPatch: @(3),
27
27
  RCTVersionPrerelease: [NSNull null],
28
28
  };
29
29
  });
@@ -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
@@ -104,7 +104,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
104
104
  BOOL _shouldAnimatePresentation;
105
105
  BOOL _shouldPresent;
106
106
  BOOL _isPresented;
107
- UIView *_modalContentsSnapshot;
108
107
  }
109
108
 
110
109
  - (instancetype)initWithFrame:(CGRect)frame
@@ -141,7 +140,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
141
140
  animated:(BOOL)animated
142
141
  completion:(void (^)(void))completion
143
142
  {
144
- _modalContentsSnapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
145
143
  [modalViewController dismissViewControllerAnimated:animated completion:completion];
146
144
  }
147
145
 
@@ -167,8 +165,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
167
165
  _isPresented = NO;
168
166
  // To animate dismissal of view controller, snapshot of
169
167
  // view hierarchy needs to be added to the UIViewController.
170
- UIView *snapshot = _modalContentsSnapshot;
171
-
168
+ UIView *snapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
172
169
  if (_shouldPresent) {
173
170
  [self.viewController.view addSubview:snapshot];
174
171
  }
@@ -547,6 +547,17 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
547
547
  return metrics;
548
548
  }
549
549
 
550
+ - (ScrollViewEventEmitter::EndDragMetrics)_scrollViewMetricsWithVelocity:(CGPoint)velocity
551
+ andTargetContentOffset:(CGPoint)targetContentOffset
552
+ {
553
+ ScrollViewEventEmitter::EndDragMetrics metrics = [self _scrollViewMetrics];
554
+ metrics.targetContentOffset.x = targetContentOffset.x;
555
+ metrics.targetContentOffset.y = targetContentOffset.y;
556
+ metrics.velocity.x = velocity.x;
557
+ metrics.velocity.y = velocity.y;
558
+ return metrics;
559
+ }
560
+
550
561
  - (void)_updateStateWithContentOffset
551
562
  {
552
563
  if (!_state) {
@@ -602,6 +613,14 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
602
613
  targetContentOffset->y = scrollView.contentOffset.y + travel * _endDraggingSensitivityMultiplier;
603
614
  }
604
615
  }
616
+
617
+ if (!_eventEmitter) {
618
+ return;
619
+ }
620
+
621
+ auto metrics = [self _scrollViewMetricsWithVelocity:velocity andTargetContentOffset:*targetContentOffset];
622
+
623
+ static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag(metrics);
605
624
  }
606
625
 
607
626
  - (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view
@@ -672,8 +691,6 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
672
691
  return;
673
692
  }
674
693
 
675
- static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag([self _scrollViewMetrics]);
676
-
677
694
  [self _updateStateWithContentOffset];
678
695
 
679
696
  if (!decelerate) {
@@ -770,7 +787,9 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
770
787
  return;
771
788
  }
772
789
 
773
- static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag([self _scrollViewMetrics]);
790
+ auto metrics = [self _scrollViewMetricsWithVelocity:{} andTargetContentOffset:{}];
791
+ static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScrollEndDrag(metrics);
792
+
774
793
  [self _updateStateWithContentOffset];
775
794
  }
776
795
 
@@ -60,7 +60,7 @@ using namespace facebook::react;
60
60
  const auto &newSwitchProps = static_cast<const SwitchProps &>(*props);
61
61
 
62
62
  // `value`
63
- if (oldSwitchProps.value != newSwitchProps.value) {
63
+ if (!_isInitialValueSet || oldSwitchProps.value != newSwitchProps.value) {
64
64
  BOOL shouldAnimate = _isInitialValueSet == YES;
65
65
  [_switchView setOn:newSwitchProps.value animated:shouldAnimate];
66
66
  }
@@ -101,11 +101,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
101
101
  NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
102
102
  [_backedTextInputView.defaultTextAttributes mutableCopy];
103
103
 
104
- #if !TARGET_OS_MACCATALYST
105
- RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
106
- eventEmitterWrapper.eventEmitter = _eventEmitter;
107
- defaultAttributes[RCTAttributedStringEventEmitterKey] = eventEmitterWrapper;
108
- #endif
104
+ defaultAttributes[RCTAttributedStringEventEmitterKey] = RCTWrapEventEmitter(_eventEmitter);
109
105
 
110
106
  _backedTextInputView.defaultTextAttributes = defaultAttributes;
111
107
  }
@@ -266,10 +262,8 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
266
262
  if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) {
267
263
  NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
268
264
  RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes(RCTFontSizeMultiplier()));
269
- #if !TARGET_OS_MACCATALYST
270
265
  defaultAttributes[RCTAttributedStringEventEmitterKey] =
271
266
  _backedTextInputView.defaultTextAttributes[RCTAttributedStringEventEmitterKey];
272
- #endif
273
267
  _backedTextInputView.defaultTextAttributes = defaultAttributes;
274
268
  }
275
269
 
@@ -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.1
1
+ VERSION_NAME=0.77.3
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
 
4
4
  android.useAndroidX=true
@@ -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
@@ -445,12 +445,18 @@ public class FabricUIManager
445
445
 
446
446
  @Override
447
447
  public void markActiveTouchForTag(int surfaceId, int reactTag) {
448
- mMountingManager.getSurfaceManager(surfaceId).markActiveTouchForTag(reactTag);
448
+ SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
449
+ if (surfaceMountingManager != null) {
450
+ surfaceMountingManager.markActiveTouchForTag(reactTag);
451
+ }
449
452
  }
450
453
 
451
454
  @Override
452
455
  public void sweepActiveTouchForTag(int surfaceId, int reactTag) {
453
- mMountingManager.getSurfaceManager(surfaceId).sweepActiveTouchForTag(reactTag);
456
+ SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
457
+ if (surfaceMountingManager != null) {
458
+ surfaceMountingManager.sweepActiveTouchForTag(reactTag);
459
+ }
454
460
  }
455
461
 
456
462
  /**
@@ -1255,12 +1261,15 @@ public class FabricUIManager
1255
1261
 
1256
1262
  // Collect surface IDs for all the mount items
1257
1263
  for (MountItem mountItem : mountItems) {
1258
- if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) {
1259
- mMountedSurfaceIds.add(mountItem.getSurfaceId());
1264
+ if (mountItem != null
1265
+ && !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
1266
+ mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
1260
1267
  }
1261
1268
  }
1262
1269
 
1263
- if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) {
1270
+ if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
1271
+ mMountNotificationScheduled = true;
1272
+
1264
1273
  // Notify mount when the effects are visible and prevent mount hooks to
1265
1274
  // delay paint.
1266
1275
  UiThreadUtil.getUiThreadHandler()
@@ -1270,17 +1279,19 @@ public class FabricUIManager
1270
1279
  public void run() {
1271
1280
  mMountNotificationScheduled = false;
1272
1281
 
1282
+ // Create a copy in case mount hooks trigger more mutations
1283
+ final List<Integer> surfaceIdsToReportMount =
1284
+ mSurfaceIdsWithPendingMountNotification;
1285
+ mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
1286
+
1273
1287
  final @Nullable FabricUIManagerBinding binding = mBinding;
1274
1288
  if (binding == null || mDestroyed) {
1275
- mMountedSurfaceIds.clear();
1276
1289
  return;
1277
1290
  }
1278
1291
 
1279
- for (int surfaceId : mMountedSurfaceIds) {
1292
+ for (int surfaceId : surfaceIdsToReportMount) {
1280
1293
  binding.reportMount(surfaceId);
1281
1294
  }
1282
-
1283
- mMountedSurfaceIds.clear();
1284
1295
  }
1285
1296
  });
1286
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", 1,
20
+ "patch", 3,
21
21
  "prerelease", null);
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,
@@ -124,7 +124,7 @@ public constructor(
124
124
  }
125
125
  }
126
126
 
127
- @ReactProp(name = "defaultSource", customType = "ImageSource")
127
+ @ReactProp(name = "defaultSource")
128
128
  public fun setDefaultSource(view: ReactImageView, source: String?) {
129
129
  view.setDefaultSource(source)
130
130
  }
@@ -37,6 +37,8 @@ import com.facebook.react.bridge.WritableNativeMap
37
37
  import com.facebook.react.common.ReactConstants
38
38
  import com.facebook.react.common.annotations.VisibleForTesting
39
39
  import com.facebook.react.config.ReactFeatureFlags
40
+ import com.facebook.react.uimanager.DisplayMetricsHolder
41
+ import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
40
42
  import com.facebook.react.uimanager.JSPointerDispatcher
41
43
  import com.facebook.react.uimanager.JSTouchDispatcher
42
44
  import com.facebook.react.uimanager.PixelUtil.pxToDp
@@ -49,6 +51,7 @@ import com.facebook.react.views.common.ContextUtils
49
51
  import com.facebook.react.views.view.ReactViewGroup
50
52
  import com.facebook.react.views.view.setStatusBarTranslucency
51
53
  import com.facebook.react.views.view.setSystemBarsTranslucency
54
+ import com.facebook.yoga.annotations.DoNotStrip
52
55
  import java.util.Objects
53
56
 
54
57
  /**
@@ -119,6 +122,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
119
122
  private var createNewDialog = false
120
123
 
121
124
  init {
125
+ initStatusBarHeight(context)
122
126
  dialogRootViewGroup = DialogRootViewGroup(context)
123
127
  }
124
128
 
@@ -220,6 +224,15 @@ public class ReactModalHostView(context: ThemedReactContext) :
220
224
 
221
225
  private fun getCurrentActivity(): Activity? = (context as ThemedReactContext).currentActivity
222
226
 
227
+ private fun isFlagSecureSet(activity: Activity?): Boolean {
228
+ if (activity == null) {
229
+ return false
230
+ }
231
+
232
+ val flags = activity.window.attributes.flags
233
+ return (flags and WindowManager.LayoutParams.FLAG_SECURE) != 0
234
+ }
235
+
223
236
  /**
224
237
  * showOrUpdate will display the Dialog. It is called by the manager once all properties are set
225
238
  * because we need to know all of them before creating the Dialog. It is also smart during updates
@@ -293,6 +306,11 @@ public class ReactModalHostView(context: ThemedReactContext) :
293
306
  if (hardwareAccelerated) {
294
307
  newDialog.window?.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
295
308
  }
309
+ val flagSecureSet = isFlagSecureSet(currentActivity)
310
+ if (flagSecureSet) {
311
+ newDialog.window?.setFlags(
312
+ WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
313
+ }
296
314
  if (currentActivity?.isFinishing == false) {
297
315
  newDialog.show()
298
316
  updateSystemAppearance()
@@ -395,6 +413,26 @@ public class ReactModalHostView(context: ThemedReactContext) :
395
413
 
396
414
  private companion object {
397
415
  private const val TAG = "ReactModalHost"
416
+
417
+ // We store the status bar height to be able to properly position
418
+ // the modal on the first render.
419
+ private var statusBarHeight = 0
420
+
421
+ private fun initStatusBarHeight(reactContext: ReactContext) {
422
+ statusBarHeight = getStatusBarHeightPx(reactContext.currentActivity)
423
+ }
424
+
425
+ @JvmStatic
426
+ @DoNotStrip
427
+ private fun getScreenDisplayMetricsWithoutInsets(): Long {
428
+ val displayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics()
429
+ return encodeFloatsToLong(
430
+ displayMetrics.widthPixels.toFloat().pxToDp(),
431
+ (displayMetrics.heightPixels - statusBarHeight).toFloat().pxToDp())
432
+ }
433
+
434
+ private fun encodeFloatsToLong(width: Float, height: Float): Long =
435
+ (width.toRawBits().toLong()) shl 32 or (height.toRawBits().toLong())
398
436
  }
399
437
 
400
438
  /**
@@ -410,6 +448,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
410
448
  */
411
449
  public class DialogRootViewGroup internal constructor(context: Context) :
412
450
  ReactViewGroup(context), RootView {
451
+
413
452
  internal var stateWrapper: StateWrapper? = null
414
453
  internal var eventDispatcher: EventDispatcher? = null
415
454
 
@@ -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