1 // Copyright 2015-present 650 Industries. All rights reserved. 2 3 import React 4 5 class DevMenuDevOptionsDelegate { 6 internal private(set) weak var bridge: RCTBridge? 7 internal private(set) weak var devSettings: RCTDevSettings? 8 9 #if DEBUG 10 internal private(set) weak var perfMonitor: RCTPerfMonitor? 11 #endif 12 13 internal init(forBridge bridge: RCTBridge) { 14 self.bridge = bridge 15 devSettings = bridge.module(forName: "DevSettings") as? RCTDevSettings 16 17 #if DEBUG 18 perfMonitor = bridge.module(forName: "PerfMonitor") as? RCTPerfMonitor 19 #endif 20 } 21 22 internal func reload() { 23 // Without this the `expo-splash-screen` will reject 24 // No native splash screen registered for given view controller. Call 'SplashScreen.show' for given view controller first. 25 DevMenuManager.shared.hideMenu() 26 27 bridge?.requestReload() 28 } 29 30 internal func toggleElementInsector() { 31 devSettings?.toggleElementInspector() 32 } 33 34 internal func openJSInspector() { 35 guard let bundleURL = bridge?.bundleURL else { 36 return 37 } 38 let port = bundleURL.port ?? Int(RCT_METRO_PORT) 39 let host = bundleURL.host ?? "localhost" 40 let openURL = "http://\(host):\(port)/inspector?applicationId=\(Bundle.main.bundleIdentifier ?? "")" 41 guard let url = URL(string: openURL) else { 42 NSLog("[DevMenu] Invalid openJSInspector URL: $@", openURL) 43 return 44 } 45 let request = NSMutableURLRequest(url: url) 46 request.httpMethod = "PUT" 47 URLSession.shared.dataTask(with: request as URLRequest).resume() 48 } 49 50 internal func toggleRemoteDebugging() { 51 guard let devSettings = devSettings else { 52 return 53 } 54 55 DevMenuManager.shared.hideMenu() 56 57 DispatchQueue.main.async { 58 devSettings.isDebuggingRemotely = !devSettings.isDebuggingRemotely 59 (DevMenuManager.shared.window?.rootViewController as? DevMenuViewController)?.updateProps() // We have to force props to reflect changes on the UI 60 } 61 } 62 63 internal func togglePerformanceMonitor() { 64 #if DEBUG 65 guard let perfMonitor = perfMonitor else { 66 return 67 } 68 69 guard let devSettings = devSettings else { 70 return 71 } 72 73 DispatchQueue.main.async { 74 devSettings.isPerfMonitorShown ? perfMonitor.hide() : perfMonitor.show() 75 devSettings.isPerfMonitorShown = !devSettings.isPerfMonitorShown 76 } 77 #endif 78 } 79 80 internal func toggleFastRefresh() { 81 guard let devSettings = devSettings else { 82 return 83 } 84 85 devSettings.isHotLoadingEnabled = !devSettings.isHotLoadingEnabled 86 } 87 } 88