From d31238758c5f2cf2d98508755633e76b39e0661e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwas=CC=81niewski?= Date: Mon, 10 Jun 2024 17:07:47 +0200 Subject: [PATCH] fix: allow to manually move dev menu to avoid conflicts --- .../SwiftExtensions/RCTMainWindow.swift | 44 +++++++++++-------- .../RCTRootViewRepresentable.swift | 20 ++++++++- .../Libraries/SwiftExtensions/RCTWindow.swift | 2 +- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift index be7d25cdae98b4..28741f9de89977 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift +++ b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift @@ -22,11 +22,11 @@ public struct RCTMainWindow: Scene { var moduleName: String var initialProps: RCTRootViewRepresentable.InitialPropsType var onOpenURLCallback: ((URL) -> ())? - var devMenuPlacement: ToolbarPlacement = .bottomOrnament + var devMenuSceneAnchor: UnitPoint? var contentView: AnyView? var rootView: RCTRootViewRepresentable { - RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps) + RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps, devMenuSceneAnchor: devMenuSceneAnchor) } /// Creates new RCTMainWindowWindow. @@ -38,11 +38,11 @@ public struct RCTMainWindow: Scene { public init( moduleName: String, initialProps: RCTRootViewRepresentable.InitialPropsType = nil, - devMenuPlacement: ToolbarPlacement = .bottomOrnament + devMenuSceneAnchor: UnitPoint? = .bottom ) { self.moduleName = moduleName self.initialProps = initialProps - self.devMenuPlacement = devMenuPlacement + self.devMenuSceneAnchor = devMenuSceneAnchor self.contentView = AnyView(rootView) } @@ -56,12 +56,12 @@ public struct RCTMainWindow: Scene { public init( moduleName: String, initialProps: RCTRootViewRepresentable.InitialPropsType = nil, - devMenuPlacement: ToolbarPlacement = .bottomOrnament, + devMenuSceneAnchor: UnitPoint? = .bottom, @ViewBuilder contentView: @escaping (_ view: RCTRootViewRepresentable) -> Content ) { self.moduleName = moduleName self.initialProps = initialProps - self.devMenuPlacement = devMenuPlacement + self.devMenuSceneAnchor = devMenuSceneAnchor self.contentView = AnyView(contentView(rootView)) } @@ -72,11 +72,6 @@ public struct RCTMainWindow: Scene { .onOpenURL(perform: { url in onOpenURLCallback?(url) }) -#if DEBUG - .toolbar { - DevMenuView(placement: .bottomOrnament) - } -#endif } } } @@ -142,18 +137,14 @@ public struct WindowHandlingModifier: ViewModifier { /** Toolbar which displays additional controls to easily open dev menu and trigger reload command. */ -struct DevMenuView: ToolbarContent { - let placement: ToolbarItemPlacement - - var body: some ToolbarContent { - ToolbarItem(placement: placement) { +struct DevMenuView: View { + var body: some View { + HStack { Button(action: { RCTTriggerReloadCommandListeners("User Reload") }, label: { Image(systemName: "arrow.clockwise") }) - } - ToolbarItem(placement: placement) { Button(action: { NotificationCenter.default.post( Notification(name: Notification.Name("RCTShowDevMenuNotification"), object: nil) @@ -163,5 +154,22 @@ struct DevMenuView: ToolbarContent { Image(systemName: "filemenu.and.selection") }) } + .padding() + .glassBackgroundEffect() } } + +extension View { + /// Applies the given transform if the given condition evaluates to `true`. + /// - Parameters: + /// - condition: The condition to evaluate. + /// - transform: The transform to apply to the source `View`. + /// - Returns: Either the original `View` or the modified `View` if the condition is `true`. + @ViewBuilder func `if`(_ condition: @autoclosure () -> Bool, transform: (Self) -> Content) -> some View { + if condition() { + transform(self) + } else { + self + } + } +} diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift index 8a839541ebb8ea..f57b9cceb27b0a 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift +++ b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift @@ -16,14 +16,30 @@ public struct RCTRootViewRepresentable: UIViewControllerRepresentable { var moduleName: String var initialProps: InitialPropsType + var devMenuSceneAnchor: UnitPoint? - public init(moduleName: String, initialProps: InitialPropsType = nil) { + public init( + moduleName: String, + initialProps: InitialPropsType = nil, + devMenuSceneAnchor: UnitPoint? = .bottom + ) { self.moduleName = moduleName self.initialProps = initialProps + self.devMenuSceneAnchor = devMenuSceneAnchor } public func makeUIViewController(context: Context) -> RCTReactViewController { - RCTReactViewController(moduleName: moduleName, initProps: initialProps) + let viewController = RCTReactViewController(moduleName: moduleName, initProps: initialProps) +#if DEBUG + if let devMenuSceneAnchor { + let ornament = UIHostingOrnament(sceneAnchor: devMenuSceneAnchor) { + DevMenuView() + } + // check if user has an ornament at this position, if so thr + viewController.ornaments.append(ornament) + } +#endif + return viewController } public func updateUIViewController(_ uiViewController: RCTReactViewController, context: Context) { diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift index fe678107d0ec00..d2bc884953b57a 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift +++ b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift @@ -16,7 +16,7 @@ public struct RCTWindow : Scene { var contentView: AnyView? func getRootView(sceneData: RCTSceneData?) -> RCTRootViewRepresentable { - return RCTRootViewRepresentable(moduleName: moduleName, initialProps: sceneData?.props ?? [:]) + return RCTRootViewRepresentable(moduleName: moduleName, initialProps: sceneData?.props ?? [:], devMenuSceneAnchor: nil) } public var body: some Scene {