react-native-tvos 0.68.1-1 → 0.68.2-2
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/Components/DrawerAndroid/AndroidDrawerLayoutNativeComponent.js +6 -6
- package/Libraries/Components/Pressable/Pressable.js +13 -2
- package/Libraries/Components/Pressable/useAndroidRippleForView.js +3 -1
- package/Libraries/Components/{AppleTV → TV}/NativeTVNavigationEventEmitter.js +0 -0
- package/Libraries/Components/{AppleTV → TV}/TVEventControl.js +0 -0
- package/Libraries/Components/{AppleTV → TV}/TVEventHandler.js +0 -0
- package/Libraries/Components/{AppleTV → TV}/TVFocusEventHandler.js +0 -0
- package/Libraries/Components/TV/TVFocusGuideView.js +135 -0
- package/Libraries/Components/{AppleTV → TV}/TVTextScrollView.js +0 -0
- package/Libraries/Components/{AppleTV → TV}/TVViewPropTypes.js +0 -0
- package/Libraries/Components/{AppleTV → TV}/tagForComponentOrHandle.js +0 -0
- package/Libraries/Components/{AppleTV → TV}/useTVEventHandler.js +0 -0
- package/Libraries/Components/Touchable/TVTouchable.js +1 -1
- package/Libraries/Components/Touchable/Touchable.js +1 -1
- package/Libraries/Components/Touchable/TouchableHighlight.js +19 -5
- package/Libraries/Components/Touchable/TouchableNativeFeedback.js +7 -6
- package/Libraries/Components/Touchable/TouchableOpacity.js +2 -2
- package/Libraries/Components/View/ReactNativeViewViewConfig.js +1 -1
- package/Libraries/Components/View/ViewPropTypes.js +1 -1
- package/Libraries/Lists/VirtualizedSectionList.js +2 -1
- package/Libraries/LogBox/UI/AnsiHighlight.js +4 -2
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +2 -2
- package/Libraries/Renderer/shims/createReactNativeComponentClass.js +1 -1
- package/Libraries/Utilities/BackHandler.ios.js +1 -1
- package/Libraries/Utilities/ReactNativeTestTools.js +5 -7
- package/README.md +6 -1
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.h +4 -0
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +83 -30
- package/React/Views/RCTTVView.h +9 -5
- package/React/Views/RCTTVView.m +98 -52
- package/ReactAndroid/build.gradle +2 -11
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/Android.mk +1 -0
- package/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/Android.mk +2 -0
- package/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/Android.mk +1 -0
- package/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk +1 -0
- package/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/Android.mk +1 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/Android.mk +1 -0
- package/ReactAndroid/src/main/java/com/facebook/react/reactperflogger/jni/Android.mk +1 -0
- package/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk +2 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/jni/Android.mk +1 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +173 -103
- package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java +20 -0
- package/ReactAndroid/src/main/jni/first-party/yogajni/Android.mk +1 -0
- package/ReactAndroid/src/main/jni/react/jni/Android.mk +2 -0
- package/ReactAndroid/src/main/jni/third-party/boost/Android.mk +1 -0
- package/ReactCommon/butter/Android.mk +1 -0
- package/ReactCommon/cxxreact/Android.mk +1 -0
- package/ReactCommon/hermes/executor/Android.mk +2 -0
- package/ReactCommon/hermes/inspector/Android.mk +1 -0
- package/ReactCommon/jsi/Android.mk +2 -0
- package/ReactCommon/jsiexecutor/Android.mk +1 -0
- package/ReactCommon/jsinspector/Android.mk +1 -0
- package/ReactCommon/logger/Android.mk +1 -0
- package/ReactCommon/react/config/Android.mk +1 -0
- package/ReactCommon/react/debug/Android.mk +1 -0
- package/ReactCommon/react/nativemodule/core/Android.mk +1 -0
- package/ReactCommon/react/nativemodule/samples/platform/android/Android.mk +1 -0
- package/ReactCommon/react/renderer/animations/Android.mk +1 -0
- package/ReactCommon/react/renderer/attributedstring/Android.mk +1 -0
- package/ReactCommon/react/renderer/componentregistry/Android.mk +1 -0
- package/ReactCommon/react/renderer/componentregistry/native/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/image/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/modal/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/progressbar/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/root/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/scrollview/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/slider/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/switch/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/text/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/textinput/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/unimplementedview/Android.mk +1 -0
- package/ReactCommon/react/renderer/components/view/Android.mk +1 -0
- package/ReactCommon/react/renderer/core/Android.mk +1 -0
- package/ReactCommon/react/renderer/debug/Android.mk +1 -0
- package/ReactCommon/react/renderer/graphics/Android.mk +1 -0
- package/ReactCommon/react/renderer/imagemanager/Android.mk +1 -0
- package/ReactCommon/react/renderer/leakchecker/Android.mk +1 -0
- package/ReactCommon/react/renderer/mapbuffer/Android.mk +1 -0
- package/ReactCommon/react/renderer/mounting/Android.mk +1 -0
- package/ReactCommon/react/renderer/runtimescheduler/Android.mk +1 -0
- package/ReactCommon/react/renderer/scheduler/Android.mk +1 -0
- package/ReactCommon/react/renderer/telemetry/Android.mk +1 -0
- package/ReactCommon/react/renderer/templateprocessor/Android.mk +1 -0
- package/ReactCommon/react/renderer/textlayoutmanager/Android.mk +1 -0
- package/ReactCommon/react/renderer/uimanager/Android.mk +1 -0
- package/ReactCommon/react/utils/Android.mk +1 -0
- package/ReactCommon/reactperflogger/Android.mk +1 -0
- package/ReactCommon/yoga/Android.mk +1 -0
- package/android/com/facebook/react/react-native/{0.68.1-1/react-native-0.68.1-1-sources.jar → 0.68.2-2/react-native-0.68.2-2-sources.jar} +0 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2-sources.jar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2-sources.jar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2-sources.jar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2-sources.jar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.68.1-1/react-native-0.68.1-1.aar → 0.68.2-2/react-native-0.68.2-2.aar} +0 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.aar.md5 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.aar.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.aar.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.aar.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.68.1-1/react-native-0.68.1-1.module → 0.68.2-2/react-native-0.68.2-2.module} +15 -15
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.module.md5 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.module.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.module.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.module.sha512 +1 -0
- package/android/com/facebook/react/react-native/{0.68.1-1/react-native-0.68.1-1.pom → 0.68.2-2/react-native-0.68.2-2.pom} +1 -1
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.pom.md5 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.pom.sha1 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.pom.sha256 +1 -0
- package/android/com/facebook/react/react-native/0.68.2-2/react-native-0.68.2-2.pom.sha512 +1 -0
- package/android/com/facebook/react/react-native/maven-metadata.xml +4 -4
- package/android/com/facebook/react/react-native/maven-metadata.xml.md5 +1 -1
- package/android/com/facebook/react/react-native/maven-metadata.xml.sha1 +1 -1
- package/android/com/facebook/react/react-native/maven-metadata.xml.sha256 +1 -1
- package/android/com/facebook/react/react-native/maven-metadata.xml.sha512 +1 -1
- package/index.js +11 -11
- package/package.json +2 -2
- package/template/android/app/build.gradle +1 -3
- package/template/android/build.gradle +0 -4
- package/template/package.json +1 -1
- package/tvos-types.d.ts +4 -0
- package/Libraries/Components/AppleTV/TVFocusGuideView.js +0 -79
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1-sources.jar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1-sources.jar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1-sources.jar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1-sources.jar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.aar.md5 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.aar.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.aar.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.aar.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.module.md5 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.module.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.module.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.module.sha512 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.pom.md5 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.pom.sha1 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.pom.sha256 +0 -1
- package/android/com/facebook/react/react-native/0.68.1-1/react-native-0.68.1-1.pom.sha512 +0 -1
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
* @flow strict-local
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {ViewProps} from '
|
|
12
|
-
import type {ColorValue} from '
|
|
11
|
+
import type {ViewProps} from '../../Components/View/ViewPropTypes';
|
|
12
|
+
import type {ColorValue} from '../../StyleSheet/StyleSheet';
|
|
13
13
|
import type {
|
|
14
14
|
WithDefault,
|
|
15
15
|
DirectEventHandler,
|
|
16
16
|
Int32,
|
|
17
17
|
Float,
|
|
18
|
-
} from '
|
|
19
|
-
import codegenNativeCommands from '
|
|
20
|
-
import codegenNativeComponent from '
|
|
21
|
-
import type {HostComponent} from '
|
|
18
|
+
} from '../../Types/CodegenTypes';
|
|
19
|
+
import codegenNativeCommands from '../../Utilities/codegenNativeCommands';
|
|
20
|
+
import codegenNativeComponent from '../../Utilities/codegenNativeComponent';
|
|
21
|
+
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
|
|
22
22
|
import * as React from 'react';
|
|
23
23
|
|
|
24
24
|
type DrawerStateEvent = $ReadOnly<{|
|
|
@@ -36,9 +36,10 @@ import type {
|
|
|
36
36
|
PressEvent,
|
|
37
37
|
} from '../../Types/CoreEventTypes';
|
|
38
38
|
import View from '../View/View';
|
|
39
|
-
import typeof TVParallaxPropertiesType from '../
|
|
39
|
+
import typeof TVParallaxPropertiesType from '../TV/TVViewPropTypes';
|
|
40
40
|
import Platform from '../../Utilities/Platform';
|
|
41
|
-
import {tvFocusEventHandler} from '../
|
|
41
|
+
import {tvFocusEventHandler} from '../TV/TVFocusEventHandler';
|
|
42
|
+
import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
|
|
42
43
|
|
|
43
44
|
type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, 'style'>;
|
|
44
45
|
|
|
@@ -212,6 +213,11 @@ function Pressable(props: Props, forwardedRef): React.Node {
|
|
|
212
213
|
onHoverIn,
|
|
213
214
|
onHoverOut,
|
|
214
215
|
isTVSelectable,
|
|
216
|
+
nextFocusDown,
|
|
217
|
+
nextFocusForward,
|
|
218
|
+
nextFocusLeft,
|
|
219
|
+
nextFocusRight,
|
|
220
|
+
nextFocusUp,
|
|
215
221
|
onBlur,
|
|
216
222
|
onFocus,
|
|
217
223
|
onLongPress,
|
|
@@ -354,6 +360,11 @@ function Pressable(props: Props, forwardedRef): React.Node {
|
|
|
354
360
|
{...restPropsWithDefaults}
|
|
355
361
|
{...eventHandlers}
|
|
356
362
|
ref={viewRef}
|
|
363
|
+
nextFocusDown={tagForComponentOrHandle(props.nextFocusDown)}
|
|
364
|
+
nextFocusForward={tagForComponentOrHandle(props.nextFocusForward)}
|
|
365
|
+
nextFocusLeft={tagForComponentOrHandle(props.nextFocusLeft)}
|
|
366
|
+
nextFocusRight={tagForComponentOrHandle(props.nextFocusRight)}
|
|
367
|
+
nextFocusUp={tagForComponentOrHandle(props.nextFocusUp)}
|
|
357
368
|
isTVSelectable={isTVSelectable !== false && accessible !== false}
|
|
358
369
|
style={typeof style === 'function' ? style({pressed, focused}) : style}
|
|
359
370
|
tvParallaxProperties={tvParallaxProperties}
|
|
@@ -12,7 +12,9 @@ import invariant from 'invariant';
|
|
|
12
12
|
import {Commands} from '../View/ViewNativeComponent';
|
|
13
13
|
import type {ColorValue} from '../../StyleSheet/StyleSheet';
|
|
14
14
|
import type {PressEvent} from '../../Types/CoreEventTypes';
|
|
15
|
-
import
|
|
15
|
+
import Platform from '../../Utilities/Platform';
|
|
16
|
+
import View from '../../Components/View/View';
|
|
17
|
+
import processColor from '../../StyleSheet/processColor';
|
|
16
18
|
import * as React from 'react';
|
|
17
19
|
import {useMemo} from 'react';
|
|
18
20
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its 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
|
+
* @flow
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const React = require('react');
|
|
12
|
+
const ReactNative = require('react-native');
|
|
13
|
+
import ReactNativeShims from '../../Renderer/shims/ReactNative';
|
|
14
|
+
const Platform = require('../../Utilities/Platform');
|
|
15
|
+
import {Commands} from '../View/ViewNativeComponent';
|
|
16
|
+
import type {ViewProps} from '../View/ViewPropTypes';
|
|
17
|
+
|
|
18
|
+
type TVFocusGuideViewProps = $ReadOnly<{
|
|
19
|
+
...ViewProps,
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The views the focus should go to
|
|
23
|
+
*/
|
|
24
|
+
destinations: ?(Object[]),
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* How the TVFocusGuideView content safe padding should be applied. "null" to disable it.
|
|
28
|
+
*/
|
|
29
|
+
safePadding?: 'vertical' | 'horizontal' | 'both' | null,
|
|
30
|
+
}>;
|
|
31
|
+
|
|
32
|
+
const TVFocusGuideView = (props: TVFocusGuideViewProps): React.Node => {
|
|
33
|
+
const safePadding =
|
|
34
|
+
props.safePadding === undefined ? 'both' : props.safePadding;
|
|
35
|
+
const focusGuidePadding =
|
|
36
|
+
safePadding === 'both'
|
|
37
|
+
? {padding: 1}
|
|
38
|
+
: safePadding === 'vertical'
|
|
39
|
+
? {paddingVertical: 1}
|
|
40
|
+
: safePadding === 'horizontal'
|
|
41
|
+
? {paddingHorizontal: 1}
|
|
42
|
+
: null;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The client specified layout(using 'style' prop) should be applied the container view ReactNative.View.
|
|
46
|
+
* And the focusGuide's layout should be overridden to wrap it fully inside the container view.
|
|
47
|
+
* For example, if the client specifies 'marginLeft' property in the style prop,
|
|
48
|
+
* then the TVFocusGuideView will apply the 'marginLeft' for both the parentView and the focusGuideView.
|
|
49
|
+
* and so, the left margin is getting added twice and UI becomes incorrect.
|
|
50
|
+
* The same is applicable for other layout properties.
|
|
51
|
+
*/
|
|
52
|
+
const focusGuideStyle = [focusGuidePadding, props.style, styles.focusGuide];
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
/**
|
|
56
|
+
* The container needs to have at least a width of 1 and a height of 1.
|
|
57
|
+
* Also, being the container, it shouldn't be possible to give it some padding.
|
|
58
|
+
*/
|
|
59
|
+
<ReactNative.View style={[props.style, styles.container]}>
|
|
60
|
+
{Platform.isTV ? (
|
|
61
|
+
Platform.isTVOS ? (
|
|
62
|
+
<FocusGuideViewTVOS {...props} style={focusGuideStyle} />
|
|
63
|
+
) : (
|
|
64
|
+
<FocusGuideViewAndroidTV {...props} style={focusGuideStyle} />
|
|
65
|
+
)
|
|
66
|
+
) : (
|
|
67
|
+
props.children
|
|
68
|
+
)}
|
|
69
|
+
</ReactNative.View>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const FocusGuideViewTVOS = (props: TVFocusGuideViewProps) => {
|
|
74
|
+
const focusGuideRef = React.useRef(null);
|
|
75
|
+
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
const nativeDestinations = (props.destinations || [])
|
|
78
|
+
.map(d => ReactNative.findNodeHandle(d))
|
|
79
|
+
.filter(c => c !== 0 && c !== null && c !== undefined);
|
|
80
|
+
const hostComponentRef = ReactNativeShims.findHostInstance_DEPRECATED(
|
|
81
|
+
focusGuideRef?.current,
|
|
82
|
+
);
|
|
83
|
+
hostComponentRef &&
|
|
84
|
+
Commands.setDestinations(hostComponentRef, nativeDestinations);
|
|
85
|
+
}, [props.destinations]);
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<ReactNative.View style={props.style} ref={focusGuideRef}>
|
|
89
|
+
{props.children}
|
|
90
|
+
</ReactNative.View>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const FocusGuideViewAndroidTV = (props: TVFocusGuideViewProps) => {
|
|
95
|
+
const nativeDestinations = React.useMemo(
|
|
96
|
+
() =>
|
|
97
|
+
(props.destinations || [])
|
|
98
|
+
.map(d => ReactNative.findNodeHandle(d))
|
|
99
|
+
.filter(c => c !== 0 && c !== null && c !== undefined),
|
|
100
|
+
[props.destinations],
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<ReactNative.View
|
|
105
|
+
style={props.style}
|
|
106
|
+
focusable={props.focusable ?? true}
|
|
107
|
+
destinations={nativeDestinations}
|
|
108
|
+
>
|
|
109
|
+
{props.children}
|
|
110
|
+
</ReactNative.View>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const styles = ReactNative.StyleSheet.create({
|
|
115
|
+
container: {
|
|
116
|
+
minWidth: 1,
|
|
117
|
+
minHeight: 1,
|
|
118
|
+
paddingTop: 0,
|
|
119
|
+
paddingBottom: 0,
|
|
120
|
+
paddingLeft: 0,
|
|
121
|
+
paddingRight: 0,
|
|
122
|
+
},
|
|
123
|
+
focusGuide: {
|
|
124
|
+
left: 0,
|
|
125
|
+
top: 0,
|
|
126
|
+
right: 0,
|
|
127
|
+
bottom: 0,
|
|
128
|
+
marginLeft: 0,
|
|
129
|
+
marginTop: 0,
|
|
130
|
+
marginRight: 0,
|
|
131
|
+
marginBottom: 0,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
module.exports = TVFocusGuideView;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -18,7 +18,7 @@ import type {
|
|
|
18
18
|
PressEvent,
|
|
19
19
|
} from '../../Types/CoreEventTypes';
|
|
20
20
|
import Platform from '../../Utilities/Platform';
|
|
21
|
-
import TVEventHandler from '../../Components/
|
|
21
|
+
import TVEventHandler from '../../Components/TV/TVEventHandler';
|
|
22
22
|
|
|
23
23
|
type TVTouchableConfig = $ReadOnly<{|
|
|
24
24
|
getDisabled: () => boolean,
|
|
@@ -15,7 +15,7 @@ import Platform from '../../Utilities/Platform';
|
|
|
15
15
|
import Position from './Position';
|
|
16
16
|
import UIManager from '../../ReactNative/UIManager';
|
|
17
17
|
import SoundManager from '../Sound/SoundManager';
|
|
18
|
-
import {tvFocusEventHandler} from '../
|
|
18
|
+
import {tvFocusEventHandler} from '../TV/TVFocusEventHandler';
|
|
19
19
|
|
|
20
20
|
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
|
|
21
21
|
|
|
@@ -19,6 +19,8 @@ import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback';
|
|
|
19
19
|
import Platform from '../../Utilities/Platform';
|
|
20
20
|
import View from '../../Components/View/View';
|
|
21
21
|
import type {ViewProps} from '../../Components/View/ViewPropTypes';
|
|
22
|
+
import typeof TVParallaxPropertiesType from '../TV/TVViewPropTypes';
|
|
23
|
+
import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
|
|
22
24
|
import * as React from 'react';
|
|
23
25
|
|
|
24
26
|
type AndroidProps = $ReadOnly<{|
|
|
@@ -29,9 +31,21 @@ type AndroidProps = $ReadOnly<{|
|
|
|
29
31
|
nextFocusUp?: ?number,
|
|
30
32
|
|}>;
|
|
31
33
|
|
|
34
|
+
type TVProps = $ReadOnly<{|
|
|
35
|
+
hasTVPreferredFocus?: ?boolean,
|
|
36
|
+
isTVSelectable?: ?boolean,
|
|
37
|
+
tvParallaxProperties?: ?TVParallaxPropertiesType,
|
|
38
|
+
nextFocusDown?: ?number,
|
|
39
|
+
nextFocusForward?: ?number,
|
|
40
|
+
nextFocusLeft?: ?number,
|
|
41
|
+
nextFocusRight?: ?number,
|
|
42
|
+
nextFocusUp?: ?number,
|
|
43
|
+
|}>;
|
|
44
|
+
|
|
32
45
|
type Props = $ReadOnly<{|
|
|
33
46
|
...React.ElementConfig<TouchableWithoutFeedback>,
|
|
34
47
|
...AndroidProps,
|
|
48
|
+
...TVProps,
|
|
35
49
|
...ViewProps,
|
|
36
50
|
|
|
37
51
|
activeOpacity?: ?number,
|
|
@@ -313,11 +327,11 @@ class TouchableHighlight extends React.Component<Props, State> {
|
|
|
313
327
|
hasTVPreferredFocus={this.props.hasTVPreferredFocus === true}
|
|
314
328
|
isTVSelectable={this.props.isTVSelectable !== false && this.props.accessible !== false}
|
|
315
329
|
tvParallaxProperties={this.props.tvParallaxProperties}
|
|
316
|
-
nextFocusDown={this.props.nextFocusDown}
|
|
317
|
-
nextFocusForward={this.props.nextFocusForward}
|
|
318
|
-
nextFocusLeft={this.props.nextFocusLeft}
|
|
319
|
-
nextFocusRight={this.props.nextFocusRight}
|
|
320
|
-
nextFocusUp={this.props.nextFocusUp}
|
|
330
|
+
nextFocusDown={tagForComponentOrHandle(this.props.nextFocusDown)}
|
|
331
|
+
nextFocusForward={tagForComponentOrHandle(this.props.nextFocusForward)}
|
|
332
|
+
nextFocusLeft={tagForComponentOrHandle(this.props.nextFocusLeft)}
|
|
333
|
+
nextFocusRight={tagForComponentOrHandle(this.props.nextFocusRight)}
|
|
334
|
+
nextFocusUp={tagForComponentOrHandle(this.props.nextFocusUp)}
|
|
321
335
|
focusable={
|
|
322
336
|
this.props.focusable !== false && this.props.onPress !== undefined
|
|
323
337
|
}
|
|
@@ -20,6 +20,7 @@ import type {PressEvent} from '../../Types/CoreEventTypes';
|
|
|
20
20
|
import Platform from '../../Utilities/Platform';
|
|
21
21
|
import View from '../../Components/View/View';
|
|
22
22
|
import processColor from '../../StyleSheet/processColor';
|
|
23
|
+
import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
|
|
23
24
|
import * as React from 'react';
|
|
24
25
|
import invariant from 'invariant';
|
|
25
26
|
|
|
@@ -291,11 +292,11 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
|
|
|
291
292
|
this.props.onPress !== undefined &&
|
|
292
293
|
!this.props.disabled,
|
|
293
294
|
nativeID: this.props.nativeID,
|
|
294
|
-
nextFocusDown: this.props.nextFocusDown,
|
|
295
|
-
nextFocusForward: this.props.nextFocusForward,
|
|
296
|
-
nextFocusLeft: this.props.nextFocusLeft,
|
|
297
|
-
nextFocusRight: this.props.nextFocusRight,
|
|
298
|
-
nextFocusUp: this.props.nextFocusUp,
|
|
295
|
+
nextFocusDown: tagForComponentOrHandle(this.props.nextFocusDown),
|
|
296
|
+
nextFocusForward: tagForComponentOrHandle(this.props.nextFocusForward),
|
|
297
|
+
nextFocusLeft: tagForComponentOrHandle(this.props.nextFocusLeft),
|
|
298
|
+
nextFocusRight: tagForComponentOrHandle(this.props.nextFocusRight),
|
|
299
|
+
nextFocusUp: tagForComponentOrHandle(this.props.nextFocusUp),
|
|
299
300
|
onLayout: this.props.onLayout,
|
|
300
301
|
testID: this.props.testID,
|
|
301
302
|
},
|
|
@@ -318,7 +319,7 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
|
|
|
318
319
|
}
|
|
319
320
|
},
|
|
320
321
|
onPress: event => {
|
|
321
|
-
if (this.props.onPress != null) {
|
|
322
|
+
if (this.props.onPress != null && Platform.OS !== 'android') {
|
|
322
323
|
this.props.onPress(event);
|
|
323
324
|
}
|
|
324
325
|
},
|
|
@@ -19,8 +19,8 @@ import Easing from '../../Animated/Easing';
|
|
|
19
19
|
import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
|
|
20
20
|
import flattenStyle from '../../StyleSheet/flattenStyle';
|
|
21
21
|
import Platform from '../../Utilities/Platform';
|
|
22
|
-
import typeof TVParallaxPropertiesType from '../
|
|
23
|
-
import tagForComponentOrHandle from '../
|
|
22
|
+
import typeof TVParallaxPropertiesType from '../TV/TVViewPropTypes';
|
|
23
|
+
import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
|
|
24
24
|
|
|
25
25
|
import * as React from 'react';
|
|
26
26
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import type {ViewConfig} from '../../Renderer/shims/ReactNativeTypes';
|
|
12
12
|
import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid';
|
|
13
13
|
import ReactNativeViewViewConfigAppleTV from './ReactNativeViewViewConfigAppleTV';
|
|
14
|
-
import
|
|
14
|
+
import Platform from '../../Utilities/Platform';
|
|
15
15
|
|
|
16
16
|
const ReactNativeViewConfig: ViewConfig = {
|
|
17
17
|
uiViewClassName: 'RCTView',
|
|
@@ -21,7 +21,7 @@ import type {
|
|
|
21
21
|
import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType';
|
|
22
22
|
import type {Node} from 'react';
|
|
23
23
|
import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
|
|
24
|
-
import type {TVViewProps} from '../
|
|
24
|
+
import type {TVViewProps} from '../TV/TVViewPropTypes';
|
|
25
25
|
import type {
|
|
26
26
|
AccessibilityRole,
|
|
27
27
|
AccessibilityState,
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
import invariant from 'invariant';
|
|
12
12
|
import type {ViewToken} from './ViewabilityHelper';
|
|
13
13
|
import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
|
|
14
|
-
import
|
|
14
|
+
import View from '../Components/View/View';
|
|
15
|
+
import VirtualizedList from './VirtualizedList';
|
|
15
16
|
import * as React from 'react';
|
|
16
17
|
|
|
17
18
|
type Item = any;
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
|
|
11
11
|
import {ansiToJson} from 'anser';
|
|
12
12
|
import * as React from 'react';
|
|
13
|
-
import
|
|
13
|
+
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
14
|
+
import Text from '../../Text/Text';
|
|
15
|
+
import View from '../../Components/View/View';
|
|
14
16
|
|
|
15
|
-
import type {TextStyleProp} from '
|
|
17
|
+
import type {TextStyleProp} from '../../StyleSheet/StyleSheet';
|
|
16
18
|
|
|
17
19
|
// Afterglow theme from https://iterm2colorschemes.com/
|
|
18
20
|
const COLORS = {
|
|
@@ -18,8 +18,8 @@ if (__DEV__) {
|
|
|
18
18
|
"use strict";
|
|
19
19
|
|
|
20
20
|
var React = require("react");
|
|
21
|
-
require("
|
|
22
|
-
var ReactNativePrivateInterface = require("
|
|
21
|
+
require("../../ReactPrivate/ReactNativePrivateInitializeCore");
|
|
22
|
+
var ReactNativePrivateInterface = require("../../ReactPrivate/ReactNativePrivateInterface");
|
|
23
23
|
var Scheduler = require("scheduler");
|
|
24
24
|
|
|
25
25
|
var ReactSharedInternals =
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
16
|
-
import {ReactNativeViewConfigRegistry} from '
|
|
16
|
+
import {ReactNativeViewConfigRegistry} from '../../ReactPrivate/ReactNativePrivateInterface';
|
|
17
17
|
import {type ViewConfig} from './ReactNativeTypes';
|
|
18
18
|
|
|
19
19
|
const {register} = ReactNativeViewConfigRegistry;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
16
16
|
const Platform = require('./Platform');
|
|
17
|
-
const TVEventHandler = require('../Components/
|
|
17
|
+
const TVEventHandler = require('../Components/TV/TVEventHandler');
|
|
18
18
|
|
|
19
19
|
type BackPressEventName = 'backPress' | 'hardwareBackPress';
|
|
20
20
|
|
|
@@ -35,13 +35,11 @@ export type ReactTestRendererJSON =
|
|
|
35
35
|
* delete this comment and run Flow. */
|
|
36
36
|
$ReturnType<ReactTestRenderer.create.toJSON>;
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
VirtualizedList,
|
|
44
|
-
} = require('react-native');
|
|
38
|
+
const Switch = require('../Components/Switch/Switch');
|
|
39
|
+
const Text = require('../Text/Text');
|
|
40
|
+
const TextInput = require('../Components/TextInput/TextInput');
|
|
41
|
+
const View = require('../Components/View/View');
|
|
42
|
+
const VirtualizedList = require('../Lists/VirtualizedList');
|
|
45
43
|
|
|
46
44
|
function byClickable(): Predicate {
|
|
47
45
|
return withMessage(
|
package/README.md
CHANGED
|
@@ -201,7 +201,12 @@ class Game2048 extends React.Component {
|
|
|
201
201
|
- `enableTVMenuKey`/`disableTVMenuKey`: Method to enable and disable the menu key gesture recognizer, in order to fix an issue with Apple's guidelines for menu key navigation (see https://github.com/facebook/react-native/issues/18930). The `RNTester` app uses these methods to implement correct menu key behavior for back navigation.
|
|
202
202
|
- `enableTVPanGesture`/`disableTVPanGesture`: Methods to enable and disable detection of finger touches that pan across the touch surface of the Siri remote. See `TVEventHandlerExample` in the `RNTester` app for a demo.
|
|
203
203
|
|
|
204
|
-
- _TVFocusGuideView_: This component provides support for Apple's `UIFocusGuide` API, to help ensure that focusable controls can be navigated to, even if they are not directly in line with other controls. An example is provided in `RNTester` that shows two different ways of using this component.
|
|
204
|
+
- _TVFocusGuideView_: This component provides support for Apple's `UIFocusGuide` API and is implemented in the same way for Android TV, to help ensure that focusable controls can be navigated to, even if they are not directly in line with other controls. An example is provided in `RNTester` that shows two different ways of using this component.
|
|
205
|
+
|
|
206
|
+
| Prop | Value | Description |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| destinations | any[] | Array of `Component`s to register as destinations of the FocusGuideView |
|
|
209
|
+
| safePadding | 'both' (default) \| 'vertical' \| 'horizontal' \| null | When the FocusGuide children are exactly the same size as the FocusGuide's container, the focus will almost certainly be given directly to the children without going through the FocusGuide. This prop make sure it doesn't happen by adding a padding of 1 in all directions.<br />"null" to disable it. |
|
|
205
210
|
|
|
206
211
|
- _Next Focus Direction_: the props `nextFocus*` on `View` should work as expected on iOS too (previously android only). One caveat is that if there is no focusable in the `nextFocusable*` direction next to the starting view, iOS doesn't check if we want to override the destination.
|
|
207
212
|
|
|
@@ -71,6 +71,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
71
71
|
|
|
72
72
|
#if TARGET_OS_TV
|
|
73
73
|
@property(nonatomic, nullable) UIFocusGuide *focusGuide;
|
|
74
|
+
@property(nonatomic, nullable) UIFocusGuide *focusGuideUp;
|
|
75
|
+
@property(nonatomic, nullable) UIFocusGuide *focusGuideDown;
|
|
76
|
+
@property(nonatomic, nullable) UIFocusGuide *focusGuideLeft;
|
|
77
|
+
@property(nonatomic, nullable) UIFocusGuide *focusGuideRight;
|
|
74
78
|
#endif
|
|
75
79
|
|
|
76
80
|
/**
|
|
@@ -309,41 +309,92 @@ using namespace facebook::react;
|
|
|
309
309
|
return _props->isTVSelectable;
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
self
|
|
324
|
-
|
|
325
|
-
|
|
312
|
+
// In tvOS, to support directional focus APIs, we add a UIFocusGuide for each
|
|
313
|
+
// side of the view where a nextFocus has been set. Set layout constraints to
|
|
314
|
+
// make the guide 1 px thick, and set the destination to the nextFocus object.
|
|
315
|
+
//
|
|
316
|
+
// This is only done once the view is focused.
|
|
317
|
+
//
|
|
318
|
+
- (void)enableDirectionalFocusGuides
|
|
319
|
+
{
|
|
320
|
+
if (self->_nextFocusUp != nil) {
|
|
321
|
+
if (self.focusGuideUp == nil) {
|
|
322
|
+
self.focusGuideUp = [UIFocusGuide new];
|
|
323
|
+
[[self containingRootView] addLayoutGuide:self.focusGuideUp];
|
|
324
|
+
|
|
325
|
+
[self.focusGuideUp.bottomAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
|
|
326
|
+
[self.focusGuideUp.widthAnchor constraintEqualToAnchor:self.widthAnchor].active = YES;
|
|
327
|
+
[self.focusGuideUp.heightAnchor constraintEqualToConstant:1.0].active = YES;
|
|
328
|
+
[self.focusGuideUp.leftAnchor constraintEqualToAnchor:self.leftAnchor].active = YES;
|
|
326
329
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
330
|
+
|
|
331
|
+
self.focusGuideUp.preferredFocusEnvironments = @[self->_nextFocusUp];
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (self->_nextFocusDown != nil) {
|
|
335
|
+
if (self.focusGuideDown == nil) {
|
|
336
|
+
self.focusGuideDown = [UIFocusGuide new];
|
|
337
|
+
[[self containingRootView] addLayoutGuide:self.focusGuideDown];
|
|
338
|
+
|
|
339
|
+
[self.focusGuideDown.topAnchor constraintEqualToAnchor:self.bottomAnchor].active = YES;
|
|
340
|
+
[self.focusGuideDown.widthAnchor constraintEqualToAnchor:self.widthAnchor].active = YES;
|
|
341
|
+
[self.focusGuideDown.heightAnchor constraintEqualToConstant:1.0].active = YES;
|
|
342
|
+
[self.focusGuideDown.leftAnchor constraintEqualToAnchor:self.leftAnchor].active = YES;
|
|
331
343
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
344
|
+
|
|
345
|
+
self.focusGuideDown.preferredFocusEnvironments = @[self->_nextFocusDown];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (self->_nextFocusLeft != nil) {
|
|
349
|
+
if (self.focusGuideLeft == nil) {
|
|
350
|
+
self.focusGuideLeft = [UIFocusGuide new];
|
|
351
|
+
[[self containingRootView] addLayoutGuide:self.focusGuideLeft];
|
|
352
|
+
|
|
353
|
+
[self.focusGuideLeft.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
|
|
354
|
+
[self.focusGuideLeft.widthAnchor constraintEqualToConstant:1.0].active = YES;
|
|
355
|
+
[self.focusGuideLeft.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = YES;
|
|
356
|
+
[self.focusGuideLeft.rightAnchor constraintEqualToAnchor:self.leftAnchor].active = YES;
|
|
336
357
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
358
|
+
|
|
359
|
+
self.focusGuideLeft.preferredFocusEnvironments = @[self->_nextFocusLeft];
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (self->_nextFocusRight != nil) {
|
|
363
|
+
if (self.focusGuideRight == nil) {
|
|
364
|
+
self.focusGuideRight = [UIFocusGuide new];
|
|
365
|
+
[[self containingRootView] addLayoutGuide:self.focusGuideRight];
|
|
366
|
+
|
|
367
|
+
[self.focusGuideRight.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
|
|
368
|
+
[self.focusGuideRight.widthAnchor constraintEqualToConstant:1.0].active = YES;
|
|
369
|
+
[self.focusGuideRight.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = YES;
|
|
370
|
+
[self.focusGuideRight.leftAnchor constraintEqualToAnchor:self.rightAnchor].active = YES;
|
|
341
371
|
}
|
|
342
|
-
|
|
343
|
-
|
|
372
|
+
|
|
373
|
+
self.focusGuideRight.preferredFocusEnvironments = @[self->_nextFocusRight];
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// Called when focus leaves this view -- disable the directional focus guides
|
|
377
|
+
// (if they exist) so that they don't interfere with focus navigation from
|
|
378
|
+
// other views
|
|
379
|
+
//
|
|
380
|
+
- (void)disableDirectionalFocusGuides
|
|
381
|
+
{
|
|
382
|
+
if (self.focusGuideUp != nil) {
|
|
383
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideUp];
|
|
384
|
+
self.focusGuideUp = nil;
|
|
385
|
+
}
|
|
386
|
+
if (self.focusGuideDown != nil) {
|
|
387
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideDown];
|
|
388
|
+
self.focusGuideDown = nil;
|
|
389
|
+
}
|
|
390
|
+
if (self.focusGuideLeft != nil) {
|
|
391
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideLeft];
|
|
392
|
+
self.focusGuideLeft = nil;
|
|
393
|
+
}
|
|
394
|
+
if (self.focusGuideRight != nil) {
|
|
395
|
+
[[self containingRootView] removeLayoutGuide:self.focusGuideRight];
|
|
396
|
+
self.focusGuideRight = nil;
|
|
344
397
|
}
|
|
345
|
-
self->_nextFocusActiveTarget = nil;
|
|
346
|
-
return true;
|
|
347
398
|
}
|
|
348
399
|
|
|
349
400
|
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
|
|
@@ -353,11 +404,13 @@ using namespace facebook::react;
|
|
|
353
404
|
}
|
|
354
405
|
if (context.nextFocusedView == self && self.isUserInteractionEnabled ) {
|
|
355
406
|
[self becomeFirstResponder];
|
|
407
|
+
[self enableDirectionalFocusGuides];
|
|
356
408
|
[coordinator addCoordinatedAnimations:^(void){
|
|
357
409
|
[self addParallaxMotionEffects];
|
|
358
410
|
[self sendFocusNotification:context];
|
|
359
411
|
} completion:^(void){}];
|
|
360
412
|
} else {
|
|
413
|
+
[self disableDirectionalFocusGuides];
|
|
361
414
|
[coordinator addCoordinatedAnimations:^(void){
|
|
362
415
|
[self removeParallaxMotionEffects];
|
|
363
416
|
[self sendBlurNotification:context];
|
package/React/Views/RCTTVView.h
CHANGED
|
@@ -32,11 +32,15 @@
|
|
|
32
32
|
/**
|
|
33
33
|
* Focus direction tags
|
|
34
34
|
*/
|
|
35
|
-
@property (nonatomic,
|
|
36
|
-
@property (nonatomic,
|
|
37
|
-
@property (nonatomic,
|
|
38
|
-
@property (nonatomic,
|
|
39
|
-
|
|
35
|
+
@property (nonatomic, weak) RCTTVView * nextFocusUp;
|
|
36
|
+
@property (nonatomic, weak) RCTTVView * nextFocusDown;
|
|
37
|
+
@property (nonatomic, weak) RCTTVView * nextFocusLeft;
|
|
38
|
+
@property (nonatomic, weak) RCTTVView * nextFocusRight;
|
|
39
|
+
|
|
40
|
+
@property (nonatomic, strong) UIFocusGuide * focusGuideUp;
|
|
41
|
+
@property (nonatomic, strong) UIFocusGuide * focusGuideDown;
|
|
42
|
+
@property (nonatomic, strong) UIFocusGuide * focusGuideLeft;
|
|
43
|
+
@property (nonatomic, strong) UIFocusGuide * focusGuideRight;
|
|
40
44
|
|
|
41
45
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
42
46
|
|