1 // Copyright 2015-present 650 Industries. All rights reserved. 2 3 @objc(DevMenuInternalModule) 4 public class DevMenuInternalModule: NSObject, RCTBridgeModule { 5 public static func moduleName() -> String! { 6 return "ExpoDevMenuInternal" 7 } 8 9 private static var fontsWereLoaded = false; 10 11 let manager: DevMenuManager 12 13 init(manager: DevMenuManager) { 14 self.manager = manager 15 } 16 17 // MARK: JavaScript API 18 19 @objc 20 func loadFontsAsync(_ resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { 21 if (DevMenuInternalModule.fontsWereLoaded) { 22 resolve(nil); 23 return; 24 } 25 26 let fonts = ["MaterialCommunityIcons", "Ionicons"] 27 for font in fonts { 28 guard let path = DevMenuUtils.resourcesBundle()?.path(forResource: font, ofType: "ttf") else { 29 reject("ERR_DEVMENU_CANNOT_FIND_FONT", "Font file for '\(font)' doesn't exist.", nil); 30 return; 31 } 32 guard let data = FileManager.default.contents(atPath: path) else { 33 reject("ERR_DEVMENU_CANNOT_OPEN_FONT_FILE", "Could not open '\(path)'.", nil); 34 return; 35 } 36 37 guard let provider = CGDataProvider(data: data as CFData) else { 38 reject("ERR_DEVMENU_CANNOT_CREATE_FONT_PROVIDER", "Could not create font provider for '\(font)'.", nil); 39 return; 40 } 41 guard let cgFont = CGFont(provider) else { 42 reject("ERR_DEVMENU_CANNOT_CREATE_FONT", "Could not create font for '\(font)'.", nil); 43 return; 44 } 45 46 var error: Unmanaged<CFError>? 47 if !CTFontManagerRegisterGraphicsFont(cgFont, &error) { 48 reject("ERR_DEVMENU_CANNOT_ADD_FONT", "Could not create font from loaded data for '\(font)'. '\(error.debugDescription)'.", nil) 49 return 50 } 51 } 52 53 DevMenuInternalModule.fontsWereLoaded = true 54 resolve(nil) 55 } 56 57 @objc 58 func dispatchActionAsync(_ actionId: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { 59 if actionId == nil { 60 return reject("ERR_DEVMENU_ACTION_FAILED", "Action ID not provided.", nil) 61 } 62 manager.dispatchAction(withId: actionId) 63 resolve(nil) 64 } 65 66 @objc 67 func hideMenu() { 68 manager.hideMenu() 69 } 70 71 @objc 72 func setOnboardingFinished(_ finished: Bool) { 73 DevMenuSettings.isOnboardingFinished = finished 74 } 75 76 @objc 77 func getSettingsAsync(_ resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { 78 resolve(DevMenuSettings.serialize()) 79 } 80 81 @objc 82 func setSettingsAsync(_ dict: [String: Any], resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { 83 if let motionGestureEnabled = dict["motionGestureEnabled"] as? Bool { 84 DevMenuSettings.motionGestureEnabled = motionGestureEnabled 85 } 86 if let touchGestureEnabled = dict["touchGestureEnabled"] as? Bool { 87 DevMenuSettings.touchGestureEnabled = touchGestureEnabled 88 } 89 if let keyCommandsEnabled = dict["keyCommandsEnabled"] as? Bool { 90 DevMenuSettings.keyCommandsEnabled = keyCommandsEnabled 91 } 92 if let showsAtLaunch = dict["showsAtLaunch"] as? Bool { 93 DevMenuSettings.showsAtLaunch = showsAtLaunch 94 } 95 } 96 } 97