react-native-tvos 0.74.0-0rc2 → 0.74.1-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/RCTAppDelegate+Protected.h +16 -0
- package/Libraries/AppDelegate/RCTAppDelegate.mm +32 -1
- package/Libraries/AppDelegate/React-RCTAppDelegate.podspec +1 -0
- package/Libraries/Components/Touchable/TouchableBounce.js +1 -0
- package/Libraries/Components/Touchable/TouchableOpacity.js +1 -0
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/ReactNative/AppContainer-dev.js +6 -1
- package/Libraries/ReactNative/RendererImplementation.js +2 -0
- package/README.md +29 -9
- package/React/Base/RCTUtils.m +28 -8
- package/React/Base/RCTVersion.m +2 -2
- package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +2 -4
- package/React/CoreModules/RCTDevMenu.mm +1 -1
- package/React/CoreModules/RCTDevSettings.mm +9 -4
- package/React/CoreModules/RCTTVNavigationEventEmitter.mm +4 -0
- package/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.h +4 -0
- package/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm +16 -6
- package/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +45 -0
- package/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm +22 -2
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +7 -3
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +2 -0
- package/React/Fabric/RCTScheduler.h +2 -0
- package/React/Fabric/RCTScheduler.mm +6 -0
- package/React/Fabric/RCTSurfacePresenter.mm +5 -0
- package/React/Modules/RCTUIManager.m +8 -9
- package/React/Views/RCTComponentData.m +14 -1
- package/React/Views/RCTModalHostViewController.m +26 -0
- package/React/Views/ScrollView/RCTScrollView.m +1 -1
- package/ReactAndroid/api/ReactAndroid.api +1 -2
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java +24 -9
- package/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultNewArchitectureEntryPoint.kt +15 -0
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +19 -7
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +31 -11
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +7 -3
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +7 -3
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +34 -12
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +7 -3
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt +15 -22
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +10 -0
- package/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +1 -3
- package/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +38 -3
- package/ReactAndroid/src/main/jni/react/fabric/Binding.h +8 -0
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +43 -15
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +10 -4
- package/ReactCommon/ReactCommon.podspec +1 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
- package/ReactCommon/jsc/JSCRuntime.cpp +2 -0
- package/ReactCommon/jsinspector-modern/React-jsinspector.podspec +2 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +13 -5
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +16 -6
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +62 -26
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +8 -4
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +13 -5
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +4 -2
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +16 -6
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +7 -3
- package/ReactCommon/react/renderer/mounting/MountingTransaction.cpp +13 -0
- package/ReactCommon/react/renderer/mounting/MountingTransaction.h +9 -0
- package/ReactCommon/react/renderer/scheduler/Scheduler.cpp +7 -2
- package/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h +11 -0
- package/package.json +13 -13
- package/scripts/cocoapods/privacy_manifest_utils.rb +172 -0
- package/scripts/cocoapods/utils.rb +19 -3
- package/scripts/react_native_pods.rb +12 -2
- 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/src/private/featureflags/NativeReactNativeFeatureFlags.js +4 -2
- package/src/private/featureflags/ReactNativeFeatureFlags.js +16 -6
- package/template/package.json +5 -5
- package/third-party-podspecs/RCT-Folly.podspec +1 -0
- package/types/public/ReactNativeTVTypes.d.ts +4 -8
- package/ReactAndroid/src/main/java/com/facebook/react/ReactAndroidHWInputDeviceHelper.java +0 -98
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#if defined(__cplusplus)
|
|
9
|
+
|
|
10
|
+
#import <ReactCommon/RCTTurboModuleManager.h>
|
|
11
|
+
#import "RCTAppDelegate.h"
|
|
12
|
+
|
|
13
|
+
@interface RCTAppDelegate () <RCTTurboModuleManagerDelegate>
|
|
14
|
+
@end
|
|
15
|
+
|
|
16
|
+
#endif
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
#import <React/RCTRootView.h>
|
|
12
12
|
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
|
13
13
|
#import <React/RCTUtils.h>
|
|
14
|
-
#import <
|
|
14
|
+
#import <objc/runtime.h>
|
|
15
|
+
#import <react/featureflags/ReactNativeFeatureFlags.h>
|
|
16
|
+
#import <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
|
|
17
|
+
#import <react/renderer/graphics/ColorComponents.h>
|
|
18
|
+
#import "RCTAppDelegate+Protected.h"
|
|
15
19
|
#import "RCTAppSetupUtils.h"
|
|
16
20
|
|
|
17
21
|
#if RN_DISABLE_OSS_PLUGIN_HEADER
|
|
@@ -46,6 +50,8 @@
|
|
|
46
50
|
|
|
47
51
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
|
48
52
|
{
|
|
53
|
+
[self _setUpFeatureFlags];
|
|
54
|
+
|
|
49
55
|
RCTSetNewArchEnabled([self newArchEnabled]);
|
|
50
56
|
RCTAppSetupPrepareApp(application, self.turboModuleEnabled);
|
|
51
57
|
|
|
@@ -268,4 +274,29 @@
|
|
|
268
274
|
return [[RCTRootViewFactory alloc] initWithConfiguration:configuration andTurboModuleManagerDelegate:self];
|
|
269
275
|
}
|
|
270
276
|
|
|
277
|
+
#pragma mark - Feature Flags
|
|
278
|
+
|
|
279
|
+
class RCTAppDelegateBridgelessFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults {
|
|
280
|
+
public:
|
|
281
|
+
bool useModernRuntimeScheduler() override
|
|
282
|
+
{
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
bool enableMicrotasks() override
|
|
286
|
+
{
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
bool batchRenderingUpdatesInEventLoop() override
|
|
290
|
+
{
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
- (void)_setUpFeatureFlags
|
|
296
|
+
{
|
|
297
|
+
if ([self bridgelessEnabled]) {
|
|
298
|
+
facebook::react::ReactNativeFeatureFlags::override(std::make_unique<RCTAppDelegateBridgelessFeatureFlags>());
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
271
302
|
@end
|
|
@@ -18,8 +18,11 @@ import type {Props} from './AppContainer';
|
|
|
18
18
|
import ReactNativeStyleAttributes from '../Components/View/ReactNativeStyleAttributes';
|
|
19
19
|
import View from '../Components/View/View';
|
|
20
20
|
import Platform from '../Utilities/Platform';
|
|
21
|
+
/*
|
|
22
|
+
// Stub out DebuggingOverlay from TV for now
|
|
21
23
|
import DebuggingOverlay from '../Debugging/DebuggingOverlay';
|
|
22
24
|
import useSubscribeToDebuggingOverlayRegistry from '../Debugging/useSubscribeToDebuggingOverlayRegistry';
|
|
25
|
+
*/
|
|
23
26
|
import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter';
|
|
24
27
|
import LogBoxNotificationContainer from '../LogBox/LogBoxNotificationContainer';
|
|
25
28
|
import StyleSheet from '../StyleSheet/StyleSheet';
|
|
@@ -96,12 +99,14 @@ const AppContainer = ({
|
|
|
96
99
|
}: Props): React.Node => {
|
|
97
100
|
const appContainerRootViewRef: AppContainerRootViewRef = React.useRef(null);
|
|
98
101
|
const innerViewRef: InspectedViewRef = React.useRef(null);
|
|
102
|
+
/*
|
|
99
103
|
const debuggingOverlayRef: DebuggingOverlayRef = React.useRef(null);
|
|
100
104
|
|
|
101
105
|
useSubscribeToDebuggingOverlayRegistry(
|
|
102
106
|
appContainerRootViewRef,
|
|
103
107
|
debuggingOverlayRef,
|
|
104
108
|
);
|
|
109
|
+
*/
|
|
105
110
|
|
|
106
111
|
const [key, setKey] = useState(0);
|
|
107
112
|
const [shouldRenderInspector, setShouldRenderInspector] = useState(false);
|
|
@@ -172,7 +177,7 @@ const AppContainer = ({
|
|
|
172
177
|
pointerEvents="box-none">
|
|
173
178
|
{innerView}
|
|
174
179
|
|
|
175
|
-
{
|
|
180
|
+
{/* <DebuggingOverlay ref={debuggingOverlayRef} /> */}
|
|
176
181
|
|
|
177
182
|
{reactDevToolsAgent != null && (
|
|
178
183
|
<ReactDevToolsOverlayDeferred
|
|
@@ -47,9 +47,11 @@ export function findHostInstance_DEPRECATED<TElementType: ElementType>(
|
|
|
47
47
|
|
|
48
48
|
export function findNodeHandle<TElementType: ElementType>(
|
|
49
49
|
componentOrHandle: ?(ElementRef<TElementType> | number),
|
|
50
|
+
suppressWarning: ?Boolean,
|
|
50
51
|
): ?number {
|
|
51
52
|
return require('../Renderer/shims/ReactNative').findNodeHandle(
|
|
52
53
|
componentOrHandle,
|
|
54
|
+
suppressWarning,
|
|
53
55
|
);
|
|
54
56
|
}
|
|
55
57
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Apple TV and Android TV support for React Native are maintained here and in the corresponding `react-native-tvos` NPM package, and not in the [core repo](https://github.com/facebook/react-native/). This is a full fork of the main repository, with only the changes needed to support Apple TV and Android TV.
|
|
4
4
|
|
|
5
|
-
Releases of `react-native-tvos` will be based on a public release of `react-native`; e.g. the 0.
|
|
5
|
+
Releases of `react-native-tvos` will be based on a public release of `react-native`; e.g. the 0.74.0-0 release of this package will be derived from the 0.74.0 release of `react-native`. All releases of this repo will follow the 0.xx.x-y format, where x digits are from a specific RN core release, and y represents the additional versioning from this repo.
|
|
6
6
|
|
|
7
7
|
Releases will be published on npmjs.org and you may find the latest release version here: https://www.npmjs.com/package/react-native-tvos?activeTab=versions or use the tag `@latest`
|
|
8
8
|
|
|
@@ -16,6 +16,11 @@ To build your project for Apple TV, you should change your `package.json` import
|
|
|
16
16
|
|
|
17
17
|
You cannot use this package and the core react-native package simultaneously in a project.
|
|
18
18
|
|
|
19
|
+
This README covers only TV-specific features. For more general documentation and for changes between versions, you should also see these resources:
|
|
20
|
+
|
|
21
|
+
- React Native documentation: https://reactnative.dev
|
|
22
|
+
- The React Native changelog: https://github.com/facebook/react-native/blob/main/CHANGELOG.md
|
|
23
|
+
|
|
19
24
|
### Hermes JS support
|
|
20
25
|
|
|
21
26
|
As of the 0.71 release, Hermes is fully working on both Apple TV and Android TV, and is enabled by default.
|
|
@@ -25,6 +30,17 @@ As of the 0.71 release, Hermes is fully working on both Apple TV and Android TV,
|
|
|
25
30
|
- _Apple TV_: Modify your app's Podfile to set the `:fabric_enabled` value to `true` in both iOS and tvOS targets. After that, run `pod install` to pick up the additional pods needed for the new architecture. Some components (TVTextScrollView, TabBarIOS) have not been reimplemented in the new architecture so they will show up as an "unimplemented component".
|
|
26
31
|
- _Android TV_: To enable Fabric, modify `android/gradle.properties` in your app and set `newArchEnabled=true`, then rebuild your app.
|
|
27
32
|
|
|
33
|
+
As of the 0.74 release, bridgeless is the default when Fabric is enabled.
|
|
34
|
+
|
|
35
|
+
Known issue: The `TVFocusGuide` `autofocus` API has problems on Apple TV when bridgeless is enabled. If you need to use Fabric without bridgeless on Apple TV, you can override the default by adding the method below in `AppDelegate.mm`:
|
|
36
|
+
|
|
37
|
+
```objc
|
|
38
|
+
- (BOOL)bridgelessEnabled
|
|
39
|
+
{
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
28
44
|
### Typescript
|
|
29
45
|
|
|
30
46
|
Typescript types for TV-specific components and APIs have been added to `types/public`.
|
|
@@ -33,21 +49,26 @@ Typescript types for TV-specific components and APIs have been added to `types/p
|
|
|
33
49
|
|
|
34
50
|
TV device support has been implemented with the intention of making existing React Native applications "just work" on TV, with few or no changes needed in the JavaScript code for the applications.
|
|
35
51
|
|
|
36
|
-
The RNTester app supports Apple TV and Android TV. In this repo, `RNTester/Podfile` and `RNTester/RNTesterPods.xcodeproj` have been modified to work for tvOS.
|
|
52
|
+
The RNTester app supports Apple TV and Android TV. In this repo, `RNTester/Podfile` and `RNTester/RNTesterPods.xcodeproj` have been modified to work for tvOS.
|
|
37
53
|
|
|
54
|
+
Minimum operating system versions:
|
|
38
55
|
|
|
39
|
-
|
|
56
|
+
- Apple TV: tvOS 13.4
|
|
57
|
+
- Android TV:
|
|
58
|
+
- API level 21 (for the 0.73 releases)
|
|
59
|
+
- API level 23 (for the 0.74 release)
|
|
40
60
|
|
|
41
61
|
## Build changes
|
|
42
62
|
|
|
43
63
|
- _Native layer for Apple TV_: React Native Xcode projects all now have Apple TV build targets, with names ending in the string '-tvOS'. Changes in the React Native podspecs in 0.73 now require that your application `Podfile` only have one target. This repo supports either an iOS target or a tvOS target, but both targets should not be active at the same time. The new app template now has the iOS target commented out.
|
|
44
|
-
- _Maven artifacts for Android TV_: In 0.71, the React Native Android prebuilt archives are published to Maven instead of being included in the NPM. We are following the same model, except that the Maven artifacts will be in group `io.github.react-native-tvos` instead of `com.facebook.react`. The `@react-native/gradle-plugin` module has been upgraded so that the Android dependencies will be detected correctly during build.
|
|
64
|
+
- _Maven artifacts for Android TV_: In 0.71 and later releases, the React Native Android prebuilt archives are published to Maven instead of being included in the NPM. We are following the same model, except that the Maven artifacts will be in group `io.github.react-native-tvos` instead of `com.facebook.react`. The `@react-native/gradle-plugin` module has been upgraded so that the Android dependencies will be detected correctly during build.
|
|
45
65
|
|
|
46
66
|
## _(New)_ Project creation using the Expo CLI
|
|
47
67
|
|
|
48
68
|
> _Pitfall:_ Make sure you do not globally install `react-native` or `react-native-tvos`. If you have done this the wrong way, you may get error messages like `ld: library not found for -lPods-TestApp-tvOS`.
|
|
49
69
|
|
|
50
70
|
We strongly recommend [Yarn](https://classic.yarnpkg.com/en/docs/install) as the package manager.
|
|
71
|
+
You should install `yarn` globally, as it should be used instead of `npm` for working in React Native projects.
|
|
51
72
|
|
|
52
73
|
To create a new project, use `yarn create react-native-app` as shown below. (This will install the Expo tool `create-react-native-app` for you if it is not already present.)
|
|
53
74
|
|
|
@@ -104,8 +125,6 @@ var running_on_tv = Platform.isTV;
|
|
|
104
125
|
var running_on_apple_tv = Platform.isTVOS;
|
|
105
126
|
```
|
|
106
127
|
|
|
107
|
-
|
|
108
|
-
|
|
109
128
|
- _Common codebase for iOS and tvOS_: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS. Apple TV specific changes in native code are all wrapped by the TARGET_OS_TV define. These include changes to suppress APIs that are not supported on tvOS (e.g. web views, sliders, switches, status bar, etc.), and changes to support user input from the TV remote or keyboard.
|
|
110
129
|
|
|
111
130
|
- _Common codebase for Android phone and Android TV_: Apps built for Android using this repo will run on both Android phone and Android TV. Most of the changes for TV are specific to handling focus-based navigation on a TV using the D-Pad on the remote control.
|
|
@@ -114,9 +133,10 @@ var running_on_apple_tv = Platform.isTVOS;
|
|
|
114
133
|
|
|
115
134
|
- `onFocus` will be executed when the touchable view goes into focus
|
|
116
135
|
- `onBlur` will be executed when the touchable view goes out of focus
|
|
117
|
-
- `onPress` will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.
|
|
136
|
+
- `onPress` will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote (center button on Apple TV remote, or center button on Android TV DPad).
|
|
137
|
+
- `onLongPress` will be executed twice if the "select" button is held down for a length of time. The two events passed into `onLongPress()` will have different values for their `eventKeyAction` property, 0 for key down (start) and 1 for key up (end).
|
|
118
138
|
|
|
119
|
-
- _Pressable controls_: The `Pressable` API works with TV. Additional `onFocus` and `onBlur` props are provided to allow you to customize behavior when a Pressable enters or leaves focus. Similar to the `pressed` state that is true while a user is pressing the component on a touchscreen, the `focused` state will be true when it is focused on TV. `PressableExample` in RNTester has been modified appropriately.
|
|
139
|
+
- _Pressable controls_: The `Pressable` API works with TV. Additional `onFocus` and `onBlur` props are provided to allow you to customize behavior when a Pressable enters or leaves focus. Similar to the `pressed` state that is true while a user is pressing the component on a touchscreen, the `focused` state will be true when it is focused on TV. `PressableExample` in RNTester has been modified appropriately. The `onPress()` and `onLongPress()` methods work the same way as with `Touchable` components.
|
|
120
140
|
|
|
121
141
|
- _TV remote/keyboard input_: Application code that needs to implement custom handling of TV remote events can create an instance of `TVEventHandler` and listen for these events. For a more convenient API, we provide `useTVEventHandler`.
|
|
122
142
|
|
|
@@ -189,7 +209,7 @@ class Game2048 extends React.Component {
|
|
|
189
209
|
|
|
190
210
|
- _Flipper_: We do not support Flipper.
|
|
191
211
|
|
|
192
|
-
- _LogBox_: The
|
|
212
|
+
- _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.
|
|
193
213
|
|
|
194
214
|
- _Dev Menu support_: 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.
|
|
195
215
|
|
package/React/Base/RCTUtils.m
CHANGED
|
@@ -562,17 +562,37 @@ UIWindow *__nullable RCTKeyWindow(void)
|
|
|
562
562
|
return nil;
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
565
|
+
NSSet<UIScene *> *connectedScenes = RCTSharedApplication().connectedScenes;
|
|
566
|
+
|
|
567
|
+
UIScene *foregroundActiveScene;
|
|
568
|
+
UIScene *foregroundInactiveScene;
|
|
569
|
+
|
|
570
|
+
for (UIScene *scene in connectedScenes) {
|
|
571
|
+
if (![scene isKindOfClass:[UIWindowScene class]]) {
|
|
568
572
|
continue;
|
|
569
573
|
}
|
|
570
|
-
UIWindowScene *windowScene = (UIWindowScene *)scene;
|
|
571
574
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
575
|
+
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
|
576
|
+
foregroundActiveScene = scene;
|
|
577
|
+
break;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (!foregroundInactiveScene && scene.activationState == UISceneActivationStateForegroundInactive) {
|
|
581
|
+
foregroundInactiveScene = scene;
|
|
582
|
+
// no break, we can have the active scene later in the set.
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
UIScene *sceneToUse = foregroundActiveScene ? foregroundActiveScene : foregroundInactiveScene;
|
|
587
|
+
UIWindowScene *windowScene = (UIWindowScene *)sceneToUse;
|
|
588
|
+
|
|
589
|
+
if (@available(iOS 15.0, *)) {
|
|
590
|
+
return windowScene.keyWindow;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
for (UIWindow *window in windowScene.windows) {
|
|
594
|
+
if (window.isKeyWindow) {
|
|
595
|
+
return window;
|
|
576
596
|
}
|
|
577
597
|
}
|
|
578
598
|
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -23,8 +23,8 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
|
|
23
23
|
__rnVersion = @{
|
|
24
24
|
RCTVersionMajor: @(0),
|
|
25
25
|
RCTVersionMinor: @(74),
|
|
26
|
-
RCTVersionPatch: @(
|
|
27
|
-
RCTVersionPrerelease: @"
|
|
26
|
+
RCTVersionPatch: @(1),
|
|
27
|
+
RCTVersionPrerelease: @"0",
|
|
28
28
|
};
|
|
29
29
|
});
|
|
30
30
|
return __rnVersion;
|
|
@@ -146,13 +146,11 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
|
146
146
|
[super surface:surface didChangeStage:stage];
|
|
147
147
|
if (RCTSurfaceStageIsRunning(stage)) {
|
|
148
148
|
[_bridge.performanceLogger markStopForTag:RCTPLTTI];
|
|
149
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
150
149
|
#if TARGET_OS_TV
|
|
150
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
151
151
|
self.tvRemoteHandler = [[RCTTVRemoteHandler alloc] initWithView:[self contentView]];
|
|
152
|
-
#endif
|
|
153
|
-
|
|
154
|
-
[[NSNotificationCenter defaultCenter] postNotificationName:RCTContentDidAppearNotification object:self];
|
|
155
152
|
});
|
|
153
|
+
#endif
|
|
156
154
|
}
|
|
157
155
|
}
|
|
158
156
|
|
|
@@ -396,7 +396,7 @@ RCT_EXPORT_METHOD(show)
|
|
|
396
396
|
? UIAlertControllerStyleActionSheet
|
|
397
397
|
: UIAlertControllerStyleAlert;
|
|
398
398
|
|
|
399
|
-
NSString *devMenuType = self.bridge ? @"Bridge" : @"Bridgeless";
|
|
399
|
+
NSString *devMenuType = [self.bridge isKindOfClass:RCTBridge.class] ? @"Bridge" : @"Bridgeless";
|
|
400
400
|
NSString *devMenuTitle = [NSString stringWithFormat:@"React Native Dev Menu (%@)", devMenuType];
|
|
401
401
|
|
|
402
402
|
_actionSheet = [UIAlertController alertControllerWithTitle:devMenuTitle message:description preferredStyle:style];
|
|
@@ -158,6 +158,11 @@ RCT_EXPORT_MODULE()
|
|
|
158
158
|
return NO;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
- (BOOL)_isBridgeMode
|
|
162
|
+
{
|
|
163
|
+
return [self.bridge isKindOfClass:[RCTBridge class]];
|
|
164
|
+
}
|
|
165
|
+
|
|
161
166
|
- (instancetype)initWithDataSource:(id<RCTDevSettingsDataSource>)dataSource
|
|
162
167
|
{
|
|
163
168
|
if (self = [super init]) {
|
|
@@ -178,7 +183,7 @@ RCT_EXPORT_MODULE()
|
|
|
178
183
|
- (void)initialize
|
|
179
184
|
{
|
|
180
185
|
#if RCT_DEV_SETTINGS_ENABLE_PACKAGER_CONNECTION
|
|
181
|
-
if (self
|
|
186
|
+
if ([self _isBridgeMode]) {
|
|
182
187
|
RCTBridge *__weak weakBridge = self.bridge;
|
|
183
188
|
_bridgeExecutorOverrideToken = [[RCTPackagerConnection sharedPackagerConnection]
|
|
184
189
|
addNotificationHandler:^(id params) {
|
|
@@ -209,7 +214,7 @@ RCT_EXPORT_MODULE()
|
|
|
209
214
|
#endif
|
|
210
215
|
|
|
211
216
|
#if RCT_ENABLE_INSPECTOR
|
|
212
|
-
if (self
|
|
217
|
+
if ([self _isBridgeMode]) {
|
|
213
218
|
// We need this dispatch to the main thread because the bridge is not yet
|
|
214
219
|
// finished with its initialisation. By the time it relinquishes control of
|
|
215
220
|
// the main thread, this operation can be performed.
|
|
@@ -250,7 +255,7 @@ RCT_EXPORT_MODULE()
|
|
|
250
255
|
{
|
|
251
256
|
[super invalidate];
|
|
252
257
|
#if RCT_DEV_SETTINGS_ENABLE_PACKAGER_CONNECTION
|
|
253
|
-
if (self
|
|
258
|
+
if ([self _isBridgeMode]) {
|
|
254
259
|
[[RCTPackagerConnection sharedPackagerConnection] removeHandler:_bridgeExecutorOverrideToken];
|
|
255
260
|
}
|
|
256
261
|
|
|
@@ -281,7 +286,7 @@ RCT_EXPORT_MODULE()
|
|
|
281
286
|
- (BOOL)isDeviceDebuggingAvailable
|
|
282
287
|
{
|
|
283
288
|
#if RCT_ENABLE_INSPECTOR
|
|
284
|
-
if (self
|
|
289
|
+
if ([self _isBridgeMode]) {
|
|
285
290
|
return self.bridge.isInspectable;
|
|
286
291
|
} else {
|
|
287
292
|
return self.isInspectable;
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
#import "RCTTVNavigationEventEmitter.h"
|
|
9
|
+
#if TARGET_OS_TV
|
|
9
10
|
#import "RCTTVNavigationEventNotificationConstants.h"
|
|
11
|
+
#endif
|
|
10
12
|
|
|
11
13
|
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
|
12
14
|
#import "CoreModulesPlugins.h"
|
|
@@ -28,10 +30,12 @@ RCT_EXPORT_MODULE()
|
|
|
28
30
|
- (instancetype)init
|
|
29
31
|
{
|
|
30
32
|
if (self = [super init]) {
|
|
33
|
+
#if TARGET_OS_TV
|
|
31
34
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
32
35
|
selector:@selector(handleTVNavigationEventNotification:)
|
|
33
36
|
name:RCTTVNavigationEventNotificationName
|
|
34
37
|
object:nil];
|
|
38
|
+
#endif
|
|
35
39
|
}
|
|
36
40
|
return self;
|
|
37
41
|
}
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
@protocol RCTFabricModalHostViewControllerDelegate <NSObject>
|
|
11
11
|
- (void)boundsDidChange:(CGRect)newBounds;
|
|
12
|
+
#if TARGET_OS_TV
|
|
13
|
+
- (void)enableEventHandlers;
|
|
14
|
+
- (void)disableEventHandlers;
|
|
15
|
+
#endif
|
|
12
16
|
@end
|
|
13
17
|
|
|
14
18
|
@interface RCTFabricModalHostViewController : UIViewController
|
|
@@ -42,18 +42,28 @@
|
|
|
42
42
|
[_touchHandler attachToView:self.view];
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
#if !TARGET_OS_TV
|
|
46
|
-
- (UIStatusBarStyle)preferredStatusBarStyle
|
|
47
|
-
{
|
|
48
|
-
return [RCTUIStatusBarManager() statusBarStyle];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
45
|
- (void)viewDidDisappear:(BOOL)animated
|
|
52
46
|
{
|
|
53
47
|
[super viewDidDisappear:animated];
|
|
54
48
|
_lastViewBounds = CGRectZero;
|
|
55
49
|
}
|
|
56
50
|
|
|
51
|
+
#if TARGET_OS_TV
|
|
52
|
+
- (void)viewDidAppear:(BOOL)animated
|
|
53
|
+
{
|
|
54
|
+
[self.delegate enableEventHandlers];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (void)viewWillDisappear:(BOOL)animated
|
|
58
|
+
{
|
|
59
|
+
[self.delegate disableEventHandlers];
|
|
60
|
+
}
|
|
61
|
+
#else
|
|
62
|
+
- (UIStatusBarStyle)preferredStatusBarStyle
|
|
63
|
+
{
|
|
64
|
+
return [RCTUIStatusBarManager() statusBarStyle];
|
|
65
|
+
}
|
|
66
|
+
|
|
57
67
|
- (BOOL)prefersStatusBarHidden
|
|
58
68
|
{
|
|
59
69
|
return [RCTUIStatusBarManager() isStatusBarHidden];
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
|
|
20
20
|
#import "RCTFabricModalHostViewController.h"
|
|
21
21
|
|
|
22
|
+
#if TARGET_OS_TV
|
|
23
|
+
#import <React/RCTTVRemoteHandler.h>
|
|
24
|
+
#endif
|
|
25
|
+
|
|
22
26
|
using namespace facebook::react;
|
|
23
27
|
|
|
24
28
|
#if !TARGET_OS_TV
|
|
@@ -115,6 +119,10 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
115
119
|
BOOL _shouldPresent;
|
|
116
120
|
BOOL _isPresented;
|
|
117
121
|
UIView *_modalContentsSnapshot;
|
|
122
|
+
#if TARGET_OS_TV
|
|
123
|
+
UITapGestureRecognizer *_menuButtonGestureRecognizer;
|
|
124
|
+
RCTTVRemoteHandler *_tvRemoteHandler;
|
|
125
|
+
#endif
|
|
118
126
|
}
|
|
119
127
|
|
|
120
128
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
@@ -122,6 +130,11 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
122
130
|
if (self = [super initWithFrame:frame]) {
|
|
123
131
|
_props = ModalHostViewShadowNode::defaultSharedProps();
|
|
124
132
|
_shouldAnimatePresentation = YES;
|
|
133
|
+
#if TARGET_OS_TV
|
|
134
|
+
_menuButtonGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
|
|
135
|
+
action:@selector(menuButtonPressed)];
|
|
136
|
+
_menuButtonGestureRecognizer.allowedPressTypes = @[ @(UIPressTypeMenu) ];
|
|
137
|
+
#endif
|
|
125
138
|
|
|
126
139
|
_isPresented = NO;
|
|
127
140
|
}
|
|
@@ -129,6 +142,38 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
|
|
|
129
142
|
return self;
|
|
130
143
|
}
|
|
131
144
|
|
|
145
|
+
#if TARGET_OS_TV
|
|
146
|
+
- (void)menuButtonPressed {
|
|
147
|
+
UIView *snapshot = _modalContentsSnapshot;
|
|
148
|
+
[self.viewController.view addSubview:snapshot];
|
|
149
|
+
[self dismissViewController:self.viewController
|
|
150
|
+
animated:_shouldAnimatePresentation
|
|
151
|
+
completion:^{
|
|
152
|
+
[snapshot removeFromSuperview];
|
|
153
|
+
auto eventEmitter = [self modalEventEmitter];
|
|
154
|
+
if (eventEmitter) {
|
|
155
|
+
eventEmitter->onDismiss(ModalHostViewEventEmitter::OnDismiss{});
|
|
156
|
+
eventEmitter->onRequestClose(ModalHostViewEventEmitter::OnRequestClose{});
|
|
157
|
+
}
|
|
158
|
+
}];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
- (void)enableEventHandlers
|
|
162
|
+
{
|
|
163
|
+
_tvRemoteHandler = [[RCTTVRemoteHandler alloc] initWithView:_viewController.view];
|
|
164
|
+
[_tvRemoteHandler disableTVMenuKey];
|
|
165
|
+
|
|
166
|
+
[_viewController.view addGestureRecognizer:_menuButtonGestureRecognizer];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
- (void)disableEventHandlers
|
|
170
|
+
{
|
|
171
|
+
_tvRemoteHandler = nil;
|
|
172
|
+
[_viewController.view removeGestureRecognizer:_menuButtonGestureRecognizer];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
#endif
|
|
176
|
+
|
|
132
177
|
- (RCTFabricModalHostViewController *)viewController
|
|
133
178
|
{
|
|
134
179
|
if (!_viewController) {
|
|
@@ -7,19 +7,22 @@
|
|
|
7
7
|
|
|
8
8
|
#import "RCTRootComponentView.h"
|
|
9
9
|
|
|
10
|
+
#import <React/RCTRootView.h>
|
|
10
11
|
#import <react/renderer/components/root/RootComponentDescriptor.h>
|
|
11
12
|
#import <react/renderer/components/root/RootProps.h>
|
|
12
13
|
#import "RCTConversions.h"
|
|
13
14
|
|
|
14
15
|
using namespace facebook::react;
|
|
15
16
|
|
|
16
|
-
@implementation RCTRootComponentView
|
|
17
|
+
@implementation RCTRootComponentView {
|
|
18
|
+
BOOL _contentHasAppeared;
|
|
19
|
+
}
|
|
17
20
|
|
|
18
21
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
19
22
|
{
|
|
20
23
|
if (self = [super initWithFrame:frame]) {
|
|
21
24
|
_props = RootShadowNode::defaultSharedProps();
|
|
22
|
-
|
|
25
|
+
_contentHasAppeared = NO;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
return self;
|
|
@@ -48,6 +51,23 @@ using namespace facebook::react;
|
|
|
48
51
|
|
|
49
52
|
#pragma mark - RCTComponentViewProtocol
|
|
50
53
|
|
|
54
|
+
- (void)prepareForRecycle
|
|
55
|
+
{
|
|
56
|
+
[super prepareForRecycle];
|
|
57
|
+
_contentHasAppeared = NO;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
61
|
+
{
|
|
62
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
63
|
+
if (!self->_contentHasAppeared) {
|
|
64
|
+
self->_contentHasAppeared = YES;
|
|
65
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
66
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:RCTContentDidAppearNotification object:self];
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
51
71
|
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
52
72
|
{
|
|
53
73
|
return concreteComponentDescriptorProvider<RootComponentDescriptor>();
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
#import <React/RCTBridge+Private.h>
|
|
12
12
|
#import <React/RCTConstants.h>
|
|
13
13
|
#import <React/RCTScrollEvent.h>
|
|
14
|
-
#import <React/RCTTVNavigationEventNotification.h>
|
|
15
14
|
|
|
16
15
|
#import <react/renderer/components/scrollview/RCTComponentViewHelpers.h>
|
|
17
16
|
#import <react/renderer/components/scrollview/ScrollViewComponentDescriptor.h>
|
|
@@ -26,7 +25,8 @@
|
|
|
26
25
|
#import "RCTFabricComponentsPlugins.h"
|
|
27
26
|
|
|
28
27
|
#if TARGET_OS_TV
|
|
29
|
-
#import
|
|
28
|
+
#import <React/RCTTVRemoteHandler.h>
|
|
29
|
+
#import <React/RCTTVNavigationEventNotification.h>
|
|
30
30
|
#endif
|
|
31
31
|
|
|
32
32
|
using namespace facebook::react;
|
|
@@ -437,6 +437,11 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
|
|
|
437
437
|
|
|
438
438
|
- (void)prepareForRecycle
|
|
439
439
|
{
|
|
440
|
+
[super prepareForRecycle];
|
|
441
|
+
// Must invalidate state before setting contentOffset on ScrollView.
|
|
442
|
+
// Otherwise the state will be propagated to shadow tree.
|
|
443
|
+
_state.reset();
|
|
444
|
+
|
|
440
445
|
const auto &props = static_cast<const ScrollViewProps &>(*_props);
|
|
441
446
|
_scrollView.contentOffset = RCTCGPointFromPoint(props.contentOffset);
|
|
442
447
|
// We set the default behavior to "never" so that iOS
|
|
@@ -444,7 +449,6 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
|
|
|
444
449
|
// and keeps it as an opt-in behavior.
|
|
445
450
|
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
446
451
|
_shouldUpdateContentInsetAdjustmentBehavior = YES;
|
|
447
|
-
_state.reset();
|
|
448
452
|
_isUserTriggeredScrolling = NO;
|
|
449
453
|
CGRect oldFrame = self.frame;
|
|
450
454
|
self.frame = CGRectZero;
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
#import <React/RCTLog.h>
|
|
20
20
|
|
|
21
21
|
#import <React/RCTSurfaceHostingProxyRootView.h>
|
|
22
|
+
#if TARGET_OS_TV
|
|
22
23
|
#import <React/RCTTVNavigationEventNotification.h>
|
|
24
|
+
#endif
|
|
23
25
|
|
|
24
26
|
#import <react/renderer/components/view/ViewComponentDescriptor.h>
|
|
25
27
|
#import <react/renderer/components/view/ViewEventEmitter.h>
|
|
@@ -30,6 +30,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
30
30
|
|
|
31
31
|
- (void)schedulerDidFinishTransaction:(facebook::react::MountingCoordinator::Shared)mountingCoordinator;
|
|
32
32
|
|
|
33
|
+
- (void)schedulerShouldRenderTransactions:(facebook::react::MountingCoordinator::Shared)mountingCoordinator;
|
|
34
|
+
|
|
33
35
|
- (void)schedulerDidDispatchCommand:(const facebook::react::ShadowView &)shadowView
|
|
34
36
|
commandName:(const std::string &)commandName
|
|
35
37
|
args:(const folly::dynamic &)args;
|
|
@@ -30,6 +30,12 @@ class SchedulerDelegateProxy : public SchedulerDelegate {
|
|
|
30
30
|
[scheduler.delegate schedulerDidFinishTransaction:mountingCoordinator];
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
void schedulerShouldRenderTransactions(const MountingCoordinator::Shared &mountingCoordinator) override
|
|
34
|
+
{
|
|
35
|
+
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
|
|
36
|
+
[scheduler.delegate schedulerShouldRenderTransactions:mountingCoordinator];
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
void schedulerDidRequestPreliminaryViewAllocation(SurfaceId surfaceId, const ShadowNode &shadowNode) override
|
|
34
40
|
{
|
|
35
41
|
// Does nothing.
|