react-native-tvos 0.76.1-0 → 0.76.2-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/AppDelegate/React-RCTAppDelegate.podspec +1 -1
- package/Libraries/Components/Pressable/Pressable.d.ts +9 -1
- package/Libraries/Components/Pressable/Pressable.js +4 -16
- package/Libraries/Components/TV/TVViewPropTypes.js +2 -1
- package/Libraries/Components/TextInput/TextInput.d.ts +1 -1
- package/Libraries/Components/Touchable/Touchable.js +0 -43
- package/Libraries/Components/Touchable/TouchableBounce.js +0 -33
- package/Libraries/Components/Touchable/TouchableHighlight.js +12 -47
- package/Libraries/Components/Touchable/TouchableNativeFeedback.js +0 -33
- package/Libraries/Components/Touchable/TouchableOpacity.js +12 -44
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +0 -19
- package/Libraries/Components/View/ViewNativeComponent.js +6 -0
- package/Libraries/Components/View/ViewPropTypes.d.ts +12 -1
- package/Libraries/Components/View/ViewPropTypes.js +7 -0
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Core/setUpErrorHandling.js +1 -7
- package/Libraries/LogBox/Data/LogBoxData.js +2 -2
- package/Libraries/NativeComponent/BaseViewConfig.android.js +19 -0
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +6 -0
- package/Libraries/NativeComponent/TVViewConfig.js +4 -0
- package/Libraries/Pressability/Pressability.js +45 -28
- package/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +1 -0
- package/Libraries/Types/CoreEventTypes.d.ts +21 -0
- package/Libraries/Types/CoreEventTypes.js +6 -0
- package/README.md +9 -7
- package/React/Base/RCTTVRemoteHandler.m +0 -19
- package/React/Base/RCTTVRemoteSelectHandler.h +27 -0
- package/React/Base/RCTTVRemoteSelectHandler.m +120 -0
- package/React/Base/RCTVersion.m +1 -1
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +12 -8
- package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +47 -3
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.h +8 -0
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +51 -44
- package/React/Views/RCTTVView.h +19 -6
- package/React/Views/RCTTVView.m +63 -55
- package/React/Views/RCTViewManager.m +4 -0
- package/React/Views/ScrollView/RCTScrollView.m +12 -8
- package/ReactAndroid/api/ReactAndroid.api +0 -1
- package/ReactAndroid/cmake-utils/ReactNative-application.cmake +1 -1
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt +2 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.kt +0 -8
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +16 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java +20 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/BlurEvent.kt +16 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/FocusEvent.kt +16 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PressInEvent.kt +16 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PressOutEvent.kt +16 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt +11 -3
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +212 -4
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java +47 -4
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/TextInputShadowNode.cpp +3 -2
- package/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.cpp +18 -0
- package/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.h +8 -0
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h +12 -1
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +165 -2
- package/cli.js +1 -1
- package/index.js +0 -4
- package/package.json +8 -8
- package/scripts/codegen/generate-artifacts-executor.js +3 -3
- 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/modules/Codegen.d.ts +6 -0
- package/types/public/ReactNativeTVTypes.d.ts +2 -2
- package/Libraries/Components/TabBarIOS/RCTTabBarItemNativeComponent.js +0 -99
- package/Libraries/Components/TabBarIOS/RCTTabBarNativeComponent.js +0 -32
- package/Libraries/Components/TabBarIOS/TabBarIOS.ios.js +0 -59
- package/Libraries/Components/TabBarIOS/TabBarIOS.js +0 -52
- package/Libraries/Components/TabBarIOS/TabBarIOSProps.js +0 -52
- package/Libraries/Components/TabBarIOS/TabBarItemIOS.ios.js +0 -177
- package/Libraries/Components/TabBarIOS/TabBarItemIOS.js +0 -55
- package/Libraries/Components/Touchable/TVTouchable.js +0 -71
- package/React/Views/RCTTabBar.h +0 -22
- package/React/Views/RCTTabBar.m +0 -237
- package/React/Views/RCTTabBarItem.h +0 -35
- package/React/Views/RCTTabBarItem.m +0 -139
- package/React/Views/RCTTabBarItemManager.h +0 -12
- package/React/Views/RCTTabBarItemManager.m +0 -38
- package/React/Views/RCTTabBarManager.h +0 -12
- package/React/Views/RCTTabBarManager.m +0 -81
|
@@ -63,8 +63,6 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
63
63
|
BOOL _removeClippedSubviews;
|
|
64
64
|
NSMutableArray<UIView *> *_reactSubviews;
|
|
65
65
|
BOOL _motionEffectsAdded;
|
|
66
|
-
UITapGestureRecognizer *_selectRecognizer;
|
|
67
|
-
UILongPressGestureRecognizer * _longSelectRecognizer;
|
|
68
66
|
NSSet<NSString *> *_Nullable _propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN;
|
|
69
67
|
UIView *_containerView;
|
|
70
68
|
BOOL _useCustomContainerView;
|
|
@@ -268,52 +266,61 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
268
266
|
[[NSNotificationCenter defaultCenter] postNavigationBlurEventWithTag:@(self.tag) target:@(self.tag)];
|
|
269
267
|
}
|
|
270
268
|
|
|
271
|
-
- (void)sendSelectNotification
|
|
269
|
+
- (void)sendSelectNotification
|
|
272
270
|
{
|
|
273
|
-
|
|
271
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventSelect keyAction:RCTTVRemoteEventKeyActionUp tag:@(self.tag) target:@(self.tag)];
|
|
274
272
|
}
|
|
275
273
|
|
|
276
|
-
- (void)
|
|
274
|
+
- (void)sendLongSelectBeganNotification
|
|
277
275
|
{
|
|
278
|
-
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:
|
|
276
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionDown tag:@(self.tag) target:@(self.tag)];
|
|
279
277
|
}
|
|
280
278
|
|
|
281
|
-
- (void)
|
|
279
|
+
- (void)sendLongSelectEndedNotification
|
|
280
|
+
{
|
|
281
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionUp tag:@(self.tag) target:@(self.tag)];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
- (void)animatePressIn
|
|
282
285
|
{
|
|
283
286
|
if (_tvParallaxProperties.enabled == YES) {
|
|
284
|
-
float magnification = _tvParallaxProperties.magnification;
|
|
285
287
|
float pressMagnification = _tvParallaxProperties.pressMagnification;
|
|
286
288
|
|
|
287
289
|
// Duration of press animation
|
|
288
290
|
float pressDuration = _tvParallaxProperties.pressDuration;
|
|
289
291
|
|
|
290
|
-
// Delay of press animation
|
|
291
|
-
float pressDelay = _tvParallaxProperties.pressDelay;
|
|
292
|
-
|
|
293
|
-
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:pressDelay]];
|
|
294
|
-
|
|
295
292
|
[UIView animateWithDuration:(pressDuration/2)
|
|
296
293
|
animations:^{
|
|
297
294
|
self.transform = CGAffineTransformMakeScale(pressMagnification, pressMagnification);
|
|
298
295
|
}
|
|
299
|
-
completion:^(__unused BOOL
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
self.transform = CGAffineTransformMakeScale(magnification, magnification);
|
|
303
|
-
}
|
|
304
|
-
completion:^(__unused BOOL finished2) {
|
|
305
|
-
[self sendSelectNotification:r];
|
|
306
|
-
}];
|
|
307
|
-
}];
|
|
296
|
+
completion:^(__unused BOOL finished){}];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
308
299
|
|
|
309
|
-
|
|
310
|
-
|
|
300
|
+
- (void) animatePressOut
|
|
301
|
+
{
|
|
302
|
+
if (_tvParallaxProperties.enabled == YES) {
|
|
303
|
+
float magnification = _tvParallaxProperties.magnification;
|
|
304
|
+
|
|
305
|
+
// Duration of press animation
|
|
306
|
+
float pressDuration = _tvParallaxProperties.pressDuration;
|
|
307
|
+
|
|
308
|
+
[UIView animateWithDuration:(pressDuration/2)
|
|
309
|
+
animations:^{
|
|
310
|
+
self.transform = CGAffineTransformMakeScale(magnification, magnification);
|
|
311
|
+
}
|
|
312
|
+
completion:^(__unused BOOL finished){}];
|
|
311
313
|
}
|
|
312
314
|
}
|
|
313
315
|
|
|
314
|
-
- (void)
|
|
316
|
+
- (void)emitPressInEvent
|
|
317
|
+
{
|
|
318
|
+
_eventEmitter->onPressIn();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
- (void)emitPressOutEvent
|
|
315
322
|
{
|
|
316
|
-
|
|
323
|
+
_eventEmitter->onPressOut();
|
|
317
324
|
}
|
|
318
325
|
|
|
319
326
|
- (void)addParallaxMotionEffects
|
|
@@ -576,6 +583,8 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
576
583
|
}
|
|
577
584
|
|
|
578
585
|
if (context.nextFocusedView == self && self.isUserInteractionEnabled && ![self isTVFocusGuide]) {
|
|
586
|
+
if(_eventEmitter) _eventEmitter->onFocus();
|
|
587
|
+
|
|
579
588
|
[self becomeFirstResponder];
|
|
580
589
|
[self enableDirectionalFocusGuides];
|
|
581
590
|
[coordinator addCoordinatedAnimations:^(void){
|
|
@@ -583,6 +592,8 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
583
592
|
[self sendFocusNotification:context];
|
|
584
593
|
} completion:^(void){}];
|
|
585
594
|
} else {
|
|
595
|
+
if (_eventEmitter) _eventEmitter->onBlur();
|
|
596
|
+
|
|
586
597
|
[self disableDirectionalFocusGuides];
|
|
587
598
|
[coordinator addCoordinatedAnimations:^(void){
|
|
588
599
|
[self removeParallaxMotionEffects];
|
|
@@ -1029,25 +1040,9 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
1029
1040
|
// `isTVSelectable`
|
|
1030
1041
|
if (oldViewProps.isTVSelectable != newViewProps.isTVSelectable) {
|
|
1031
1042
|
if (newViewProps.isTVSelectable && ![self isTVFocusGuide]) {
|
|
1032
|
-
|
|
1033
|
-
action:@selector(handleSelect:)];
|
|
1034
|
-
recognizer.allowedPressTypes = @[ @(UIPressTypeSelect) ];
|
|
1035
|
-
_selectRecognizer = recognizer;
|
|
1036
|
-
|
|
1037
|
-
UILongPressGestureRecognizer *longRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongSelect:)];
|
|
1038
|
-
recognizer.allowedPressTypes = @[ @(UIPressTypeSelect) ];
|
|
1039
|
-
[self addGestureRecognizer:longRecognizer];
|
|
1040
|
-
_longSelectRecognizer = longRecognizer;
|
|
1041
|
-
|
|
1042
|
-
[self addGestureRecognizer:_selectRecognizer];
|
|
1043
|
-
[self addGestureRecognizer:_longSelectRecognizer];
|
|
1043
|
+
self.tvRemoteSelectHandler = [[RCTTVRemoteSelectHandler alloc]initWithView:self];
|
|
1044
1044
|
} else {
|
|
1045
|
-
|
|
1046
|
-
[self removeGestureRecognizer:_selectRecognizer];
|
|
1047
|
-
}
|
|
1048
|
-
if (_longSelectRecognizer) {
|
|
1049
|
-
[self removeGestureRecognizer:_longSelectRecognizer];
|
|
1050
|
-
}
|
|
1045
|
+
self.tvRemoteSelectHandler = nil;
|
|
1051
1046
|
}
|
|
1052
1047
|
}
|
|
1053
1048
|
// `tvParallaxProperties
|
|
@@ -1077,6 +1072,9 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
1077
1072
|
_nextFocusUp = [rootView viewWithTag:newViewProps.nextFocusUp.value()];
|
|
1078
1073
|
[self enableDirectionalFocusGuides];
|
|
1079
1074
|
} else {
|
|
1075
|
+
if (self.focusGuideUp != nil) {
|
|
1076
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideUp];
|
|
1077
|
+
}
|
|
1080
1078
|
_nextFocusUp = nil;
|
|
1081
1079
|
}
|
|
1082
1080
|
}
|
|
@@ -1087,6 +1085,9 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
1087
1085
|
_nextFocusDown = [rootView viewWithTag:newViewProps.nextFocusDown.value()];
|
|
1088
1086
|
[self enableDirectionalFocusGuides];
|
|
1089
1087
|
} else {
|
|
1088
|
+
if (self.focusGuideDown != nil) {
|
|
1089
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideDown];
|
|
1090
|
+
}
|
|
1090
1091
|
_nextFocusDown = nil;
|
|
1091
1092
|
}
|
|
1092
1093
|
}
|
|
@@ -1097,6 +1098,9 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
1097
1098
|
_nextFocusLeft = [rootView viewWithTag:newViewProps.nextFocusLeft.value()];
|
|
1098
1099
|
[self enableDirectionalFocusGuides];
|
|
1099
1100
|
} else {
|
|
1101
|
+
if (self.focusGuideLeft != nil) {
|
|
1102
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideLeft];
|
|
1103
|
+
}
|
|
1100
1104
|
_nextFocusLeft = nil;
|
|
1101
1105
|
}
|
|
1102
1106
|
}
|
|
@@ -1107,6 +1111,9 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
1107
1111
|
_nextFocusRight = [rootView viewWithTag:newViewProps.nextFocusRight.value()];
|
|
1108
1112
|
[self enableDirectionalFocusGuides];
|
|
1109
1113
|
} else {
|
|
1114
|
+
if (self.focusGuideRight != nil) {
|
|
1115
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideRight];
|
|
1116
|
+
}
|
|
1110
1117
|
_nextFocusRight = nil;
|
|
1111
1118
|
}
|
|
1112
1119
|
}
|
package/React/Views/RCTTVView.h
CHANGED
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
#import <React/RCTView.h>
|
|
12
12
|
#import <React/RCTBridge.h>
|
|
13
|
+
#import <React/RCTTVRemoteSelectHandler.h>
|
|
13
14
|
|
|
14
15
|
// A RCTView with additional properties and methods for user interaction using the Apple TV focus engine.
|
|
15
|
-
@interface RCTTVView : RCTView
|
|
16
|
+
@interface RCTTVView : RCTView <RCTTVRemoteSelectHandlerDelegate>
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* TV event handlers
|
|
@@ -29,6 +30,10 @@
|
|
|
29
30
|
*/
|
|
30
31
|
@property (nonatomic, assign) BOOL hasTVPreferredFocus;
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Select and longSelect event handler
|
|
35
|
+
*/
|
|
36
|
+
@property (nonatomic, strong) RCTTVRemoteSelectHandler *tvRemoteSelectHandler;
|
|
32
37
|
/**
|
|
33
38
|
* Focus direction tags
|
|
34
39
|
*/
|
|
@@ -52,6 +57,19 @@
|
|
|
52
57
|
@property (nonatomic, assign) BOOL trapFocusLeft;
|
|
53
58
|
@property (nonatomic, assign) BOOL trapFocusRight;
|
|
54
59
|
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Focus
|
|
63
|
+
*/
|
|
64
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onFocus;
|
|
65
|
+
@property (nonatomic, copy) RCTBubblingEventBlock onBlur;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* TV Press Handlers
|
|
69
|
+
*/
|
|
70
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPressIn;
|
|
71
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPressOut;
|
|
72
|
+
|
|
55
73
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
56
74
|
|
|
57
75
|
/**
|
|
@@ -64,11 +82,6 @@
|
|
|
64
82
|
*/
|
|
65
83
|
- (void)sendBlurNotification:(UIFocusUpdateContext *)context;
|
|
66
84
|
|
|
67
|
-
/**
|
|
68
|
-
* Send Select Notification to listeners
|
|
69
|
-
*/
|
|
70
|
-
- (void)sendSelectNotification:(UIGestureRecognizer *)recognizer;
|
|
71
|
-
|
|
72
85
|
/**
|
|
73
86
|
* Adds Parallax Motion Effects if tvParallaxProperty is enabled
|
|
74
87
|
*/
|
package/React/Views/RCTTVView.m
CHANGED
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
|
|
23
23
|
@implementation RCTTVView {
|
|
24
24
|
__weak RCTBridge *_bridge;
|
|
25
|
-
UITapGestureRecognizer *_selectRecognizer;
|
|
26
|
-
UILongPressGestureRecognizer * _longSelectRecognizer;
|
|
27
25
|
BOOL motionEffectsAdded;
|
|
28
26
|
NSArray* focusDestinations;
|
|
29
27
|
id<UIFocusItem> previouslyFocusedItem;
|
|
@@ -77,64 +75,47 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
77
75
|
{
|
|
78
76
|
self->_isTVSelectable = isTVSelectable;
|
|
79
77
|
if (isTVSelectable && ![self isTVFocusGuide]) {
|
|
80
|
-
|
|
81
|
-
action:@selector(handleSelect:)];
|
|
82
|
-
recognizer.allowedPressTypes = @[ @(UIPressTypeSelect) ];
|
|
83
|
-
_selectRecognizer = recognizer;
|
|
84
|
-
|
|
85
|
-
UILongPressGestureRecognizer *longRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongSelect:)];
|
|
86
|
-
recognizer.allowedPressTypes = @[ @(UIPressTypeSelect) ];
|
|
87
|
-
[self addGestureRecognizer:longRecognizer];
|
|
88
|
-
_longSelectRecognizer = longRecognizer;
|
|
89
|
-
|
|
90
|
-
[self addGestureRecognizer:_selectRecognizer];
|
|
91
|
-
[self addGestureRecognizer:_longSelectRecognizer];
|
|
78
|
+
self.tvRemoteSelectHandler = [[RCTTVRemoteSelectHandler alloc] initWithView:self];
|
|
92
79
|
} else {
|
|
93
|
-
|
|
94
|
-
[self removeGestureRecognizer:_selectRecognizer];
|
|
95
|
-
}
|
|
96
|
-
if (_longSelectRecognizer) {
|
|
97
|
-
[self removeGestureRecognizer:_longSelectRecognizer];
|
|
98
|
-
}
|
|
80
|
+
self.tvRemoteSelectHandler = nil;
|
|
99
81
|
}
|
|
100
82
|
}
|
|
101
83
|
|
|
102
|
-
- (void)
|
|
84
|
+
- (void)animatePressIn
|
|
103
85
|
{
|
|
104
86
|
if ([self.tvParallaxProperties[@"enabled"] boolValue] == YES) {
|
|
105
|
-
float magnification = [self.tvParallaxProperties[@"magnification"] floatValue];
|
|
106
87
|
float pressMagnification = [self.tvParallaxProperties[@"pressMagnification"] floatValue];
|
|
107
|
-
|
|
108
|
-
// Duration of press animation
|
|
109
88
|
float pressDuration = [self.tvParallaxProperties[@"pressDuration"] floatValue];
|
|
110
|
-
|
|
111
|
-
// Delay of press animation
|
|
112
|
-
float pressDelay = [self.tvParallaxProperties[@"pressDelay"] floatValue];
|
|
113
|
-
|
|
114
|
-
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:pressDelay]];
|
|
115
|
-
|
|
116
89
|
[UIView animateWithDuration:(pressDuration/2)
|
|
117
90
|
animations:^{
|
|
118
91
|
self.transform = CGAffineTransformMakeScale(pressMagnification, pressMagnification);
|
|
119
92
|
}
|
|
120
|
-
completion:^(__unused BOOL
|
|
121
|
-
[UIView animateWithDuration:(pressDuration/2)
|
|
122
|
-
animations:^{
|
|
123
|
-
self.transform = CGAffineTransformMakeScale(magnification, magnification);
|
|
124
|
-
}
|
|
125
|
-
completion:^(__unused BOOL finished2) {
|
|
126
|
-
[self sendSelectNotification:r];
|
|
127
|
-
}];
|
|
128
|
-
}];
|
|
129
|
-
|
|
130
|
-
} else {
|
|
131
|
-
[self sendSelectNotification:r];
|
|
93
|
+
completion:^(__unused BOOL finished){}];
|
|
132
94
|
}
|
|
133
95
|
}
|
|
134
96
|
|
|
135
|
-
- (void)
|
|
97
|
+
- (void) animatePressOut
|
|
98
|
+
{
|
|
99
|
+
if ([self.tvParallaxProperties[@"enabled"] boolValue] == YES) {
|
|
100
|
+
float magnification = [self.tvParallaxProperties[@"magnification"] floatValue];
|
|
101
|
+
float pressDuration = [self.tvParallaxProperties[@"pressDuration"] floatValue];
|
|
102
|
+
|
|
103
|
+
[UIView animateWithDuration:(pressDuration/2)
|
|
104
|
+
animations:^{
|
|
105
|
+
self.transform = CGAffineTransformMakeScale(magnification, magnification);
|
|
106
|
+
}
|
|
107
|
+
completion:^(__unused BOOL finished){}];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
- (void)emitPressInEvent
|
|
112
|
+
{
|
|
113
|
+
if (self.onPressIn) self.onPressIn(nil);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
- (void)emitPressOutEvent
|
|
136
117
|
{
|
|
137
|
-
|
|
118
|
+
if (self.onPressOut) self.onPressOut(nil);
|
|
138
119
|
}
|
|
139
120
|
|
|
140
121
|
- (BOOL)isTVFocusGuide
|
|
@@ -323,6 +304,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
323
304
|
}
|
|
324
305
|
|
|
325
306
|
if (context.nextFocusedView == self && ![self isTVFocusGuide] && self.isTVSelectable ) {
|
|
307
|
+
if (self.onFocus) self.onFocus(nil);
|
|
326
308
|
[self becomeFirstResponder];
|
|
327
309
|
[self enableDirectionalFocusGuides];
|
|
328
310
|
[coordinator addCoordinatedAnimations:^(void){
|
|
@@ -330,6 +312,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
330
312
|
[self sendFocusNotification:context];
|
|
331
313
|
} completion:^(void){}];
|
|
332
314
|
} else {
|
|
315
|
+
if (self.onBlur) self.onBlur(nil);
|
|
333
316
|
[self disableDirectionalFocusGuides];
|
|
334
317
|
[coordinator addCoordinatedAnimations:^(void){
|
|
335
318
|
[self sendBlurNotification:context];
|
|
@@ -441,14 +424,19 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
441
424
|
[[NSNotificationCenter defaultCenter] postNavigationBlurEventWithTag:self.reactTag target:self.reactTag];
|
|
442
425
|
}
|
|
443
426
|
|
|
444
|
-
- (void)sendSelectNotification
|
|
427
|
+
- (void)sendSelectNotification
|
|
445
428
|
{
|
|
446
429
|
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventSelect keyAction:RCTTVRemoteEventKeyActionUp tag:self.reactTag target:self.reactTag];
|
|
447
430
|
}
|
|
448
431
|
|
|
449
|
-
- (void)
|
|
432
|
+
- (void)sendLongSelectBeganNotification
|
|
450
433
|
{
|
|
451
|
-
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:
|
|
434
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionDown tag:self.reactTag target:self.reactTag];
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
- (void)sendLongSelectEndedNotification
|
|
438
|
+
{
|
|
439
|
+
[[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventLongSelect keyAction:RCTTVRemoteEventKeyActionUp tag:self.reactTag target:self.reactTag];
|
|
452
440
|
}
|
|
453
441
|
|
|
454
442
|
- (RCTTVView *)getViewById:(NSNumber *)viewId {
|
|
@@ -458,23 +446,43 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
|
|
458
446
|
}
|
|
459
447
|
|
|
460
448
|
- (void)setNextFocusUp:(NSNumber *)nextFocusUp {
|
|
461
|
-
self
|
|
462
|
-
|
|
449
|
+
if (self.focusGuideUp != nil && nextFocusUp == nil) {
|
|
450
|
+
[[self rootView] removeLayoutGuide:self.focusGuideUp];
|
|
451
|
+
self.focusGuideUp = nil;
|
|
452
|
+
} else {
|
|
453
|
+
self->_nextFocusUp = [self getViewById: nextFocusUp];
|
|
454
|
+
[self enableDirectionalFocusGuides];
|
|
455
|
+
}
|
|
463
456
|
}
|
|
464
457
|
|
|
465
458
|
- (void)setNextFocusDown:(NSNumber *)nextFocusDown {
|
|
466
|
-
self
|
|
467
|
-
|
|
459
|
+
if (self.focusGuideDown != nil && nextFocusDown == nil) {
|
|
460
|
+
[[self rootView] removeLayoutGuide:self.focusGuideDown];
|
|
461
|
+
self.focusGuideDown = nil;
|
|
462
|
+
} else {
|
|
463
|
+
self->_nextFocusDown = [self getViewById: nextFocusDown];
|
|
464
|
+
[self enableDirectionalFocusGuides];
|
|
465
|
+
}
|
|
468
466
|
}
|
|
469
467
|
|
|
470
468
|
- (void)setNextFocusLeft:(NSNumber *)nextFocusLeft {
|
|
471
|
-
self
|
|
472
|
-
|
|
469
|
+
if (self.focusGuideLeft != nil && nextFocusLeft == nil) {
|
|
470
|
+
[[self rootView] removeLayoutGuide:self.focusGuideLeft];
|
|
471
|
+
self.focusGuideLeft = nil;
|
|
472
|
+
} else {
|
|
473
|
+
self->_nextFocusLeft = [self getViewById: nextFocusLeft];
|
|
474
|
+
[self enableDirectionalFocusGuides];
|
|
475
|
+
}
|
|
473
476
|
}
|
|
474
477
|
|
|
475
478
|
- (void)setNextFocusRight:(NSNumber *)nextFocusRight {
|
|
476
|
-
self
|
|
477
|
-
|
|
479
|
+
if (self.focusGuideRight != nil && nextFocusRight == nil) {
|
|
480
|
+
[[self rootView] removeLayoutGuide:self.focusGuideRight];
|
|
481
|
+
self.focusGuideRight = nil;
|
|
482
|
+
} else {
|
|
483
|
+
self->_nextFocusRight = [self getViewById: nextFocusRight];
|
|
484
|
+
[self enableDirectionalFocusGuides];
|
|
485
|
+
}
|
|
478
486
|
}
|
|
479
487
|
|
|
480
488
|
- (void)setPreferredFocus:(BOOL)hasTVPreferredFocus
|
|
@@ -197,6 +197,10 @@ RCT_EXPORT_VIEW_PROPERTY(trapFocusUp, BOOL)
|
|
|
197
197
|
RCT_EXPORT_VIEW_PROPERTY(trapFocusDown, BOOL)
|
|
198
198
|
RCT_EXPORT_VIEW_PROPERTY(trapFocusLeft, BOOL)
|
|
199
199
|
RCT_EXPORT_VIEW_PROPERTY(trapFocusRight, BOOL)
|
|
200
|
+
RCT_EXPORT_VIEW_PROPERTY(onFocus, RCTBubblingEventBlock)
|
|
201
|
+
RCT_EXPORT_VIEW_PROPERTY(onBlur, RCTBubblingEventBlock)
|
|
202
|
+
RCT_EXPORT_VIEW_PROPERTY(onPressIn, RCTDirectEventBlock)
|
|
203
|
+
RCT_EXPORT_VIEW_PROPERTY(onPressOut, RCTDirectEventBlock)
|
|
200
204
|
#endif
|
|
201
205
|
|
|
202
206
|
// Accessibility related properties
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
#if TARGET_OS_TV
|
|
24
24
|
#import "RCTTVRemoteHandler.h"
|
|
25
25
|
#import "RCTTVNavigationEventNotification.h"
|
|
26
|
+
#import "React/RCTI18nUtil.h"
|
|
26
27
|
#endif
|
|
27
28
|
|
|
28
29
|
#if !TARGET_OS_TV
|
|
@@ -1086,21 +1087,24 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
|
|
1086
1087
|
|
|
1087
1088
|
- (BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context
|
|
1088
1089
|
{
|
|
1089
|
-
//
|
|
1090
|
+
// Determine if the layout is Right-to-Left
|
|
1091
|
+
BOOL isRTL = [[RCTI18nUtil sharedInstance] isRTL];
|
|
1092
|
+
// Adjust for horizontal scrolling with RTL support
|
|
1090
1093
|
if ([self isHorizontal:self.scrollView]) {
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
+
BOOL isNavigatingToEnd = (isRTL ? context.focusHeading == UIFocusHeadingLeft : context.focusHeading == UIFocusHeadingRight);
|
|
1095
|
+
BOOL isNavigatingToStart = (isRTL ? context.focusHeading == UIFocusHeadingRight : context.focusHeading == UIFocusHeadingLeft);
|
|
1096
|
+
|
|
1097
|
+
if ((isNavigatingToEnd && self.scrollView.contentOffset.x < self.scrollView.contentSize.width - self.scrollView.visibleSize.width) ||
|
|
1098
|
+
(isNavigatingToStart && self.scrollView.contentOffset.x > 0)) {
|
|
1094
1099
|
return [UIFocusSystem environment:self containsEnvironment:context.nextFocusedItem];
|
|
1095
1100
|
}
|
|
1096
1101
|
} else {
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1102
|
+
// Handle vertical scrolling as before
|
|
1103
|
+
if ((context.focusHeading == UIFocusHeadingUp && self.scrollView.contentOffset.y > 0) ||
|
|
1104
|
+
(context.focusHeading == UIFocusHeadingDown && self.scrollView.contentOffset.y < self.scrollView.contentSize.height - self.scrollView.visibleSize.height)) {
|
|
1100
1105
|
return [UIFocusSystem environment:self containsEnvironment:context.nextFocusedItem];
|
|
1101
1106
|
}
|
|
1102
1107
|
}
|
|
1103
|
-
|
|
1104
1108
|
return [super shouldUpdateFocusInContext:context];
|
|
1105
1109
|
}
|
|
1106
1110
|
|
|
@@ -3306,7 +3306,6 @@ public final class com/facebook/react/modules/core/TimingModule : com/facebook/f
|
|
|
3306
3306
|
public fun createTimer (DDDZ)V
|
|
3307
3307
|
public fun deleteTimer (D)V
|
|
3308
3308
|
public fun emitTimeDriftWarning (Ljava/lang/String;)V
|
|
3309
|
-
public fun initialize ()V
|
|
3310
3309
|
public fun invalidate ()V
|
|
3311
3310
|
public fun setSendIdleEvents (Z)V
|
|
3312
3311
|
}
|
|
@@ -36,7 +36,7 @@ if(CMAKE_HOST_WIN32)
|
|
|
36
36
|
endif()
|
|
37
37
|
|
|
38
38
|
file(GLOB input_SRC CONFIGURE_DEPENDS
|
|
39
|
-
|
|
39
|
+
${REACT_ANDROID_DIR}/cmake-utils/default-app-setup/*.cpp
|
|
40
40
|
${BUILD_DIR}/generated/autolinking/src/main/jni/*.cpp)
|
|
41
41
|
|
|
42
42
|
add_library(${CMAKE_PROJECT_NAME} SHARED ${input_SRC})
|
|
@@ -65,6 +65,7 @@ public open class JavaTimerManager(
|
|
|
65
65
|
|
|
66
66
|
init {
|
|
67
67
|
reactApplicationContext.addLifecycleEventListener(this)
|
|
68
|
+
HeadlessJsTaskContext.getInstance(reactApplicationContext).addTaskEventListener(this)
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
override fun onHostPause() {
|
|
@@ -103,6 +104,7 @@ public open class JavaTimerManager(
|
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
public open fun onInstanceDestroy() {
|
|
107
|
+
HeadlessJsTaskContext.getInstance(reactApplicationContext).removeTaskEventListener(this)
|
|
106
108
|
reactApplicationContext.removeLifecycleEventListener(this)
|
|
107
109
|
clearFrameCallback()
|
|
108
110
|
clearChoreographerIdleCallback()
|
|
@@ -12,7 +12,6 @@ import com.facebook.react.bridge.ReactApplicationContext
|
|
|
12
12
|
import com.facebook.react.bridge.WritableArray
|
|
13
13
|
import com.facebook.react.common.annotations.VisibleForTesting
|
|
14
14
|
import com.facebook.react.devsupport.interfaces.DevSupportManager
|
|
15
|
-
import com.facebook.react.jstasks.HeadlessJsTaskContext
|
|
16
15
|
import com.facebook.react.module.annotations.ReactModule
|
|
17
16
|
|
|
18
17
|
/** Native module for JS timer execution. Timers fire on frame boundaries. */
|
|
@@ -24,11 +23,6 @@ public class TimingModule(
|
|
|
24
23
|
private val javaTimerManager: JavaTimerManager =
|
|
25
24
|
JavaTimerManager(reactContext, this, ReactChoreographer.getInstance(), devSupportManager)
|
|
26
25
|
|
|
27
|
-
override fun initialize() {
|
|
28
|
-
HeadlessJsTaskContext.getInstance(getReactApplicationContext())
|
|
29
|
-
.addTaskEventListener(javaTimerManager)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
26
|
override fun createTimer(
|
|
33
27
|
callbackIDDouble: Double,
|
|
34
28
|
durationDouble: Double,
|
|
@@ -68,8 +62,6 @@ public class TimingModule(
|
|
|
68
62
|
}
|
|
69
63
|
|
|
70
64
|
override fun invalidate() {
|
|
71
|
-
val headlessJsTaskContext = HeadlessJsTaskContext.getInstance(getReactApplicationContext())
|
|
72
|
-
headlessJsTaskContext.removeTaskEventListener(javaTimerManager)
|
|
73
65
|
javaTimerManager.onInstanceDestroy()
|
|
74
66
|
}
|
|
75
67
|
|
|
@@ -736,6 +736,16 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|
|
736
736
|
MapBuilder.of(
|
|
737
737
|
"phasedRegistrationNames",
|
|
738
738
|
MapBuilder.of("bubbled", "onClick", "captured", "onClickCapture")))
|
|
739
|
+
.put(
|
|
740
|
+
"topFocus",
|
|
741
|
+
MapBuilder.of(
|
|
742
|
+
"phasedRegistrationNames",
|
|
743
|
+
MapBuilder.of("bubbled", "onFocus", "captured", "onFocusCapture")))
|
|
744
|
+
.put(
|
|
745
|
+
"topBlur",
|
|
746
|
+
MapBuilder.of(
|
|
747
|
+
"phasedRegistrationNames",
|
|
748
|
+
MapBuilder.of("bubbled", "onBlur", "captured", "onBlurCapture")))
|
|
739
749
|
.build());
|
|
740
750
|
return eventTypeConstants;
|
|
741
751
|
}
|
|
@@ -751,6 +761,12 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|
|
751
761
|
.put(
|
|
752
762
|
"topAccessibilityAction",
|
|
753
763
|
MapBuilder.of("registrationName", "onAccessibilityAction"))
|
|
764
|
+
.put(
|
|
765
|
+
"topPressIn",
|
|
766
|
+
MapBuilder.of("registrationName", "onPressIn"))
|
|
767
|
+
.put(
|
|
768
|
+
"topPressOut",
|
|
769
|
+
MapBuilder.of("registrationName", "onPressOut"))
|
|
754
770
|
.build());
|
|
755
771
|
return eventTypeConstants;
|
|
756
772
|
}
|
package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java
CHANGED
|
@@ -568,6 +568,26 @@ public class ReactAccessibilityDelegate extends ExploreByTouchHelper {
|
|
|
568
568
|
if (action == AccessibilityNodeInfoCompat.ACTION_EXPAND) {
|
|
569
569
|
host.setTag(R.id.accessibility_state_expanded, true);
|
|
570
570
|
}
|
|
571
|
+
if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
|
|
572
|
+
final WritableMap payload = Arguments.createMap();
|
|
573
|
+
final int reactTag = host.getId();
|
|
574
|
+
payload.putString("eventType", "select");
|
|
575
|
+
payload.putInt("eventKeyAction", 1);
|
|
576
|
+
payload.putInt("tag", reactTag);
|
|
577
|
+
payload.putInt("target", reactTag);
|
|
578
|
+
ReactContext reactContext = (ReactContext) host.getContext();
|
|
579
|
+
reactContext.emitDeviceEvent("onHWKeyEvent", payload);
|
|
580
|
+
}
|
|
581
|
+
if (action == AccessibilityNodeInfoCompat.ACTION_LONG_CLICK) {
|
|
582
|
+
final WritableMap payload = Arguments.createMap();
|
|
583
|
+
final int reactTag = host.getId();
|
|
584
|
+
payload.putString("eventType", "longSelect");
|
|
585
|
+
payload.putInt("eventKeyAction", 1);
|
|
586
|
+
payload.putInt("tag", reactTag);
|
|
587
|
+
payload.putInt("target", reactTag);
|
|
588
|
+
ReactContext reactContext = (ReactContext) host.getContext();
|
|
589
|
+
reactContext.emitDeviceEvent("onHWKeyEvent", payload);
|
|
590
|
+
}
|
|
571
591
|
if (mAccessibilityActionsMap.containsKey(action)) {
|
|
572
592
|
final WritableMap event = Arguments.createMap();
|
|
573
593
|
event.putString("actionName", mAccessibilityActionsMap.get(action));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.facebook.react.uimanager.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
|
|
6
|
+
public class BlurEvent(surfaceId: Int, viewId: Int) :
|
|
7
|
+
Event<BlurEvent>(surfaceId, viewId) {
|
|
8
|
+
|
|
9
|
+
override fun getEventName(): String = EVENT_NAME
|
|
10
|
+
|
|
11
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
12
|
+
|
|
13
|
+
private companion object {
|
|
14
|
+
private const val EVENT_NAME: String = "topBlur"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.facebook.react.uimanager.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
|
|
6
|
+
public class FocusEvent(surfaceId: Int, viewId: Int) :
|
|
7
|
+
Event<FocusEvent>(surfaceId, viewId) {
|
|
8
|
+
|
|
9
|
+
override fun getEventName(): String = EVENT_NAME
|
|
10
|
+
|
|
11
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
12
|
+
|
|
13
|
+
private companion object {
|
|
14
|
+
private const val EVENT_NAME: String = "topFocus"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.facebook.react.uimanager.events
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
|
|
6
|
+
public class PressInEvent(surfaceId: Int, viewId: Int) :
|
|
7
|
+
Event<PressInEvent>(surfaceId, viewId) {
|
|
8
|
+
|
|
9
|
+
override fun getEventName(): String = EVENT_NAME
|
|
10
|
+
|
|
11
|
+
override fun getEventData(): WritableMap = Arguments.createMap()
|
|
12
|
+
|
|
13
|
+
private companion object {
|
|
14
|
+
private const val EVENT_NAME: String = "topPressIn"
|
|
15
|
+
}
|
|
16
|
+
}
|