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 
reloadnull22   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     DispatchQueue.main.async {
28       RCTTriggerReloadCommandListeners("Dev menu - reload")
29     }
30   }
31 
toggleElementInsectornull32   internal func toggleElementInsector() {
33     devSettings?.toggleElementInspector()
34   }
35 
openJSInspectornull36   internal func openJSInspector() {
37     guard let bundleURL = bridge?.bundleURL else {
38       return
39     }
40     let port = bundleURL.port ?? Int(RCT_METRO_PORT)
41     let host = bundleURL.host ?? "localhost"
42     let openURL = "http://\(host):\(port)/inspector?applicationId=\(Bundle.main.bundleIdentifier ?? "")"
43     guard let url = URL(string: openURL) else {
44       NSLog("[DevMenu] Invalid openJSInspector URL: $@", openURL)
45       return
46     }
47     let request = NSMutableURLRequest(url: url)
48     request.httpMethod = "PUT"
49     URLSession.shared.dataTask(with: request as URLRequest).resume()
50   }
51 
toggleRemoteDebuggingnull52   internal func toggleRemoteDebugging() {
53     guard let devSettings = devSettings else {
54       return
55     }
56 
57     DevMenuManager.shared.hideMenu()
58 
59     DispatchQueue.main.async {
60       devSettings.isDebuggingRemotely = !devSettings.isDebuggingRemotely
61       (DevMenuManager.shared.window?.rootViewController as? DevMenuViewController)?.updateProps() // We have to force props to reflect changes on the UI
62     }
63   }
64 
togglePerformanceMonitornull65   internal func togglePerformanceMonitor() {
66     #if DEBUG
67     guard let perfMonitor = perfMonitor else {
68       return
69     }
70 
71     guard let devSettings = devSettings else {
72       return
73     }
74 
75     DispatchQueue.main.async {
76       devSettings.isPerfMonitorShown ? perfMonitor.hide() : perfMonitor.show()
77       devSettings.isPerfMonitorShown = !devSettings.isPerfMonitorShown
78     }
79     #endif
80   }
81 
toggleFastRefreshnull82   internal func toggleFastRefresh() {
83     guard let devSettings = devSettings else {
84       return
85     }
86 
87     devSettings.isHotLoadingEnabled = !devSettings.isHotLoadingEnabled
88   }
89 }
90