react-native-tvos 0.79.2-0 → 0.79.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.
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/README.md +3 -1
- package/React/Base/RCTRootView.h +7 -1
- package/React/Base/RCTRootView.m +38 -0
- package/React/Base/RCTRootViewInternal.h +1 -0
- package/React/Base/RCTTVRemoteSelectHandler.m +2 -1
- package/React/Base/RCTVersion.m +1 -1
- package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h +6 -0
- package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +37 -0
- package/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +18 -4
- package/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm +1 -1
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +3 -5
- package/React/Views/RCTTVView.m +4 -4
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +0 -3
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/jsc/React-jsc.podspec +1 -1
- package/ReactCommon/react/runtime/TimerManager.cpp +6 -4
- package/ReactCommon/react/runtime/TimerManager.h +3 -1
- package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm +0 -1
- package/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +9 -5
- package/package.json +8 -8
- package/scripts/codegen/generate-artifacts-executor.js +53 -18
- package/sdks/.hermesversion +1 -1
- 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/types/index.d.ts +1 -1
- package/types/tsconfig.test.json +16 -0
package/README.md
CHANGED
|
@@ -262,7 +262,9 @@ class Game2048 extends React.Component {
|
|
|
262
262
|
|
|
263
263
|
- _LogBox_: The LogBox error/warning display (which replaced YellowBox in 0.63) is working as expected on TV platforms, after a few adjustments to make the controls accessible to the focus engine.
|
|
264
264
|
|
|
265
|
-
- _Dev Menu support_:
|
|
265
|
+
- _Dev Menu support_:
|
|
266
|
+
- The developer menu provided by React Native itself works on TV. On the Apple TV simulator, cmd-D will bring up the developer menu, just like on iOS. To bring it up on a real Apple TV device, make a long press on the play/pause button on the remote. (Please do not shake the Apple TV device, that will not work :) ). Android TV dev menu behavior is the same as on Android phone.
|
|
267
|
+
- The Expo dev menu (provided by the [Expo dev client package](https://docs.expo.dev/versions/latest/sdk/dev-client/)) is *not* supported on TV.
|
|
266
268
|
|
|
267
269
|
- _TV remote animations on Apple TV_: `RCTTVView` native code implements Apple-recommended parallax animations to help guide the eye as the user navigates through views. The animations can be disabled or adjusted with new optional view properties.
|
|
268
270
|
|
package/React/Base/RCTRootView.h
CHANGED
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
extern NSString * _Nonnull const RCTTVEnableMenuKeyNotification;
|
|
15
15
|
extern NSString * _Nonnull const RCTTVDisableMenuKeyNotification;
|
|
16
16
|
|
|
17
|
+
#if TARGET_OS_TV
|
|
18
|
+
#import "RCTTVRemoteSelectHandler.h"
|
|
19
|
+
#endif
|
|
17
20
|
|
|
18
21
|
@protocol RCTRootViewDelegate;
|
|
19
22
|
|
|
@@ -51,8 +54,11 @@ extern
|
|
|
51
54
|
* like any ordinary UIView. You can have multiple RCTRootViews on screen at
|
|
52
55
|
* once, all controlled by the same JavaScript application.
|
|
53
56
|
*/
|
|
57
|
+
#if TARGET_OS_TV
|
|
58
|
+
@interface RCTRootView : UIView <RCTTVRemoteSelectHandlerDelegate>
|
|
59
|
+
#else
|
|
54
60
|
@interface RCTRootView : UIView
|
|
55
|
-
|
|
61
|
+
#endif
|
|
56
62
|
/**
|
|
57
63
|
* - Designated initializer -
|
|
58
64
|
*/
|
package/React/Base/RCTRootView.m
CHANGED
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
#if TARGET_OS_TV
|
|
32
32
|
#import "RCTTVNavigationEventEmitter.h"
|
|
33
33
|
#import "RCTTVRemoteHandler.h"
|
|
34
|
+
#import "RCTTVRemoteSelectHandler.h"
|
|
35
|
+
#import <React/RCTTVNavigationEventNotification.h>
|
|
34
36
|
#endif
|
|
35
37
|
|
|
36
38
|
#if RCT_DEV
|
|
@@ -98,6 +100,7 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
|
|
|
98
100
|
#endif
|
|
99
101
|
|
|
100
102
|
self.tvRemoteHandler = [[RCTTVRemoteHandler alloc] initWithView:self];
|
|
103
|
+
self.tvRemoteSelectHandler = [[RCTTVRemoteSelectHandler alloc] initWithView:self];
|
|
101
104
|
#endif
|
|
102
105
|
|
|
103
106
|
[self showLoadingView];
|
|
@@ -424,10 +427,45 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
|
424
427
|
{
|
|
425
428
|
#if TARGET_OS_TV
|
|
426
429
|
self.tvRemoteHandler = nil;
|
|
430
|
+
self.tvRemoteSelectHandler = nil;
|
|
427
431
|
#endif
|
|
428
432
|
[_contentView invalidate];
|
|
429
433
|
}
|
|
430
434
|
|
|
435
|
+
#if TARGET_OS_TV
|
|
436
|
+
|
|
437
|
+
#pragma mark -
|
|
438
|
+
#pragma mark RCTTVRemoteSelectHandlerDelegate methods
|
|
439
|
+
|
|
440
|
+
- (void)animatePressIn {
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
- (void)animatePressOut {
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
- (void)emitPressInEvent {
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
- (void)emitPressOutEvent {
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
- (void)sendSelectNotification
|
|
453
|
+
{
|
|
454
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventSelect keyAction:RCTTVRemoteEventKeyActionUp tag:self.reactTag target:self.reactTag];
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
- (void)sendLongSelectBeganNotification
|
|
458
|
+
{
|
|
459
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionDown tag:self.reactTag target:self.reactTag];
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
- (void)sendLongSelectEndedNotification
|
|
463
|
+
{
|
|
464
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionUp tag:self.reactTag target:self.reactTag];
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
#endif
|
|
468
|
+
|
|
431
469
|
@end
|
|
432
470
|
|
|
433
471
|
@implementation RCTRootView (Deprecated)
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
#if TARGET_OS_TV
|
|
28
28
|
@property (nonatomic, strong, nullable) RCTTVRemoteHandler *tvRemoteHandler;
|
|
29
|
+
@property (nonatomic, strong, nullable) RCTTVRemoteSelectHandler *tvRemoteSelectHandler;
|
|
29
30
|
@property (nonatomic, weak) UIView *reactPreferredFocusedView;
|
|
30
31
|
@property (nonatomic, copy, nullable) NSArray<id<UIFocusEnvironment>> *reactPreferredFocusEnvironments;
|
|
31
32
|
#endif
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
// Press recognizer should allow long press recognizer to work (but not the reverse)
|
|
38
38
|
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
|
39
|
-
return gestureRecognizer ==
|
|
39
|
+
return gestureRecognizer == self.pressRecognizer && otherGestureRecognizer == self.longPressRecognizer;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
#pragma mark -
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
|
|
55
55
|
longPressRecognizer.allowedPressTypes = @[ @(UIPressTypeSelect) ];
|
|
56
56
|
longPressRecognizer.minimumPressDuration = 0.5;
|
|
57
|
+
longPressRecognizer.delegate = self;
|
|
57
58
|
|
|
58
59
|
[self.view addGestureRecognizer:longPressRecognizer];
|
|
59
60
|
self.longPressRecognizer = longPressRecognizer;
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
#if TARGET_OS_TV
|
|
16
16
|
#import <React/RCTTVRemoteHandler.h>
|
|
17
|
+
#import <React/RCTTVRemoteSelectHandler.h>
|
|
17
18
|
#endif
|
|
18
19
|
|
|
19
20
|
NS_ASSUME_NONNULL_BEGIN
|
|
@@ -25,7 +26,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
25
26
|
*
|
|
26
27
|
* WARNING: In the future, RCTRootView will be deprecated in favor of RCTSurfaceHostingView.
|
|
27
28
|
*/
|
|
29
|
+
#if TARGET_OS_TV
|
|
30
|
+
@interface RCTSurfaceHostingProxyRootView : RCTSurfaceHostingView <RCTTVRemoteSelectHandlerDelegate>
|
|
31
|
+
#else
|
|
28
32
|
@interface RCTSurfaceHostingProxyRootView : RCTSurfaceHostingView
|
|
33
|
+
#endif
|
|
29
34
|
|
|
30
35
|
#pragma mark RCTRootView compatibility - keep these sync'ed with RCTRootView.h
|
|
31
36
|
|
|
@@ -44,6 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
44
49
|
@property (nonatomic, assign) CGSize minimumSize;
|
|
45
50
|
#if TARGET_OS_TV
|
|
46
51
|
@property (nonatomic, strong, nullable) RCTTVRemoteHandler *tvRemoteHandler;
|
|
52
|
+
@property (nonatomic, strong, nullable) RCTTVRemoteSelectHandler *tvRemoteSelectHandler;
|
|
47
53
|
@property (nonatomic, weak, nullable) UIView *reactPreferredFocusedView;
|
|
48
54
|
@property (nonatomic, copy, nullable) NSArray<id<UIFocusEnvironment>> *reactPreferredFocusEnvironments;
|
|
49
55
|
#endif
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
#import "RCTSurface.h"
|
|
21
21
|
#import "UIView+React.h"
|
|
22
22
|
|
|
23
|
+
#if TARGET_OS_TV
|
|
24
|
+
#import <React/RCTTVNavigationEventNotification.h>
|
|
25
|
+
#endif
|
|
26
|
+
|
|
23
27
|
static RCTSurfaceSizeMeasureMode convertToSurfaceSizeMeasureMode(RCTRootViewSizeFlexibility sizeFlexibility)
|
|
24
28
|
{
|
|
25
29
|
switch (sizeFlexibility) {
|
|
@@ -61,9 +65,11 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
|
|
|
61
65
|
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
62
66
|
|
|
63
67
|
#if TARGET_OS_TV
|
|
68
|
+
|
|
64
69
|
- (void)dealloc
|
|
65
70
|
{
|
|
66
71
|
self.tvRemoteHandler = nil;
|
|
72
|
+
self.tvRemoteSelectHandler = nil;
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
- (NSArray<id<UIFocusEnvironment>> *)preferredFocusEnvironments {
|
|
@@ -78,6 +84,36 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
|
78
84
|
}
|
|
79
85
|
return [super preferredFocusEnvironments];
|
|
80
86
|
}
|
|
87
|
+
|
|
88
|
+
#pragma mark -
|
|
89
|
+
#pragma mark RCTTVRemoteSelectHandlerDelegate methods
|
|
90
|
+
|
|
91
|
+
- (void)animatePressIn {
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
- (void)animatePressOut {
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
- (void)emitPressInEvent {
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
- (void)emitPressOutEvent {
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
- (void)sendSelectNotification
|
|
104
|
+
{
|
|
105
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventSelect keyAction:RCTTVRemoteEventKeyActionUp tag:self.reactTag target:self.reactTag];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
- (void)sendLongSelectBeganNotification
|
|
109
|
+
{
|
|
110
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionDown tag:self.reactTag target:self.reactTag];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
- (void)sendLongSelectEndedNotification
|
|
114
|
+
{
|
|
115
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionUp tag:self.reactTag target:self.reactTag];
|
|
116
|
+
}
|
|
81
117
|
#endif
|
|
82
118
|
|
|
83
119
|
|
|
@@ -145,6 +181,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
|
145
181
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
146
182
|
#if TARGET_OS_TV
|
|
147
183
|
self.tvRemoteHandler = [[RCTTVRemoteHandler alloc] initWithView:[self contentView]];
|
|
184
|
+
self.tvRemoteSelectHandler = [[RCTTVRemoteSelectHandler alloc] initWithView:self];
|
|
148
185
|
#endif
|
|
149
186
|
});
|
|
150
187
|
}
|
|
@@ -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
|
|
@@ -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
|
}
|
|
@@ -587,23 +587,21 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
if (context.nextFocusedView == self) {
|
|
590
|
-
if(_eventEmitter) _eventEmitter->onFocus();
|
|
591
|
-
|
|
592
590
|
[self becomeFirstResponder];
|
|
593
591
|
[self enableDirectionalFocusGuides];
|
|
594
592
|
[coordinator addCoordinatedAnimations:^(void){
|
|
595
|
-
|
|
593
|
+
if (self->_eventEmitter) self->_eventEmitter->onFocus();
|
|
596
594
|
[self sendFocusNotification:context];
|
|
595
|
+
[self addParallaxMotionEffects];
|
|
597
596
|
} completion:^(void){}];
|
|
598
597
|
// Without this check, onBlur would also trigger when `TVFocusGuideView` transfers focus to its children.
|
|
599
598
|
// [self isTVFocusGuide] is false when autofocus and destinations are not used, so we cannot use that.
|
|
600
599
|
// Generally speaking, it would happen for any non-collapsable `View`.
|
|
601
600
|
} else if (context.previouslyFocusedView == self) {
|
|
602
|
-
if (_eventEmitter) _eventEmitter->onBlur();
|
|
603
|
-
|
|
604
601
|
[self disableDirectionalFocusGuides];
|
|
605
602
|
[coordinator addCoordinatedAnimations:^(void){
|
|
606
603
|
[self removeParallaxMotionEffects];
|
|
604
|
+
if (self->_eventEmitter) self->_eventEmitter->onBlur();
|
|
607
605
|
[self sendBlurNotification:context];
|
|
608
606
|
} completion:^(void){}];
|
|
609
607
|
[self resignFirstResponder];
|
package/React/Views/RCTTVView.m
CHANGED
|
@@ -304,22 +304,22 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
if (context.nextFocusedView == self) {
|
|
307
|
-
if (self.onFocus) self.onFocus(nil);
|
|
308
307
|
[self becomeFirstResponder];
|
|
309
308
|
[self enableDirectionalFocusGuides];
|
|
310
309
|
[coordinator addCoordinatedAnimations:^(void){
|
|
311
|
-
|
|
310
|
+
if (self.onFocus) self.onFocus(nil);
|
|
312
311
|
[self sendFocusNotification:context];
|
|
312
|
+
[self addParallaxMotionEffects];
|
|
313
313
|
} completion:^(void){}];
|
|
314
314
|
// Without this check, onBlur would also trigger when `TVFocusGuideView` transfers focus to its children.
|
|
315
315
|
// [self isTVFocusGuide] is false when autofocus and destinations are not used, so we cannot use that.
|
|
316
316
|
// Generally speaking, it would happen for any non-collapsable `View`.
|
|
317
317
|
} else if (context.previouslyFocusedView == self ) {
|
|
318
|
-
if (self.onBlur) self.onBlur(nil);
|
|
319
318
|
[self disableDirectionalFocusGuides];
|
|
320
319
|
[coordinator addCoordinatedAnimations:^(void){
|
|
321
|
-
[self sendBlurNotification:context];
|
|
322
320
|
[self removeParallaxMotionEffects];
|
|
321
|
+
if (self.onBlur) self.onBlur(nil);
|
|
322
|
+
[self sendBlurNotification:context];
|
|
323
323
|
} completion:^(void){}];
|
|
324
324
|
[self resignFirstResponder];
|
|
325
325
|
}
|
|
@@ -136,10 +136,10 @@ internal 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,
|
|
@@ -710,9 +710,6 @@ public class ReactViewGroup extends ViewGroup
|
|
|
710
710
|
UiThreadUtil.assertOnUiThread();
|
|
711
711
|
checkViewClippingTag(child, Boolean.TRUE);
|
|
712
712
|
if (!customDrawOrderDisabled()) {
|
|
713
|
-
if (indexOfChild(child) == -1) {
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
713
|
getDrawingOrderHelper().handleRemoveView(child);
|
|
717
714
|
setChildrenDrawingOrderEnabled(getDrawingOrderHelper().shouldEnableCustomDrawingOrder());
|
|
718
715
|
} else {
|
|
@@ -242,8 +242,9 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) {
|
|
245
|
-
// Do not throw any error to match web spec
|
|
246
|
-
|
|
245
|
+
// Do not throw any error to match web spec; instead return 0, an
|
|
246
|
+
// invalid timer id
|
|
247
|
+
return 0;
|
|
247
248
|
}
|
|
248
249
|
|
|
249
250
|
auto callback = args[0].getObject(rt).getFunction(rt);
|
|
@@ -300,8 +301,9 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
|
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) {
|
|
303
|
-
throw
|
|
304
|
-
|
|
304
|
+
// Do not throw any error to match web spec; instead return 0, an
|
|
305
|
+
// invalid timer id
|
|
306
|
+
return 0;
|
|
305
307
|
}
|
|
306
308
|
auto callback = args[0].getObject(rt).getFunction(rt);
|
|
307
309
|
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
|
|
@@ -474,7 +474,6 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags)
|
|
|
474
474
|
|
|
475
475
|
if (error) {
|
|
476
476
|
[strongSelf handleBundleLoadingError:error];
|
|
477
|
-
[strongSelf invalidate];
|
|
478
477
|
return;
|
|
479
478
|
}
|
|
480
479
|
// DevSettings module is needed by _loadScriptFromSource's callback so prior initialization is required
|
|
@@ -267,7 +267,9 @@ TEST_F(ReactInstanceTest, testSetTimeoutWithoutDelay) {
|
|
|
267
267
|
EXPECT_CALL(
|
|
268
268
|
*mockRegistry_,
|
|
269
269
|
createTimer(_, 0)); // If delay is not provided, it should use 0
|
|
270
|
-
eval("setTimeout(() => {});");
|
|
270
|
+
auto val = eval("setTimeout(() => {});");
|
|
271
|
+
expectNoError();
|
|
272
|
+
EXPECT_EQ(val.asNumber(), 1); // First timer id should start at 1
|
|
271
273
|
}
|
|
272
274
|
|
|
273
275
|
TEST_F(ReactInstanceTest, testSetTimeoutWithPassThroughArgs) {
|
|
@@ -299,8 +301,9 @@ TEST_F(ReactInstanceTest, testSetTimeoutWithInvalidArgs) {
|
|
|
299
301
|
getErrorMessage("setTimeout();"),
|
|
300
302
|
"setTimeout must be called with at least one argument (the function to call).");
|
|
301
303
|
|
|
302
|
-
eval("setTimeout('invalid')
|
|
304
|
+
auto val = eval("setTimeout('invalid')");
|
|
303
305
|
expectNoError();
|
|
306
|
+
EXPECT_EQ(val.asNumber(), 0);
|
|
304
307
|
|
|
305
308
|
eval("setTimeout(() => {}, 'invalid');");
|
|
306
309
|
expectNoError();
|
|
@@ -417,9 +420,10 @@ TEST_F(ReactInstanceTest, testSetIntervalWithInvalidArgs) {
|
|
|
417
420
|
EXPECT_EQ(
|
|
418
421
|
getErrorMessage("setInterval();"),
|
|
419
422
|
"setInterval must be called with at least one argument (the function to call).");
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
+
|
|
424
|
+
auto val = eval("setInterval('invalid', 100)");
|
|
425
|
+
expectNoError();
|
|
426
|
+
EXPECT_EQ(val.asNumber(), 0);
|
|
423
427
|
}
|
|
424
428
|
|
|
425
429
|
TEST_F(ReactInstanceTest, testClearInterval) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-tvos",
|
|
3
|
-
"version": "0.79.
|
|
3
|
+
"version": "0.79.3-0",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -112,12 +112,12 @@
|
|
|
112
112
|
},
|
|
113
113
|
"dependencies": {
|
|
114
114
|
"@jest/create-cache-key-function": "^29.7.0",
|
|
115
|
-
"@react-native/assets-registry": "0.79.
|
|
116
|
-
"@react-native/codegen": "0.79.
|
|
117
|
-
"@react-native/community-cli-plugin": "0.79.
|
|
118
|
-
"@react-native/gradle-plugin": "0.79.
|
|
119
|
-
"@react-native/js-polyfills": "0.79.
|
|
120
|
-
"@react-native/normalize-colors": "0.79.
|
|
115
|
+
"@react-native/assets-registry": "0.79.3",
|
|
116
|
+
"@react-native/codegen": "0.79.3",
|
|
117
|
+
"@react-native/community-cli-plugin": "0.79.3",
|
|
118
|
+
"@react-native/gradle-plugin": "0.79.3",
|
|
119
|
+
"@react-native/js-polyfills": "0.79.3",
|
|
120
|
+
"@react-native/normalize-colors": "0.79.3",
|
|
121
121
|
"abort-controller": "^3.0.0",
|
|
122
122
|
"anser": "^1.4.9",
|
|
123
123
|
"ansi-regex": "^5.0.0",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"whatwg-fetch": "^3.0.0",
|
|
147
147
|
"ws": "^6.2.3",
|
|
148
148
|
"yargs": "^17.6.2",
|
|
149
|
-
"@react-native-tvos/virtualized-lists": "0.79.
|
|
149
|
+
"@react-native-tvos/virtualized-lists": "0.79.3-0"
|
|
150
150
|
},
|
|
151
151
|
"codegenConfig": {
|
|
152
152
|
"libraries": [
|
|
@@ -326,22 +326,13 @@ function findExternalLibraries(pkgJson, projectRoot) {
|
|
|
326
326
|
});
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
function findLibrariesFromReactNativeConfig(projectRoot) {
|
|
330
|
-
const rnConfigFileName = 'react-native.config.js';
|
|
331
|
-
|
|
329
|
+
function findLibrariesFromReactNativeConfig(projectRoot, rnConfig) {
|
|
332
330
|
codegenLog(
|
|
333
|
-
`Searching for codegen-enabled libraries in
|
|
331
|
+
`Searching for codegen-enabled libraries in react-native.config.js`,
|
|
334
332
|
true,
|
|
335
333
|
);
|
|
336
334
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (!fs.existsSync(rnConfigFilePath)) {
|
|
340
|
-
return [];
|
|
341
|
-
}
|
|
342
|
-
const rnConfig = require(rnConfigFilePath);
|
|
343
|
-
|
|
344
|
-
if (rnConfig.dependencies == null) {
|
|
335
|
+
if (!rnConfig.dependencies) {
|
|
345
336
|
return [];
|
|
346
337
|
}
|
|
347
338
|
return Object.keys(rnConfig.dependencies).flatMap(name => {
|
|
@@ -365,6 +356,19 @@ function findLibrariesFromReactNativeConfig(projectRoot) {
|
|
|
365
356
|
});
|
|
366
357
|
}
|
|
367
358
|
|
|
359
|
+
/**
|
|
360
|
+
* Finds all disabled libraries by platform based the react native config.
|
|
361
|
+
*
|
|
362
|
+
* This is needed when selectively disabling libraries in react-native.config.js since codegen should exclude those libraries as well.
|
|
363
|
+
*/
|
|
364
|
+
function findDisabledLibrariesByPlatform(reactNativeConfig, platform) {
|
|
365
|
+
const dependencies = reactNativeConfig.dependencies ?? {};
|
|
366
|
+
|
|
367
|
+
return Object.keys(dependencies).filter(
|
|
368
|
+
dependency => dependencies[dependency].platforms?.[platform] === null,
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
368
372
|
function findProjectRootLibraries(pkgJson, projectRoot) {
|
|
369
373
|
codegenLog('Searching for codegen-enabled libraries in the app.', true);
|
|
370
374
|
|
|
@@ -593,7 +597,7 @@ function mustGenerateNativeCode(includeLibraryPath, schemaInfo) {
|
|
|
593
597
|
);
|
|
594
598
|
}
|
|
595
599
|
|
|
596
|
-
function findCodegenEnabledLibraries(pkgJson, projectRoot) {
|
|
600
|
+
function findCodegenEnabledLibraries(pkgJson, projectRoot, reactNativeConfig) {
|
|
597
601
|
const projectLibraries = findProjectRootLibraries(pkgJson, projectRoot);
|
|
598
602
|
if (pkgJsonIncludesGeneratedCode(pkgJson)) {
|
|
599
603
|
return projectLibraries;
|
|
@@ -601,11 +605,21 @@ function findCodegenEnabledLibraries(pkgJson, projectRoot) {
|
|
|
601
605
|
return [
|
|
602
606
|
...projectLibraries,
|
|
603
607
|
...findExternalLibraries(pkgJson, projectRoot),
|
|
604
|
-
...findLibrariesFromReactNativeConfig(projectRoot),
|
|
608
|
+
...findLibrariesFromReactNativeConfig(projectRoot, reactNativeConfig),
|
|
605
609
|
];
|
|
606
610
|
}
|
|
607
611
|
}
|
|
608
612
|
|
|
613
|
+
function readReactNativeConfig(projectRoot) {
|
|
614
|
+
const rnConfigFilePath = path.resolve(projectRoot, 'react-native.config.js');
|
|
615
|
+
|
|
616
|
+
if (!fs.existsSync(rnConfigFilePath)) {
|
|
617
|
+
return {};
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return require(rnConfigFilePath);
|
|
621
|
+
}
|
|
622
|
+
|
|
609
623
|
function generateCustomURLHandlers(libraries, outputDir) {
|
|
610
624
|
const customImageURLLoaderClasses = libraries
|
|
611
625
|
.flatMap(
|
|
@@ -834,8 +848,11 @@ function findFilesWithExtension(filePath, extension) {
|
|
|
834
848
|
return null;
|
|
835
849
|
}
|
|
836
850
|
|
|
837
|
-
// Skip hidden folders, that starts with `.`
|
|
838
|
-
if (
|
|
851
|
+
// Skip hidden folders, that starts with `.` but allow `.pnpm`
|
|
852
|
+
if (
|
|
853
|
+
absolutePath.includes(`${path.sep}.`) &&
|
|
854
|
+
!absolutePath.includes(`${path.sep}.pnpm`)
|
|
855
|
+
) {
|
|
839
856
|
return null;
|
|
840
857
|
}
|
|
841
858
|
|
|
@@ -1054,9 +1071,14 @@ function execute(projectRoot, targetPlatform, baseOutputPath, source) {
|
|
|
1054
1071
|
|
|
1055
1072
|
buildCodegenIfNeeded();
|
|
1056
1073
|
|
|
1057
|
-
const
|
|
1074
|
+
const reactNativeConfig = readReactNativeConfig(projectRoot);
|
|
1075
|
+
const codegenEnabledLibraries = findCodegenEnabledLibraries(
|
|
1076
|
+
pkgJson,
|
|
1077
|
+
projectRoot,
|
|
1078
|
+
reactNativeConfig,
|
|
1079
|
+
);
|
|
1058
1080
|
|
|
1059
|
-
if (
|
|
1081
|
+
if (codegenEnabledLibraries.length === 0) {
|
|
1060
1082
|
codegenLog('No codegen-enabled libraries found.', true);
|
|
1061
1083
|
return;
|
|
1062
1084
|
}
|
|
@@ -1065,6 +1087,19 @@ function execute(projectRoot, targetPlatform, baseOutputPath, source) {
|
|
|
1065
1087
|
targetPlatform === 'all' ? supportedPlatforms : [targetPlatform];
|
|
1066
1088
|
|
|
1067
1089
|
for (const platform of platforms) {
|
|
1090
|
+
const disabledLibraries = findDisabledLibrariesByPlatform(
|
|
1091
|
+
reactNativeConfig,
|
|
1092
|
+
platform,
|
|
1093
|
+
);
|
|
1094
|
+
|
|
1095
|
+
const libraries = codegenEnabledLibraries.filter(
|
|
1096
|
+
({name}) => !disabledLibraries.includes(name),
|
|
1097
|
+
);
|
|
1098
|
+
|
|
1099
|
+
if (!libraries.length) {
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1068
1103
|
const outputPath = computeOutputPath(
|
|
1069
1104
|
projectRoot,
|
|
1070
1105
|
baseOutputPath,
|
package/sdks/.hermesversion
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
hermes-2025-
|
|
1
|
+
hermes-2025-06-04-RNv0.79.3-7f9a871eefeb2c3852365ee80f0b6733ec12ac3b
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/types/index.d.ts
CHANGED
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
/// <reference path="modules/BatchedBridge.d.ts" />
|
|
69
69
|
/// <reference path="modules/Codegen.d.ts" />
|
|
70
70
|
/// <reference path="modules/Devtools.d.ts" />
|
|
71
|
-
/// <reference
|
|
71
|
+
/// <reference path="../src/types/globals.d.ts" />
|
|
72
72
|
/// <reference path="modules/LaunchScreen.d.ts" />
|
|
73
73
|
|
|
74
74
|
export * from '../Libraries/ActionSheetIOS/ActionSheetIOS';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"lib": ["es6"],
|
|
5
|
+
"noImplicitAny": true,
|
|
6
|
+
"noImplicitThis": true,
|
|
7
|
+
"strictFunctionTypes": true,
|
|
8
|
+
"strictNullChecks": true,
|
|
9
|
+
"types": [],
|
|
10
|
+
"jsx": "react",
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"paths": {"react-native": ["."]}
|
|
14
|
+
},
|
|
15
|
+
"include": ["../**/*.d.ts", "__typetests__/**/*"]
|
|
16
|
+
}
|