react-native-tvos 0.77.2-2 → 0.77.3-1
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.
- package/Libraries/Core/ReactNativeVersion.js +3 -3
- package/Libraries/Network/RCTDataRequestHandler.mm +17 -3
- package/Libraries/Network/RCTFileRequestHandler.mm +17 -3
- package/React/Base/RCTVersion.m +3 -3
- package/React/DevSupport/RCTPausedInDebuggerOverlayController.mm +3 -5
- package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +18 -4
- package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +2 -5
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +22 -3
- package/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm +1 -1
- package/React/Fabric/Surface/RCTFabricSurface.mm +1 -0
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/publish.gradle +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +13 -8
- package/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.kt +3 -16
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +3 -3
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt +13 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +0 -3
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +18 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +18 -1
- package/ReactCommon/React-FabricComponents.podspec +1 -1
- package/ReactCommon/cxxreact/ReactNativeVersion.h +3 -3
- package/ReactCommon/react/renderer/components/modal/CMakeLists.txt +4 -1
- package/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h +3 -2
- package/ReactCommon/react/renderer/components/modal/ModalHostViewState.h +4 -12
- package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.h +2 -2
- package/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.mm +1 -1
- package/ReactCommon/react/renderer/components/modal/platform/android/JReactModalHostView.h +38 -0
- package/ReactCommon/react/renderer/components/modal/platform/android/ModalHostViewUtils.cpp +18 -0
- package/ReactCommon/react/renderer/components/modal/platform/cxx/ModalHostViewUtils.cpp +17 -0
- package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.cpp +33 -0
- package/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h +17 -0
- package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.cpp +3 -2
- package/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h +2 -1
- package/ReactCommon/react/runtime/TimerManager.cpp +6 -4
- package/ReactCommon/react/runtime/TimerManager.h +3 -1
- package/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +9 -5
- package/package.json +10 -10
- package/sdks/hermesc/osx-bin/hermes +0 -0
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
- package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
- package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
* @flow strict
|
|
8
|
-
* @generated by scripts/releases/set-
|
|
8
|
+
* @generated by scripts/releases/set-version.js
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const version: $ReadOnly<{
|
|
@@ -16,8 +16,8 @@ const version: $ReadOnly<{
|
|
|
16
16
|
}> = {
|
|
17
17
|
major: 0,
|
|
18
18
|
minor: 77,
|
|
19
|
-
patch:
|
|
20
|
-
prerelease: '
|
|
19
|
+
patch: 3,
|
|
20
|
+
prerelease: '1',
|
|
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
|
-
|
|
25
|
-
_queue
|
|
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
|
-
|
|
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
|
-
|
|
29
|
-
_fileQueue
|
|
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
|
-
|
|
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:
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated by scripts/releases/set-
|
|
7
|
+
* @generated by scripts/releases/set-version.js
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import "RCTVersion.h"
|
|
@@ -23,8 +23,8 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
|
|
23
23
|
__rnVersion = @{
|
|
24
24
|
RCTVersionMajor: @(0),
|
|
25
25
|
RCTVersionMinor: @(77),
|
|
26
|
-
RCTVersionPatch: @(
|
|
27
|
-
RCTVersionPrerelease: @"
|
|
26
|
+
RCTVersionPatch: @(3),
|
|
27
|
+
RCTVersionPrerelease: @"1",
|
|
28
28
|
};
|
|
29
29
|
});
|
|
30
30
|
return __rnVersion;
|
|
@@ -54,13 +54,11 @@
|
|
|
54
54
|
]];
|
|
55
55
|
|
|
56
56
|
UIButton *resumeButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
57
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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,7 +143,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
144
143
|
|
|
145
144
|
#if TARGET_OS_TV
|
|
146
145
|
- (void)menuButtonPressed {
|
|
147
|
-
UIView *snapshot =
|
|
146
|
+
UIView *snapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
|
|
148
147
|
[self.viewController.view addSubview:snapshot];
|
|
149
148
|
[self dismissViewController:self.viewController
|
|
150
149
|
animated:_shouldAnimatePresentation
|
|
@@ -196,7 +195,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
196
195
|
animated:(BOOL)animated
|
|
197
196
|
completion:(void (^)(void))completion
|
|
198
197
|
{
|
|
199
|
-
_modalContentsSnapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
|
|
200
198
|
[modalViewController dismissViewControllerAnimated:animated completion:completion];
|
|
201
199
|
}
|
|
202
200
|
|
|
@@ -222,8 +220,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
222
220
|
_isPresented = NO;
|
|
223
221
|
// To animate dismissal of view controller, snapshot of
|
|
224
222
|
// view hierarchy needs to be added to the UIViewController.
|
|
225
|
-
UIView *snapshot =
|
|
226
|
-
|
|
223
|
+
UIView *snapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO];
|
|
227
224
|
if (_shouldPresent) {
|
|
228
225
|
[self.viewController.view addSubview:snapshot];
|
|
229
226
|
}
|
|
@@ -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
|
-
|
|
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
|
}
|
|
@@ -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
|
}
|
|
@@ -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:///
|
|
23
|
+
def mavenTempLocalUrl = 'file:///home/expo/workingdir/build/maven-local'
|
|
24
24
|
// Rewritten when copying this to ReactAndroid/publish.gradle
|
|
25
25
|
|
|
26
26
|
publishing {
|
|
@@ -105,4 +105,4 @@ publishing {
|
|
|
105
105
|
} else {
|
|
106
106
|
logger.info('Signing disabled as the PGP key was not found')
|
|
107
107
|
}
|
|
108
|
-
}
|
|
108
|
+
}
|
|
@@ -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
|
|
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
|
|
1265
|
-
|
|
1264
|
+
if (mountItem != null
|
|
1265
|
+
&& !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
|
|
1266
|
+
mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
|
|
1266
1267
|
}
|
|
1267
1268
|
}
|
|
1268
1269
|
|
|
1269
|
-
if (!mMountNotificationScheduled && !
|
|
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 :
|
|
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()
|
package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated by scripts/releases/set-
|
|
7
|
+
* @generated by scripts/releases/set-version.js
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
package com.facebook.react.modules.systeminfo;
|
|
@@ -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",
|
|
21
|
-
"prerelease",
|
|
20
|
+
"patch", 3,
|
|
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
|
}
|
|
@@ -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 ?:
|
|
139
|
+
(endEnd ?: bottomEnd ?: bottomRight ?: uniform)?.resolve(width, height)
|
|
140
140
|
?: zeroRadii,
|
|
141
141
|
bottomRight =
|
|
142
|
-
(startEnd ?:
|
|
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
|
|
|
@@ -214,6 +217,15 @@ public class ReactModalHostView(context: ThemedReactContext) :
|
|
|
214
217
|
|
|
215
218
|
private fun getCurrentActivity(): Activity? = (context as ThemedReactContext).currentActivity
|
|
216
219
|
|
|
220
|
+
private fun isFlagSecureSet(activity: Activity?): Boolean {
|
|
221
|
+
if (activity == null) {
|
|
222
|
+
return false
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
val flags = activity.window.attributes.flags
|
|
226
|
+
return (flags and WindowManager.LayoutParams.FLAG_SECURE) != 0
|
|
227
|
+
}
|
|
228
|
+
|
|
217
229
|
/**
|
|
218
230
|
* showOrUpdate will display the Dialog. It is called by the manager once all properties are set
|
|
219
231
|
* because we need to know all of them before creating the Dialog. It is also smart during updates
|
|
@@ -309,6 +321,11 @@ public class ReactModalHostView(context: ThemedReactContext) :
|
|
|
309
321
|
if (hardwareAccelerated) {
|
|
310
322
|
newDialog.window?.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
|
|
311
323
|
}
|
|
324
|
+
val flagSecureSet = isFlagSecureSet(currentActivity)
|
|
325
|
+
if (flagSecureSet) {
|
|
326
|
+
newDialog.window?.setFlags(
|
|
327
|
+
WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
|
|
328
|
+
}
|
|
312
329
|
if (currentActivity?.isFinishing == false) {
|
|
313
330
|
newDialog.show()
|
|
314
331
|
updateSystemAppearance()
|
|
@@ -417,6 +434,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
|
|
|
417
434
|
*/
|
|
418
435
|
public class DialogRootViewGroup internal constructor(context: Context?) :
|
|
419
436
|
ReactViewGroup(context), RootView {
|
|
437
|
+
|
|
420
438
|
internal var stateWrapper: StateWrapper? = null
|
|
421
439
|
internal var eventDispatcher: EventDispatcher? = null
|
|
422
440
|
|
|
@@ -683,6 +683,23 @@ public class ReactViewGroup extends ViewGroup
|
|
|
683
683
|
super.onViewAdded(child);
|
|
684
684
|
}
|
|
685
685
|
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
@Override
|
|
689
|
+
public void removeView(@Nullable View view) {
|
|
690
|
+
if (view != null) {
|
|
691
|
+
recoverFocus(view);
|
|
692
|
+
}
|
|
693
|
+
super.removeView(view);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
@Override
|
|
697
|
+
public void removeViewAt(int index) {
|
|
698
|
+
recoverFocus(getChildAt(index));
|
|
699
|
+
super.removeViewAt(index);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
|
|
686
703
|
@Override
|
|
687
704
|
public void onViewRemoved(View child) {
|
|
688
705
|
UiThreadUtil.assertOnUiThread();
|
|
@@ -817,7 +834,7 @@ public class ReactViewGroup extends ViewGroup
|
|
|
817
834
|
|
|
818
835
|
/*package*/ void removeViewWithSubviewClippingEnabled(View view) {
|
|
819
836
|
UiThreadUtil.assertOnUiThread();
|
|
820
|
-
|
|
837
|
+
recoverFocus(view);
|
|
821
838
|
Assertions.assertCondition(mRemoveClippedSubviews);
|
|
822
839
|
Assertions.assertNotNull(mClippingRect);
|
|
823
840
|
View[] childArray = Assertions.assertNotNull(mAllChildren);
|
|
@@ -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
|
|
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
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated by scripts/releases/set-
|
|
7
|
+
* @generated by scripts/releases/set-version.js
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#pragma once
|
|
@@ -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 =
|
|
21
|
-
std::string_view Prerelease = "
|
|
20
|
+
int32_t Patch = 3;
|
|
21
|
+
std::string_view Prerelease = "1";
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
10
|
+
#include <react/renderer/graphics/Size.h>
|
|
11
11
|
|
|
12
12
|
namespace facebook::react {
|
|
13
13
|
|
|
14
|
-
Size
|
|
14
|
+
Size ModalHostViewScreenSize(void);
|
|
15
15
|
|
|
16
16
|
} // namespace facebook::react
|
|
@@ -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
|
|
29
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
362
|
-
|
|
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
|
-
|
|
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
|
-
|
|
420
|
-
|
|
421
|
-
|
|
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.
|
|
3
|
+
"version": "0.77.3-1",
|
|
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.
|
|
116
|
-
"@react-native/codegen": "0.77.
|
|
117
|
-
"@react-native/community-cli-plugin": "0.77.
|
|
118
|
-
"@react-native/gradle-plugin": "0.77.
|
|
119
|
-
"@react-native/js-polyfills": "0.77.
|
|
120
|
-
"@react-native/normalize-colors": "0.77.
|
|
121
|
-
"@react-native-tvos/virtualized-lists": "0.77.
|
|
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-1",
|
|
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.
|
|
138
|
-
"metro-source-map": "^0.81.
|
|
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
|
|
Binary file
|
|
Binary file
|