From e107ed0a89c709d09377be41a97112597583054e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 26 Feb 2024 12:13:58 +0100 Subject: [PATCH] feat: add multi-window support (#117) * feat: add multi-window support * feat: introduce WindowManager fix: RCTReactViewController properly check props to update fix: use clearColor instead of systemBackgroundColor for visionOS (#125) --- .../Libraries/AppDelegate/RCTAppDelegate.h | 4 +- .../Libraries/AppDelegate/RCTAppDelegate.mm | 4 + .../AppDelegate/RCTRootViewFactory.mm | 8 + .../SwiftExtensions/RCTMainWindow.swift | 53 ++- .../SwiftExtensions/RCTReactContext.swift | 45 ++ .../SwiftExtensions/RCTReactViewController.h | 2 + .../RCTRootViewRepresentable.swift | 6 +- .../Libraries/SwiftExtensions/RCTWindow.swift | 45 ++ .../React-RCTSwiftExtensions.podspec | 1 + .../WindowManager/NativeWindowManager.js | 8 + .../WindowManager/RCTWindowManager.h | 6 + .../WindowManager/RCTWindowManager.mm | 90 ++++ .../WindowManager/WindowManager.d.ts | 16 + .../Libraries/WindowManager/WindowManager.js | 63 +++ .../Libraries/XR/ImmersiveBridge.swift | 8 +- .../react-native/Libraries/XR/RCTXRModule.mm | 63 +-- packages/react-native/Libraries/XR/XR.d.ts | 3 +- packages/react-native/Libraries/XR/XR.js | 14 +- .../__snapshots__/public-api-test.js.snap | 26 +- packages/react-native/React-Core.podspec | 1 + packages/react-native/React.podspec | 1 + packages/react-native/React/Base/RCTUtils.m | 12 +- packages/react-native/index.js | 4 + .../react-native/scripts/react_native_pods.rb | 1 + .../visionos_modules/NativeWindowManager.js | 24 ++ .../specs/visionos_modules/NativeXRModule.js | 9 +- packages/react-native/types/index.d.ts | 1 + packages/rn-tester/Podfile.lock | 388 +++++++++++++----- .../rn-tester/RNTester-visionOS/App.swift | 8 +- packages/rn-tester/js/RNTesterApp.ios.js | 3 + .../js/examples/SecondWindow/SecondWindow.js | 52 +++ .../rn-tester/js/examples/XR/XRExample.js | 28 +- 32 files changed, 835 insertions(+), 162 deletions(-) create mode 100644 packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift create mode 100644 packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift create mode 100644 packages/react-native/Libraries/WindowManager/NativeWindowManager.js create mode 100644 packages/react-native/Libraries/WindowManager/RCTWindowManager.h create mode 100644 packages/react-native/Libraries/WindowManager/RCTWindowManager.mm create mode 100644 packages/react-native/Libraries/WindowManager/WindowManager.d.ts create mode 100644 packages/react-native/Libraries/WindowManager/WindowManager.js create mode 100644 packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js create mode 100644 packages/rn-tester/js/examples/SecondWindow/SecondWindow.js diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h index 51ce13d8321922..d3ecacac5754dd 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h @@ -59,7 +59,9 @@ NS_ASSUME_NONNULL_BEGIN /// The window object, used to render the UViewControllers @property (nonatomic, strong, nonnull) UIWindow *window; -@property (nonatomic, nullable) RCTBridge *bridge; +/// Store last focused window to properly handle multi-window scenarios +@property (nonatomic, weak, nullable) UIWindow *lastFocusedWindow; +@property (nonatomic, strong, nullable) RCTBridge *bridge; @property (nonatomic, strong, nullable) NSString *moduleName; @property (nonatomic, strong, nullable) NSDictionary *initialProps; @property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory; diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm index c0f0a926126d0f..933410db53919b 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm @@ -87,7 +87,11 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge BOOL enableFabric = self.fabricEnabled; UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric); +#if TARGET_OS_VISION + rootView.backgroundColor = [UIColor clearColor]; +#else rootView.backgroundColor = [UIColor systemBackgroundColor]; +#endif return rootView; } diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index 377e5efeae8030..05c1baa804abc8 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -149,7 +149,11 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName initWithSurface:surface sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact]; +#if TARGET_OS_VISION + surfaceHostingProxyRootView.backgroundColor = [UIColor clearColor]; +#else surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor]; +#endif if (self->_configuration.customizeRootView != nil) { self->_configuration.customizeRootView(surfaceHostingProxyRootView); } @@ -183,7 +187,11 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge BOOL enableFabric = self->_configuration.fabricEnabled; UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric); +#if TARGET_OS_VISION + rootView.backgroundColor = [UIColor clearColor]; +#else rootView.backgroundColor = [UIColor systemBackgroundColor]; +#endif return rootView; } diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift index 1bf0bca5901b63..bbf3a3c203252e 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift +++ b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift @@ -15,8 +15,8 @@ import SwiftUI } ``` - Note: If you want to create additional windows in your app, create a new `WindowGroup {}` and pass it a `RCTRootViewRepresentable`. -*/ + Note: If you want to create additional windows in your app, use `RCTWindow()`. + */ public struct RCTMainWindow: Scene { var moduleName: String var initialProps: RCTRootViewRepresentable.InitialPropsType @@ -29,6 +29,55 @@ public struct RCTMainWindow: Scene { public var body: some Scene { WindowGroup { RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps) + .modifier(WindowHandlingModifier()) + } + } +} + +/** + Handles data sharing between React Native and SwiftUI views. + */ +struct WindowHandlingModifier: ViewModifier { + typealias UserInfoType = Dictionary + + @Environment(\.reactContext) private var reactContext + @Environment(\.openWindow) private var openWindow + @Environment(\.dismissWindow) private var dismissWindow + @Environment(\.supportsMultipleWindows) private var supportsMultipleWindows + + func body(content: Content) -> some View { + // Attach listeners only if app supports multiple windows + if supportsMultipleWindows { + content + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTOpenWindow"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + reactContext.scenes.updateValue(RCTSceneData(id: id, props: data.userInfo?["userInfo"] as? UserInfoType), forKey: id) + openWindow(id: id) + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTUpdateWindow"))) { data in + guard + let id = data.userInfo?["id"] as? String, + let userInfo = data.userInfo?["userInfo"] as? UserInfoType else { return } + reactContext.scenes[id]?.props = userInfo + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTDismissWindow"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + dismissWindow(id: id) + reactContext.scenes.removeValue(forKey: id) + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTOpenImmersiveSpace"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + reactContext.scenes.updateValue( + RCTSceneData(id: id, props: data.userInfo?["userInfo"] as? UserInfoType), + forKey: id + ) + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTDismissImmersiveSpace"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + reactContext.scenes.removeValue(forKey: id) + } + } else { + content } } } diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift b/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift new file mode 100644 index 00000000000000..4f5c3b3738b0e7 --- /dev/null +++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift @@ -0,0 +1,45 @@ +import SwiftUI +import Observation + +@Observable +public class RCTSceneData: Identifiable { + public var id: String + public var props: Dictionary? + + init(id: String, props: Dictionary?) { + self.id = id + self.props = props + } +} + +extension RCTSceneData: Equatable { + public static func == (lhs: RCTSceneData, rhs: RCTSceneData) -> Bool { + lhs.id == rhs.id && NSDictionary(dictionary: lhs.props ?? [:]).isEqual(to: rhs.props ?? [:]) + } +} + +@Observable +public class RCTReactContext { + public var scenes: Dictionary = [:] + + public func getSceneData(id: String) -> RCTSceneData? { + return scenes[id] + } +} + +extension RCTReactContext: Equatable { + public static func == (lhs: RCTReactContext, rhs: RCTReactContext) -> Bool { + NSDictionary(dictionary: lhs.scenes).isEqual(to: rhs.scenes) + } +} + +public extension EnvironmentValues { + var reactContext: RCTReactContext { + get { self[RCTSceneContextKey.self] } + set { self[RCTSceneContextKey.self] = newValue } + } +} + +private struct RCTSceneContextKey: EnvironmentKey { + static var defaultValue: RCTReactContext = RCTReactContext() +} diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h index 13de19c37cf0e2..aa77150ce21c92 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h +++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h @@ -13,4 +13,6 @@ - (instancetype _Nonnull)initWithModuleName:(NSString *_Nonnull)moduleName initProps:(NSDictionary *_Nullable)initProps; +-(void)updateProps:(NSDictionary *_Nullable)newProps; + @end diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift index 6a89db9d08e2d7..8a839541ebb8ea 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift +++ b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift @@ -22,11 +22,11 @@ public struct RCTRootViewRepresentable: UIViewControllerRepresentable { self.initialProps = initialProps } - public func makeUIViewController(context: Context) -> UIViewController { + public func makeUIViewController(context: Context) -> RCTReactViewController { RCTReactViewController(moduleName: moduleName, initProps: initialProps) } - public func updateUIViewController(_ uiViewController: UIViewController, context: Context) { - // noop + public func updateUIViewController(_ uiViewController: RCTReactViewController, context: Context) { + uiViewController.updateProps(initialProps) } } diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift new file mode 100644 index 00000000000000..12bb37085cd1dd --- /dev/null +++ b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift @@ -0,0 +1,45 @@ +import SwiftUI +import React + +/** + `RCTWindow` is a SwiftUI struct that returns additional scenes. + + Example usage: + ``` + RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow")) + ``` + */ +public struct RCTWindow : Scene { + var id: String + var sceneData: RCTSceneData? + var moduleName: String + + public init(id: String, moduleName: String, sceneData: RCTSceneData?) { + self.id = id + self.moduleName = moduleName + self.sceneData = sceneData + } + + public var body: some Scene { + WindowGroup(id: id) { + Group { + if let sceneData { + RCTRootViewRepresentable(moduleName: moduleName, initialProps: sceneData.props) + } + } + .onAppear { + if sceneData == nil { + RCTFatal(RCTErrorWithMessage("Passed scene data is nil, make sure to pass sceneContext to RCTWindow() in App.swift")) + } + } + } + } +} + +extension RCTWindow { + public init(id: String, sceneData: RCTSceneData?) { + self.id = id + self.moduleName = id + self.sceneData = sceneData + } +} diff --git a/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec index 531f1d8172ca7d..9d61b8e4cf31c3 100644 --- a/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec +++ b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec @@ -25,4 +25,5 @@ Pod::Spec.new do |s| s.dependency "React-Core" s.dependency "React-RCTXR" + s.dependency "React-RCTWindowManager" end diff --git a/packages/react-native/Libraries/WindowManager/NativeWindowManager.js b/packages/react-native/Libraries/WindowManager/NativeWindowManager.js new file mode 100644 index 00000000000000..a1904df0228866 --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/NativeWindowManager.js @@ -0,0 +1,8 @@ +/** + * @flow strict + * @format + */ + +export * from '../../src/private/specs/visionos_modules/NativeWindowManager'; +import NativeWindowManager from '../../src/private/specs/visionos_modules/NativeWindowManager'; +export default NativeWindowManager; diff --git a/packages/react-native/Libraries/WindowManager/RCTWindowManager.h b/packages/react-native/Libraries/WindowManager/RCTWindowManager.h new file mode 100644 index 00000000000000..8d782b1bfe77e7 --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/RCTWindowManager.h @@ -0,0 +1,6 @@ +#import +#import + +@interface RCTWindowManager : NSObject + +@end diff --git a/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm b/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm new file mode 100644 index 00000000000000..3700bceba20b95 --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm @@ -0,0 +1,90 @@ +#import + +#import + +#import +#import +#import + +// Events +static NSString *const RCTOpenWindow = @"RCTOpenWindow"; +static NSString *const RCTDismissWindow = @"RCTDismissWindow"; +static NSString *const RCTUpdateWindow = @"RCTUpdateWindow"; + +@interface RCTWindowManager () +@end + +@implementation RCTWindowManager + +RCT_EXPORT_MODULE(WindowManager) + +RCT_EXPORT_METHOD(openWindow + : (NSString *)windowId userInfo + : (NSDictionary *)userInfo resolve + : (RCTPromiseResolveBlock)resolve reject + : (RCTPromiseRejectBlock)reject) +{ + RCTExecuteOnMainQueue(^{ + if (!RCTSharedApplication().supportsMultipleScenes) { + reject(@"ERROR", @"Multiple scenes not supported", nil); + } + NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init]; + [userInfoDict setValue:windowId forKey:@"id"]; + if (userInfo != nil) { + [userInfoDict setValue:userInfo forKey:@"userInfo"]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenWindow object:self userInfo:userInfoDict]; + resolve(nil); + }); +} + +RCT_EXPORT_METHOD(closeWindow + : (NSString *)windowId resolve + : (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) +{ + RCTExecuteOnMainQueue(^{ + [[NSNotificationCenter defaultCenter] postNotificationName:RCTDismissWindow object:self userInfo:@{@"id": windowId}]; + resolve(nil); + }); +} + +RCT_EXPORT_METHOD(updateWindow + : (NSString *)windowId userInfo + : (NSDictionary *)userInfo resolve + : (RCTPromiseResolveBlock)resolve reject + : (RCTPromiseRejectBlock)reject) +{ + RCTExecuteOnMainQueue(^{ + if (!RCTSharedApplication().supportsMultipleScenes) { + reject(@"ERROR", @"Multiple scenes not supported", nil); + } + NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init]; + [userInfoDict setValue:windowId forKey:@"id"]; + if (userInfo != nil) { + [userInfoDict setValue:userInfo forKey:@"userInfo"]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:RCTUpdateWindow object:self userInfo:userInfoDict]; + resolve(nil); + }); +} + +- (facebook::react::ModuleConstants)constantsToExport { + return [self getConstants]; +} + +- (facebook::react::ModuleConstants)getConstants { + __block facebook::react::ModuleConstants constants; + RCTUnsafeExecuteOnMainQueueSync(^{ + constants = facebook::react::typedConstants({ + .supportsMultipleScenes = RCTSharedApplication().supportsMultipleScenes + }); + }); + + return constants; +} + +- (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { + return std::make_shared(params); +} + +@end diff --git a/packages/react-native/Libraries/WindowManager/WindowManager.d.ts b/packages/react-native/Libraries/WindowManager/WindowManager.d.ts new file mode 100644 index 00000000000000..bcdf96c272c21c --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/WindowManager.d.ts @@ -0,0 +1,16 @@ +export interface WindowStatic { + id: String; + open (props?: Object): Promise; + update (props: Object): Promise; + close (): Promise; +} + +export interface WindowManagerStatic { + getWindow(id: String): Window; + supportsMultipleScenes: boolean; +} + +export const WindowManager: WindowManagerStatic; +export type WindowManager = WindowManagerStatic; +export const Window: WindowStatic; +export type Window = WindowStatic; diff --git a/packages/react-native/Libraries/WindowManager/WindowManager.js b/packages/react-native/Libraries/WindowManager/WindowManager.js new file mode 100644 index 00000000000000..bb39535a65bb1a --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/WindowManager.js @@ -0,0 +1,63 @@ +/** + * @format + * @flow strict + * @jsdoc + */ + +import NativeWindowManager from './NativeWindowManager'; + +const WindowManager = { + getWindow: function (id: string): Window { + return new Window(id); + }, + + // $FlowIgnore[unsafe-getters-setters] + get supportsMultipleScenes(): boolean { + if (NativeWindowManager == null) { + return false; + } + + const nativeConstants = NativeWindowManager.getConstants(); + return nativeConstants.supportsMultipleScenes || false; + }, +}; + +class Window { + id: string; + + constructor(id: string) { + this.id = id; + } + + // $FlowIgnore[unclear-type] + open(props: ?Object): Promise { + if (NativeWindowManager != null && NativeWindowManager.openWindow != null) { + return NativeWindowManager.openWindow(this.id, props); + } + return Promise.reject(new Error('NativeWindowManager is not available')); + } + + // $FlowIgnore[unclear-type] + close(): Promise { + if ( + NativeWindowManager != null && + NativeWindowManager.closeWindow != null + ) { + return NativeWindowManager.closeWindow(this.id); + } + return Promise.reject(new Error('NativeWindowManager is not available')); + } + + // $FlowIgnore[unclear-type] + update(props: ?Object): Promise { + if ( + NativeWindowManager != null && + NativeWindowManager.updateWindow != null + ) { + return NativeWindowManager.updateWindow(this.id, props); + } + return Promise.reject(new Error('NativeWindowManager is not available')); + } +} + +module.exports = WindowManager; diff --git a/packages/react-native/Libraries/XR/ImmersiveBridge.swift b/packages/react-native/Libraries/XR/ImmersiveBridge.swift index 45fdbcf4087b00..43bdfe5b170739 100644 --- a/packages/react-native/Libraries/XR/ImmersiveBridge.swift +++ b/packages/react-native/Libraries/XR/ImmersiveBridge.swift @@ -9,6 +9,7 @@ import SwiftUI public typealias CompletionHandlerType = (_ result: ImmersiveSpaceResult) -> Void +#if os(visionOS) /** * Utility view used to bridge the gap between SwiftUI environment and UIKit. * @@ -44,12 +45,17 @@ struct ImmersiveBridgeView: View { } } } +#endif -@objc public class ImmersiveBridgeFactory: NSObject { +@objc public class SwiftUIBridgeFactory: NSObject { @objc public static func makeImmersiveBridgeView( spaceId: String, completionHandler: @escaping CompletionHandlerType ) -> UIViewController { +#if os(visionOS) return UIHostingController(rootView: ImmersiveBridgeView(spaceId: spaceId, completionHandler: completionHandler)) +#else + return UIViewController() +#endif } } diff --git a/packages/react-native/Libraries/XR/RCTXRModule.mm b/packages/react-native/Libraries/XR/RCTXRModule.mm index 8b5db6c7cbd008..f0c600b3a09c99 100644 --- a/packages/react-native/Libraries/XR/RCTXRModule.mm +++ b/packages/react-native/Libraries/XR/RCTXRModule.mm @@ -7,11 +7,16 @@ #import #import "RCTXR-Swift.h" +// Events +static NSString *const RCTOpenImmersiveSpace = @"RCTOpenImmersiveSpace"; +static NSString *const RCTDismissImmersiveSpace = @"RCTDismissImmersiveSpace"; + @interface RCTXRModule () @end @implementation RCTXRModule { UIViewController *_immersiveBridgeView; + NSString *_currentSessionId; } RCT_EXPORT_MODULE() @@ -20,28 +25,51 @@ @implementation RCTXRModule { : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) { - [self removeImmersiveBridge]; + [self removeViewController:self->_immersiveBridgeView]; + self->_immersiveBridgeView = nil; + RCTExecuteOnMainQueue(^{ + if (self->_currentSessionId != nil) { + [[NSNotificationCenter defaultCenter] postNotificationName:RCTDismissImmersiveSpace object:self userInfo:@{@"id": self->_currentSessionId}]; + } + }); + _currentSessionId = nil; resolve(nil); } RCT_EXPORT_METHOD(requestSession - : (NSString *)sessionId resolve - : (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) + : (NSString *)sessionId userInfo + : (NSDictionary *)userInfo resolve + : (RCTPromiseResolveBlock)resolve reject + : (RCTPromiseRejectBlock)reject) { RCTExecuteOnMainQueue(^{ + if (!RCTSharedApplication().supportsMultipleScenes) { + reject(@"ERROR", @"Multiple scenes not supported", nil); + } UIWindow *keyWindow = RCTKeyWindow(); UIViewController *rootViewController = keyWindow.rootViewController; if (self->_immersiveBridgeView == nil) { - self->_immersiveBridgeView = [ImmersiveBridgeFactory makeImmersiveBridgeViewWithSpaceId:sessionId + NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init]; + [userInfoDict setValue:sessionId forKey:@"id"]; + if (userInfo != nil) { + [userInfoDict setValue:userInfo forKey:@"userInfo"]; + } + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:RCTOpenImmersiveSpace object:self userInfo:userInfoDict]; + self->_currentSessionId = sessionId; + + self->_immersiveBridgeView = [SwiftUIBridgeFactory makeImmersiveBridgeViewWithSpaceId:sessionId completionHandler:^(enum ImmersiveSpaceResult result){ if (result == ImmersiveSpaceResultError) { reject(@"ERROR", @"Immersive Space failed to open, the system cannot fulfill the request.", nil); - [self removeImmersiveBridge]; + [self removeViewController:self->_immersiveBridgeView]; + self->_immersiveBridgeView = nil; } else if (result == ImmersiveSpaceResultUserCancelled) { reject(@"ERROR", @"Immersive Space canceled by user", nil); - [self removeImmersiveBridge]; + [self removeViewController:self->_immersiveBridgeView]; + self->_immersiveBridgeView = nil; } else if (result == ImmersiveSpaceResultOpened) { resolve(nil); } @@ -56,28 +84,13 @@ @implementation RCTXRModule { }); } -- (facebook::react::ModuleConstants)constantsToExport { - return [self getConstants]; -} - -- (facebook::react::ModuleConstants)getConstants { - __block facebook::react::ModuleConstants constants; - RCTUnsafeExecuteOnMainQueueSync(^{ - constants = facebook::react::typedConstants({ - .supportsMultipleScenes = RCTSharedApplication().supportsMultipleScenes - }); - }); - - return constants; -} -- (void) removeImmersiveBridge +- (void)removeViewController:(UIViewController*)viewController { RCTExecuteOnMainQueue(^{ - [self->_immersiveBridgeView willMoveToParentViewController:nil]; - [self->_immersiveBridgeView.view removeFromSuperview]; - [self->_immersiveBridgeView removeFromParentViewController]; - self->_immersiveBridgeView = nil; + [viewController willMoveToParentViewController:nil]; + [viewController.view removeFromSuperview]; + [viewController removeFromParentViewController]; }); } diff --git a/packages/react-native/Libraries/XR/XR.d.ts b/packages/react-native/Libraries/XR/XR.d.ts index 11d397a4ebde34..293a97bb084c3e 100644 --- a/packages/react-native/Libraries/XR/XR.d.ts +++ b/packages/react-native/Libraries/XR/XR.d.ts @@ -1,8 +1,7 @@ export interface XRStatic { - requestSession(sessionId: string): Promise; + requestSession(sessionId: string, userInfo: Object): Promise; endSession(): Promise; - supportsMultipleScenes: boolean; } export const XR: XRStatic; diff --git a/packages/react-native/Libraries/XR/XR.js b/packages/react-native/Libraries/XR/XR.js index 3487429aff1bb5..923a3184c71dea 100644 --- a/packages/react-native/Libraries/XR/XR.js +++ b/packages/react-native/Libraries/XR/XR.js @@ -7,9 +7,10 @@ import NativeXRModule from './NativeXRModule'; const XR = { - requestSession: (sessionId?: string): Promise => { + // $FlowIgnore[unclear-type] + requestSession: (sessionId: string, userInfo: ?Object): Promise => { if (NativeXRModule != null && NativeXRModule.requestSession != null) { - return NativeXRModule.requestSession(sessionId); + return NativeXRModule.requestSession(sessionId, userInfo); } return Promise.reject(new Error('NativeXRModule is not available')); }, @@ -19,15 +20,6 @@ const XR = { } return Promise.reject(new Error('NativeXRModule is not available')); }, - // $FlowIgnore[unsafe-getters-setters] - get supportsMultipleScenes(): boolean { - if (NativeXRModule == null) { - return false; - } - - const nativeConstants = NativeXRModule.getConstants(); - return nativeConstants.supportsMultipleScenes || false; - }, }; module.exports = XR; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 3509cc2bdd807a..cc819092becf78 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -9085,6 +9085,28 @@ exports[`public API should not change unintentionally Libraries/WebSocket/WebSoc exports[`public API should not change unintentionally Libraries/WebSocket/WebSocketInterceptor.js 1`] = `"UNTYPED MODULE"`; +exports[`public API should not change unintentionally Libraries/WindowManager/NativeWindowManager.js 1`] = ` +"export * from \\"../../src/private/specs/visionos_modules/NativeWindowManager\\"; +declare export default typeof NativeWindowManager; +" +`; + +exports[`public API should not change unintentionally Libraries/WindowManager/WindowManager.js 1`] = ` +"declare const WindowManager: { + getWindow: (id: string) => Window, + get supportsMultipleScenes(): boolean, +}; +declare class Window { + id: string; + constructor(id: string): void; + open(props: ?Object): Promise; + close(): Promise; + update(props: ?Object): Promise; +} +declare module.exports: WindowManager; +" +`; + exports[`public API should not change unintentionally Libraries/XR/NativeXRModule.js 1`] = ` "export * from \\"../../src/private/specs/visionos_modules/NativeXRModule\\"; declare export default typeof NativeXRModule; @@ -9093,9 +9115,8 @@ declare export default typeof NativeXRModule; exports[`public API should not change unintentionally Libraries/XR/XR.js 1`] = ` "declare const XR: { - requestSession: (sessionId?: string) => Promise, + requestSession: (sessionId: string, userInfo: ?Object) => Promise, endSession: () => Promise, - get supportsMultipleScenes(): boolean, }; declare module.exports: XR; " @@ -9220,6 +9241,7 @@ declare module.exports: { get Settings(): Settings, get Share(): Share, get XR(): XR, + get WindowManager(): WindowManager, get StyleSheet(): StyleSheet, get Systrace(): Systrace, get ToastAndroid(): ToastAndroid, diff --git a/packages/react-native/React-Core.podspec b/packages/react-native/React-Core.podspec index 159d41e3a24a11..bdb8138dd1f4a4 100644 --- a/packages/react-native/React-Core.podspec +++ b/packages/react-native/React-Core.podspec @@ -38,6 +38,7 @@ header_subspecs = { 'RCTTextHeaders' => 'Libraries/Text/**/*.h', 'RCTVibrationHeaders' => 'Libraries/Vibration/*.h', 'RCTXRHeaders' => 'Libraries/XR/*.h', + 'RCTWindowManagerHeaders' => 'Libraries/WindowManager/*.h', } frameworks_search_paths = [] diff --git a/packages/react-native/React.podspec b/packages/react-native/React.podspec index 2d085e63040906..50397b11182021 100644 --- a/packages/react-native/React.podspec +++ b/packages/react-native/React.podspec @@ -54,4 +54,5 @@ Pod::Spec.new do |s| s.dependency "React-RCTText", version s.dependency "React-RCTVibration", version s.dependency "React-RCTXR", version + s.dependency "React-RCTWindowManager", version end diff --git a/packages/react-native/React/Base/RCTUtils.m b/packages/react-native/React/Base/RCTUtils.m index 1573a675f23a6b..5f1e13390b37c7 100644 --- a/packages/react-native/React/Base/RCTUtils.m +++ b/packages/react-native/React/Base/RCTUtils.m @@ -566,7 +566,17 @@ BOOL RCTRunningInAppExtension(void) if (RCTRunningInAppExtension()) { return nil; } - + + id delegate = RCTSharedApplication().delegate; + + SEL lastFocusedWindowSelector = NSSelectorFromString(@"lastFocusedWindow"); + if ([delegate respondsToSelector:lastFocusedWindowSelector]) { + UIWindow *lastFocusedWindow = [delegate performSelector:lastFocusedWindowSelector]; + if (lastFocusedWindow) { + return lastFocusedWindow; + } + } + NSSet *connectedScenes = RCTSharedApplication().connectedScenes; UIScene *foregroundActiveScene; diff --git a/packages/react-native/index.js b/packages/react-native/index.js index 555cf263a3019a..02b5377f43ed11 100644 --- a/packages/react-native/index.js +++ b/packages/react-native/index.js @@ -90,6 +90,7 @@ import typeof Platform from './Libraries/Utilities/Platform'; import typeof useColorScheme from './Libraries/Utilities/useColorScheme'; import typeof useWindowDimensions from './Libraries/Utilities/useWindowDimensions'; import typeof Vibration from './Libraries/Vibration/Vibration'; +import typeof WindowManager from './Libraries/WindowManager/WindowManager'; import typeof XR from './Libraries/XR/XR'; import typeof YellowBox from './Libraries/YellowBox/YellowBoxDeprecated'; @@ -304,6 +305,9 @@ module.exports = { get XR(): XR { return require('./Libraries/XR/XR'); }, + get WindowManager(): WindowManager { + return require('./Libraries/WindowManager/WindowManager'); + }, get StyleSheet(): StyleSheet { return require('./Libraries/StyleSheet/StyleSheet'); }, diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index 3c6f225570abbf..5c493778b214fd 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -135,6 +135,7 @@ def use_react_native! ( pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation" pod 'React-RCTSwiftExtensions', :path => "#{prefix}/Libraries/SwiftExtensions" pod 'React-RCTXR', :path => "#{prefix}/Libraries/XR" + pod 'React-RCTWindowManager', :path => "#{prefix}/Libraries/WindowManager", :modular_headers => true if hermes_enabled setup_hermes!(:react_native_path => prefix) diff --git a/packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js b/packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js new file mode 100644 index 00000000000000..db0332702236c4 --- /dev/null +++ b/packages/react-native/src/private/specs/visionos_modules/NativeWindowManager.js @@ -0,0 +1,24 @@ +/** + * @flow strict + * @format + */ + +import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport'; + +import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry'; + +export type WindowManagerConstants = {| + +supportsMultipleScenes?: boolean, +|}; + +export interface Spec extends TurboModule { + +getConstants: () => WindowManagerConstants; + + // $FlowIgnore[unclear-type] + +openWindow: (windowId: string, userInfo: Object) => Promise; + // $FlowIgnore[unclear-type] + +updateWindow: (windowId: string, userInfo: Object) => Promise; + +closeWindow: (windowId: string) => Promise; +} + +export default (TurboModuleRegistry.get('WindowManager'): ?Spec); diff --git a/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js b/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js index ce8d22dca68c49..f96c2a84a48ac4 100644 --- a/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js +++ b/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js @@ -7,14 +7,9 @@ import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport'; import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry'; -export type XRModuleConstants = {| - +supportsMultipleScenes?: boolean, -|}; - export interface Spec extends TurboModule { - +getConstants: () => XRModuleConstants; - - +requestSession: (sessionId?: string) => Promise; + // $FlowIgnore[unclear-type] + +requestSession: (sessionId?: string, userInfo: Object) => Promise; +endSession: () => Promise; } diff --git a/packages/react-native/types/index.d.ts b/packages/react-native/types/index.d.ts index 917b5cc65d098d..5c89c19b97c707 100644 --- a/packages/react-native/types/index.d.ts +++ b/packages/react-native/types/index.d.ts @@ -148,6 +148,7 @@ export * from '../Libraries/Utilities/PixelRatio'; export * from '../Libraries/Utilities/Platform'; export * from '../Libraries/Vibration/Vibration'; export * from '../Libraries/XR/XR'; +export * from '../Libraries/WindowManager/WindowManager'; export * from '../Libraries/YellowBox/YellowBoxDeprecated'; export * from '../Libraries/vendor/core/ErrorUtils'; export { diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 349b8a6ae3729d..ac90aa410852e7 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -5,51 +5,55 @@ PODS: - fmt (9.1.0) - glog (0.3.5) - hermes-engine (1000.0.0): + - hermes-engine/cdp (= 1000.0.0) - hermes-engine/Hermes (= 1000.0.0) - hermes-engine/inspector (= 1000.0.0) - hermes-engine/inspector_chrome (= 1000.0.0) - hermes-engine/Public (= 1000.0.0) + - hermes-engine/cdp (1000.0.0) - hermes-engine/Hermes (1000.0.0) - hermes-engine/inspector (1000.0.0) - hermes-engine/inspector_chrome (1000.0.0) - hermes-engine/Public (1000.0.0) - - MyNativeView (0.0.1): + - MyNativeView (0.75.0-main): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety - - React-Codegen - React-Core - React-debug - React-Fabric + - React-featureflags - React-graphics - React-ImageManager - React-NativeModulesApple - React-RCTFabric - React-rendererdebug - React-utils + - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - NativeCxxModuleExample (0.0.1): + - NativeCxxModuleExample (0.75.0-main): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety - - React-Codegen - React-Core - React-debug - React-Fabric + - React-featureflags - React-graphics - React-ImageManager - React-NativeModulesApple - React-RCTFabric - React-rendererdebug - React-utils + - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga @@ -89,27 +93,9 @@ PODS: - React-RCTSettings (= 1000.0.0) - React-RCTText (= 1000.0.0) - React-RCTVibration (= 1000.0.0) + - React-RCTWindowManager (= 1000.0.0) - React-RCTXR (= 1000.0.0) - React-callinvoker (1000.0.0) - - React-Codegen (1000.0.0): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly - - RCTRequired - - RCTTypeSafety - - React-Core - - React-debug - - React-Fabric - - React-FabricImage - - React-graphics - - React-jsi - - React-jsiexecutor - - React-NativeModulesApple - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - React-Core (1000.0.0): - glog - hermes-engine @@ -117,9 +103,11 @@ PODS: - RCTDeprecation - React-Core/Default (= 1000.0.0) - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -132,9 +120,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -146,10 +136,11 @@ PODS: - RCT-Folly (= 2024.01.01.00) - RCTDeprecation - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -163,10 +154,11 @@ PODS: - React-Core/Default (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -179,9 +171,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -194,9 +188,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -209,9 +205,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -224,9 +222,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -239,9 +239,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -254,9 +256,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -269,9 +273,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -284,9 +290,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -299,9 +307,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -314,9 +324,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -329,9 +341,28 @@ PODS: - RCTDeprecation - React-Core/Default (= 1000.0.0) - React-cxxreact + - React-featureflags + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector + - React-perflogger + - React-runtimescheduler + - React-utils + - SocketRocket (= 0.7.0.1) + - Yoga + - React-Core/RCTWindowManagerHeaders (1000.0.0): + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTDeprecation + - React-Core/Default + - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -344,23 +375,28 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils - SocketRocket (= 0.7.0.1) - Yoga - React-CoreModules (1000.0.0): + - DoubleConversion + - fmt (= 9.1.0) - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety (= 1000.0.0) - - React-Codegen - React-Core/CoreModulesHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) + - React-jsinspector - React-NativeModulesApple - React-RCTBlob - React-RCTImage (= 1000.0.0) + - ReactCodegen - ReactCommon - SocketRocket (= 0.7.0.1) - React-cxxreact (1000.0.0): @@ -373,7 +409,7 @@ PODS: - React-callinvoker (= 1000.0.0) - React-debug (= 1000.0.0) - React-jsi (= 1000.0.0) - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-logger (= 1000.0.0) - React-perflogger (= 1000.0.0) - React-runtimeexecutor (= 1000.0.0) @@ -428,6 +464,7 @@ PODS: - React-Fabric/templateprocessor (= 1000.0.0) - React-Fabric/textlayoutmanager (= 1000.0.0) - React-Fabric/uimanager (= 1000.0.0) + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -447,6 +484,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -466,6 +504,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -485,6 +524,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -504,6 +544,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -524,6 +565,7 @@ PODS: - React-cxxreact - React-debug - React-Fabric/components/inputaccessory (= 1000.0.0) + - React-Fabric/components/iostextinput (= 1000.0.0) - React-Fabric/components/legacyviewmanagerinterop (= 1000.0.0) - React-Fabric/components/modal (= 1000.0.0) - React-Fabric/components/rncore (= 1000.0.0) @@ -534,6 +576,7 @@ PODS: - React-Fabric/components/textinput (= 1000.0.0) - React-Fabric/components/unimplementedview (= 1000.0.0) - React-Fabric/components/view (= 1000.0.0) + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -553,6 +596,27 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags + - React-graphics + - React-jsi + - React-jsiexecutor + - React-logger + - React-rendererdebug + - React-runtimescheduler + - React-utils + - ReactCommon/turbomodule/core + - React-Fabric/components/iostextinput (1000.0.0): + - DoubleConversion + - fmt (= 9.1.0) + - glog + - hermes-engine + - RCT-Folly/Fabric (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-cxxreact + - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -572,6 +636,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -591,6 +656,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -610,6 +676,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -629,6 +696,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -648,6 +716,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -667,6 +736,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -686,6 +756,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -705,6 +776,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -724,6 +796,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -743,6 +816,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -763,6 +837,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -805,6 +880,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -824,6 +900,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -843,6 +920,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -862,6 +940,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -881,6 +960,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -900,6 +980,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -920,6 +1001,7 @@ PODS: - React-cxxreact - React-debug - React-Fabric/uimanager + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -991,10 +1073,35 @@ PODS: - React-utils - ReactCommon - Yoga + - React-featureflags (1000.0.0) + - React-featureflagsnativemodule (1000.0.0): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - React-graphics (1000.0.0): + - DoubleConversion + - fmt (= 9.1.0) - glog - RCT-Folly/Fabric (= 2024.01.01.00) - - React-Core/Default (= 1000.0.0) + - React-jsi + - React-jsiexecutor - React-utils - React-hermes (1000.0.0): - DoubleConversion @@ -1005,8 +1112,9 @@ PODS: - React-cxxreact (= 1000.0.0) - React-jsi - React-jsiexecutor (= 1000.0.0) - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-perflogger (= 1000.0.0) + - React-runtimeexecutor - React-ImageManager (1000.0.0): - glog - RCT-Folly/Fabric @@ -1035,12 +1143,16 @@ PODS: - RCT-Folly (= 2024.01.01.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) + - React-jsinspector - React-perflogger (= 1000.0.0) - React-jsinspector (1000.0.0): - DoubleConversion - glog + - hermes-engine - RCT-Folly (= 2024.01.01.00) - - React-nativeconfig + - React-featureflags + - React-jsi + - React-runtimeexecutor (= 1000.0.0) - React-jsitracing (1000.0.0): - React-jsi - React-logger (1000.0.0): @@ -1048,6 +1160,27 @@ PODS: - React-Mapbuffer (1000.0.0): - glog - React-debug + - React-microtasksnativemodule (1000.0.0): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - React-nativeconfig (1000.0.0) - React-NativeModulesApple (1000.0.0): - glog @@ -1056,6 +1189,7 @@ PODS: - React-Core - React-cxxreact - React-jsi + - React-jsinspector - React-runtimeexecutor - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core @@ -1065,10 +1199,10 @@ PODS: - React-RCTAnimation (1000.0.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTAnimationHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTAppDelegate (1000.0.0): - RCT-Folly (= 2024.01.01.00) @@ -1079,9 +1213,11 @@ PODS: - React-debug - React-domnativemodule - React-Fabric + - React-featureflags + - React-featureflagsnativemodule - React-graphics - React-hermes - - React-jsinspector + - React-microtasksnativemodule - React-nativeconfig - React-NativeModulesApple - React-RCTFabric @@ -1093,16 +1229,20 @@ PODS: - React-RuntimeHermes - React-runtimescheduler - React-utils + - ReactCodegen - ReactCommon - React-RCTBlob (1000.0.0): + - DoubleConversion + - fmt (= 9.1.0) - hermes-engine - RCT-Folly (= 2024.01.01.00) - - React-Codegen - React-Core/RCTBlobHeaders - React-Core/RCTWebSocket - React-jsi + - React-jsinspector - React-NativeModulesApple - React-RCTNetwork + - ReactCodegen - ReactCommon - React-RCTFabric (1000.0.0): - glog @@ -1112,9 +1252,11 @@ PODS: - React-debug - React-Fabric - React-FabricImage + - React-featureflags - React-graphics - React-ImageManager - React-jsi + - React-jsinspector - React-nativeconfig - React-RCTImage - React-RCTText @@ -1126,44 +1268,45 @@ PODS: - React-RCTImage (1000.0.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTImageHeaders - React-jsi - React-NativeModulesApple - React-RCTNetwork + - ReactCodegen - ReactCommon - React-RCTLinking (1000.0.0): - - React-Codegen - React-Core/RCTLinkingHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) - React-NativeModulesApple + - ReactCodegen - ReactCommon - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTNetworkHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTPushNotification (1000.0.0): - RCTTypeSafety - - React-Codegen - React-Core/RCTPushNotificationHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTSettings (1000.0.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTSettingsHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTSwiftExtensions (1000.0.0): - React-Core + - React-RCTWindowManager - React-RCTXR - React-RCTTest (1000.0.0): - RCT-Folly (= 2024.01.01.00) @@ -1176,7 +1319,6 @@ PODS: - Yoga - React-RCTVibration (1000.0.0): - RCT-Folly (= 2024.01.01.00) - - React-Codegen - React-Core/RCTVibrationHeaders - React-jsi - React-NativeModulesApple @@ -1212,6 +1354,7 @@ PODS: - hermes-engine - RCT-Folly/Fabric (= 2024.01.01.00) - React-cxxreact + - React-featureflags - React-jserrorhandler - React-jsi - React-jsiexecutor @@ -1224,7 +1367,10 @@ PODS: - React-RuntimeHermes (1000.0.0): - hermes-engine - RCT-Folly/Fabric (= 2024.01.01.00) + - React-featureflags + - React-hermes - React-jsi + - React-jsinspector - React-jsitracing - React-nativeconfig - React-RuntimeCore @@ -1236,6 +1382,7 @@ PODS: - React-callinvoker - React-cxxreact - React-debug + - React-featureflags - React-jsi - React-rendererconsistency - React-rendererdebug @@ -1243,21 +1390,42 @@ PODS: - React-utils - React-utils (1000.0.0): - glog + - hermes-engine - RCT-Folly (= 2024.01.01.00) - React-debug + - React-jsi (= 1000.0.0) + - ReactCodegen (1000.0.0): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-FabricImage + - React-featureflags + - React-graphics + - React-jsi + - React-jsiexecutor + - React-NativeModulesApple + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core - ReactCommon (1000.0.0): - - React-logger (= 1000.0.0) - ReactCommon/turbomodule (= 1000.0.0) - ReactCommon-Samples (1000.0.0): - DoubleConversion - fmt (= 9.1.0) - hermes-engine - RCT-Folly - - React-Codegen - React-Core - React-cxxreact - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - ReactCommon/turbomodule (1000.0.0): - DoubleConversion @@ -1292,26 +1460,29 @@ PODS: - React-callinvoker (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-debug (= 1000.0.0) + - React-featureflags (= 1000.0.0) - React-jsi (= 1000.0.0) - React-logger (= 1000.0.0) - React-perflogger (= 1000.0.0) - - ScreenshotManager (0.0.1): + - React-utils (= 1000.0.0) + - ScreenshotManager (0.75.0-main): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety - - React-Codegen - React-Core - React-debug - React-Fabric + - React-featureflags - React-graphics - React-ImageManager - React-NativeModulesApple - React-RCTFabric - React-rendererdebug - React-utils + - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga @@ -1335,7 +1506,6 @@ DEPENDENCIES: - RCTTypeSafety (from `../react-native/Libraries/TypeSafety`) - React (from `../react-native/`) - React-callinvoker (from `../react-native/ReactCommon/callinvoker`) - - React-Codegen (from `build/generated/ios`) - React-Core (from `../react-native/`) - React-Core/RCTWebSocket (from `../react-native/`) - React-CoreModules (from `../react-native/React/CoreModules`) @@ -1344,6 +1514,8 @@ DEPENDENCIES: - React-domnativemodule (from `../react-native/ReactCommon/react/nativemodule/dom`) - React-Fabric (from `../react-native/ReactCommon`) - React-FabricImage (from `../react-native/ReactCommon`) + - React-featureflags (from `../react-native/ReactCommon/react/featureflags`) + - React-featureflagsnativemodule (from `../react-native/ReactCommon/react/nativemodule/featureflags`) - React-graphics (from `../react-native/ReactCommon/react/renderer/graphics`) - React-hermes (from `../react-native/ReactCommon/hermes`) - React-ImageManager (from `../react-native/ReactCommon/react/renderer/imagemanager/platform/ios`) @@ -1354,6 +1526,7 @@ DEPENDENCIES: - React-jsitracing (from `../react-native/ReactCommon/hermes/executor/`) - React-logger (from `../react-native/ReactCommon/logger`) - React-Mapbuffer (from `../react-native/ReactCommon`) + - React-microtasksnativemodule (from `../react-native/ReactCommon/react/nativemodule/microtasks`) - React-nativeconfig (from `../react-native/ReactCommon`) - React-NativeModulesApple (from `../react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../react-native/ReactCommon/reactperflogger`) @@ -1380,6 +1553,7 @@ DEPENDENCIES: - React-RuntimeHermes (from `../react-native/ReactCommon/react/runtime`) - React-runtimescheduler (from `../react-native/ReactCommon/react/renderer/runtimescheduler`) - React-utils (from `../react-native/ReactCommon/react/utils`) + - ReactCodegen (from `build/generated/ios`) - ReactCommon-Samples (from `../react-native/ReactCommon/react/nativemodule/samples`) - ReactCommon/turbomodule/core (from `../react-native/ReactCommon`) - ScreenshotManager (from `NativeModuleExample`) @@ -1419,8 +1593,6 @@ EXTERNAL SOURCES: :path: "../react-native/" React-callinvoker: :path: "../react-native/ReactCommon/callinvoker" - React-Codegen: - :path: build/generated/ios React-Core: :path: "../react-native/" React-CoreModules: @@ -1435,6 +1607,10 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon" React-FabricImage: :path: "../react-native/ReactCommon" + React-featureflags: + :path: "../react-native/ReactCommon/react/featureflags" + React-featureflagsnativemodule: + :path: "../react-native/ReactCommon/react/nativemodule/featureflags" React-graphics: :path: "../react-native/ReactCommon/react/renderer/graphics" React-hermes: @@ -1455,6 +1631,8 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon/logger" React-Mapbuffer: :path: "../react-native/ReactCommon" + React-microtasksnativemodule: + :path: "../react-native/ReactCommon/react/nativemodule/microtasks" React-nativeconfig: :path: "../react-native/ReactCommon" React-NativeModulesApple: @@ -1507,6 +1685,8 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon/react/renderer/runtimescheduler" React-utils: :path: "../react-native/ReactCommon/react/utils" + ReactCodegen: + :path: build/generated/ios ReactCommon: :path: "../react-native/ReactCommon" ReactCommon-Samples: @@ -1589,67 +1769,71 @@ SPEC CHECKSUMS: SPEC CHECKSUMS: boost: 8f1e9b214fa11f71081fc8ecd5fad3daf221cf7f DoubleConversion: 26c660c8d88372cca1a67f8101d2d962a7064361 - FBLazyVector: 6d72bc9033085488dab3c20cee3dab2b6a771dda + FBLazyVector: f7c646d10b8cd215e5dab3e26206582d1bd1f3b3 fmt: 5d9ffa7ccba126c08b730252123601d514652320 glog: 4f05d17aa39a829fee878689fc9a41af587fabba - hermes-engine: 3fed7e58e811ae8f795063cc6450714395c0276d - MyNativeView: 534e99e9c5dfd0bae242bdb06bb72e11d720c9a2 - NativeCxxModuleExample: 107af3af8f5ce8802037937aabf1872ac891ad43 + hermes-engine: bca1a39d82a348d5da84cd78a69763e639ca3c03 + MyNativeView: 285c6f70650ff53a276f7086047921e617a4d0e3 + NativeCxxModuleExample: 1cd42853b5ec241c6b5e70f2dd4bbc26feb97b39 OCMock: 267d92c078398b7ce11d99e811e3a402744c06bc - RCT-Folly: 70c792c856324d6a518af75b3a307c14c226343a + RCT-Folly: 38265df22721cd15cc13ba692c23a52cceaf3752 RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf - RCTRequired: 6426efd0d6123b35fdac9ad5796717cbcef85ff9 - RCTTypeSafety: 7c822d061f3b0efcfb058c61cda509369bcb8602 - React: 2f26ffcc453dbb43a07e7396d3cc568cf328f830 - React-callinvoker: 1a7c0d6de53398862ddf642677df14231f6697d9 - React-Codegen: 04a9ac6fd2f392534ed432102c6cbf117dcbf62b - React-Core: 9397cdd14ae7018850c16dea3b31ac72c4ff0324 - React-CoreModules: 53a00162be44e3353f2a9efad243d3dafe258cdb - React-cxxreact: 46f736a9cace851d42a3704c0da637d8566fd7d6 - React-debug: b1f637660400365b9b6908bd521ffce20c713dc5 - React-Fabric: 34c01267cb5ace971a7ae1a9c720ce5b30e92465 - React-FabricImage: 2e076721abe31734ce2a01cf82e254801ce5503f - React-graphics: 5ca218f8180dda07f997fa5ad145b7d5d7f35bd9 - React-hermes: d5707721feadf6c74d53fbc7a6212a98a140954c - React-ImageManager: deb13029061d5b0b08b21b8ea5883c15b7f4ba93 - React-jserrorhandler: f719009db2ae821f7df30866fa7e16676a14e85d - React-jsi: 9bf49563b30132199feb9b7721289ebbe61258f5 - React-jsiexecutor: 81e5a31965bb0e29d66df963ec9bf13496e84482 - React-jsinspector: 3b3514d648791386506f2f4eb7f1791e8b44f663 - React-jsitracing: 84ec35538d5d28a74431e58fc245761327dcb537 - React-logger: a41fc9cccff7de126c97e366c8909304531813ec - React-Mapbuffer: 3f22d38e3c903fa729061b0e8b976d102c377306 - React-nativeconfig: 0d00e737812420344137c8b7010033675d527982 - React-NativeModulesApple: 803f8508c47c2963cf893d74904ccc605fae4696 - React-perflogger: 0d57e63db7d181c2c3b9d13305b89b7783615739 - React-RCTActionSheet: aa4ae1a2a14153412e9237b10234a40e30d2b410 - React-RCTAnimation: 7eea83acd5da45de3d2e0c3aaa8df9d2957783bf - React-RCTAppDelegate: d48ddb6a45470b5d5d75d35927c2342698c47e56 - React-RCTBlob: 038dce0c29488cfbc19daa6d60b1cfcb01e9172d - React-RCTFabric: 131c60dc266f637d45c75c02b81d337c4e3179f9 - React-RCTImage: af4bbba6368f6b219915ca569ae5cf67fc8585f8 - React-RCTLinking: ce884034ffbece4c6c2ae8e1e8b4b88fb0ee406b - React-RCTNetwork: 488fca1b0e9f4f9802696372216029f5d1da6bc6 - React-RCTPushNotification: 2bb0038afd0c02f65d7b74b93bddcb2639cc6edf - React-RCTSettings: 0ff75db9df85764bd838b1ea9411fde23247f229 - React-RCTSwiftExtensions: 0751aeb108e9c7ae39b26710b7fb47d79fe0bfb9 - React-RCTTest: 3144ece03e48904e7796c2a96bd931649027516d - React-RCTText: abc6d97f7e36f9aed66678fc712f703d5bce2dfc - React-RCTVibration: 2b3b6cda5f979b0d16db391e737651d0dd4147a6 - React-RCTXR: 07a185fd7221532ccc6a5a9f237102256f823e60 - React-rendererdebug: 48c745f05ebf3ae447ea521c2b77bb7ee3923fd6 - React-rncore: 84944ba68705b5de9959d2206cfe7dd3181e83f2 - React-RuntimeApple: 33e35a0c93367647120758a61c71e21c73ce54ee - React-RuntimeCore: 7a4d19efece49c4087fd7bb30a643397d9ba1ab1 - React-runtimeexecutor: fb3425d082ad47c4bc7153419b3eac899d318603 - React-RuntimeHermes: 556f92a11c0cf9b4d4e4d7240dca228bdebb4622 - React-runtimescheduler: c101938ad407340555eb5d56557b3409785a7396 - React-utils: c3b2a4535dfad1e3c68d371b3946a33db4ceac4a - ReactCommon: 93b947fa9f432e09577a5d8c3f09c0ad7a6a4fc5 - ReactCommon-Samples: 6a59337d27861b986269a95c52aa5353b87da4ba - ScreenshotManager: a5f596498de38f3cf3377df636ca67355503f190 + RCTRequired: 239aa032bf3e9e2b43f4279650d63c0514951272 + RCTTypeSafety: e5bbadc74447a21a1cc6d98ad4d5cdfc73ad5b66 + React: 36785b138eaf4d504269ac00ff83c830b0373cc5 + React-callinvoker: bd85ea880a7f9ec6f795b61e3e358fde6c0b317f + React-Core: a26b444d25335c293811d41c9ac1e305a874f3b6 + React-CoreModules: 4ee3dd2283abea7880db94ca0d8d74378f3ec9c7 + React-cxxreact: 1db0679e0e4ecd9f4cd558bb3a0c7c5c61898c46 + React-debug: 76832f0727faeabe8d5797b89af59405245303ab + React-Fabric: 2eb7d788b7494a689a8c037e9f19bbdfc0a98c16 + React-FabricImage: 78fd6dd2c9941919148085b849899efe2374753d + React-featureflags: 0b457907abe15741d96164e86f987e44e0deb682 + React-featureflagsnativemodule: 8099131f04c0e14100b9042e502c9f4a601a1c9f + React-graphics: b3dccf47ce13236169b572f2ae68294254b9d00b + React-hermes: 2ecd1177928bb621e1417d3355d97f712ab80ba8 + React-ImageManager: a116cb9770a8dd1a96663949b46c62b2b88e215e + React-jserrorhandler: 840ed095e547ec53ab9e1358fe9d328388ad6bfe + React-jsi: 296634766135fc72c578f836ed11ea43c30f062a + React-jsiexecutor: dc33a899bb4a018c1fd782fa86b39a3244fd67da + React-jsinspector: 2bc546bf89903b65c6e66a822b65239ec3ffbe2f + React-jsitracing: 57b4ec6a2f0442242cbcbf8f017cf697020dca37 + React-logger: be89505b09a5ee83ff68c205b1bcd2ebb3946f1c + React-Mapbuffer: 708e90b77110c3fa3fe2ae81c4ddc169cb7eeca0 + React-microtasksnativemodule: b3855853e36d49824f3b99174067fc2f4ed60044 + React-nativeconfig: 5b509000c98cbe5ca55fcc795bc41604e1c95133 + React-NativeModulesApple: ca430b16c6130627f584bc2a13c10cf0864dd23f + React-perflogger: 47f5978f4e2183208b911e7b009b887602165566 + React-RCTActionSheet: 36cbb9a32d7b0a762fa260b693f233438e2eba42 + React-RCTAnimation: 0c19d427491635e8cf80e0d22652339317760495 + React-RCTAppDelegate: cb18253c38d44dfdb270aaf969e212e141ff2eda + React-RCTBlob: 67d12c51a8dc3bf915c5dbd568fdf2420c593946 + React-RCTFabric: 0c297f7bfff6bfc15493e6b52d926206ddf4e7f3 + React-RCTImage: 2268b4c62d81343cb4a261b01c285140f583fefb + React-RCTLinking: 659311c46fc100f750d0bd06d5b347dd731f014c + React-RCTNetwork: 8b8df92aa1eb87bc028ee94689a747b85956db27 + React-RCTPushNotification: bfe7a851d7c69005bf42c31262db3c388566a9a7 + React-RCTSettings: ab9f3f94954c3e226075c51d69b4fbe5355f8cbc + React-RCTSwiftExtensions: 9796d287e7bbd7b11551f93ac99f2f6f637795ad + React-RCTTest: d2b359f29ae63fa20b90859dbf9cc01bd06319ec + React-RCTText: c7a31b344ff91c62c8eb51cb19ae75e94c74caaa + React-RCTVibration: dbb77d0546be6644df5a0d72c7c71d84074f8dd6 + React-RCTWindowManager: 590894746aee624fcb4eab807224fc5708e6b018 + React-RCTXR: 8ada18d6b23da3c6d1afcf8232ee9df9f3b42f2f + React-rendererdebug: ee39d499144ad322a5e8f2815197b2be770151fd + React-rncore: 9104c5cc28cd2777a641843b2297c55674593e64 + React-RuntimeApple: e6c533fe960654098a2bc1f63a9a2b9589311b94 + React-RuntimeCore: 8484628d9d4914ccfd1f3905cabca19b3e605419 + React-runtimeexecutor: 2f2c677c8600c1105928a67f5f725518bf1f9d27 + React-RuntimeHermes: cd010ffb49df509b57077716359a5275ce4db90b + React-runtimescheduler: 9c66554fc1cc6f28952949366150f2d39dae2eaf + React-utils: a94e4f22cc27a2bb874ba9d97de87fd0ec4f5d5f + ReactCodegen: 2fa2bfb8df604e5bbf2462cf3cced313c3131b96 + ReactCommon: 4760f12d60e79f903e5fff832e29a925bdc8d764 + ReactCommon-Samples: bed8a502f833c9b4c18331dc3f8ded5c090b2217 + ScreenshotManager: 662151998cf5859591e72c76ceb9ebc6d04b425b SocketRocket: 0ba3e799f983d2dfa878777017659ef6c866e5c6 - Yoga: 50572c6c7c8227a84feb5746efa5f841f75f6f1b + Yoga: 00ec2b1b43fcb85eb2faeb0263759b7995c9ddad PODFILE CHECKSUM: 7e999b8158f1055609ef4491bc35f1ad658fdd6c diff --git a/packages/rn-tester/RNTester-visionOS/App.swift b/packages/rn-tester/RNTester-visionOS/App.swift index 8e28482981e8a6..939cef2664d031 100644 --- a/packages/rn-tester/RNTester-visionOS/App.swift +++ b/packages/rn-tester/RNTester-visionOS/App.swift @@ -5,11 +5,17 @@ import React_RCTSwiftExtensions @main struct RNTesterApp: App { @UIApplicationDelegateAdaptor var delegate: AppDelegate + @Environment(\.reactContext) private var reactContext + @State private var immersionLevel: ImmersionStyle = .full var body: some Scene { RCTMainWindow(moduleName: "RNTesterApp") + + RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow")) + .defaultSize(CGSize(width: 400, height: 700)) + ImmersiveSpace(id: "TestImmersiveSpace") {} - .immersionStyle(selection: $immersionLevel, in: .mixed, .progressive, .full) + .immersionStyle(selection: $immersionLevel, in: .mixed, .progressive, .full) } } diff --git a/packages/rn-tester/js/RNTesterApp.ios.js b/packages/rn-tester/js/RNTesterApp.ios.js index 281ee25afd77a1..8ea87c26361438 100644 --- a/packages/rn-tester/js/RNTesterApp.ios.js +++ b/packages/rn-tester/js/RNTesterApp.ios.js @@ -24,6 +24,9 @@ AppRegistry.registerComponent('SetPropertiesExampleApp', () => AppRegistry.registerComponent('RootViewSizeFlexibilityExampleApp', () => require('./examples/RootViewSizeFlexibilityExample/RootViewSizeFlexibilityExampleApp'), ); +AppRegistry.registerComponent('SecondWindow', () => + require('./examples/SecondWindow/SecondWindow'), +); AppRegistry.registerComponent('RNTesterApp', () => RNTesterApp); // Register suitable examples for snapshot tests diff --git a/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js b/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js new file mode 100644 index 00000000000000..10f71a32dae917 --- /dev/null +++ b/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js @@ -0,0 +1,52 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; + +const {WindowManager} = require('@callstack/react-native-visionos'); +const React = require('react'); +const {Button, StyleSheet, Text, View} = require('react-native'); + +type Props = $ReadOnly<{| + title?: String, +|}>; + +const SecondWindow = ({title}: Props): React.Node => { + const [counter, setCounter] = React.useState(0); + return ( + + {title} + {counter} +