<lambda>null1 package expo.modules.devmenu.modules
2 
3 import android.content.ClipData
4 import android.content.ClipboardManager
5 import android.content.Context
6 import com.facebook.react.bridge.Arguments
7 import com.facebook.react.bridge.ReadableMap
8 import expo.modules.core.utilities.EmulatorUtilities
9 import expo.modules.devmenu.DevMenuManager
10 import expo.modules.kotlin.Promise
11 import expo.modules.kotlin.exception.Exceptions
12 import expo.modules.kotlin.exception.UnexpectedException
13 import expo.modules.kotlin.modules.Module
14 import expo.modules.kotlin.modules.ModuleDefinition
15 import kotlinx.coroutines.launch
16 
17 class DevMenuInternalModule : Module() {
18   private val context: Context
19     get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
20 
21   override fun definition() = ModuleDefinition {
22     Name("ExpoDevMenuInternal")
23     Constants(
24       "doesDeviceSupportKeyCommands" to EmulatorUtilities.isRunningOnEmulator()
25     )
26 
27     AsyncFunction("loadFontsAsync") {
28       DevMenuManager.loadFonts(context)
29     }
30 
31     AsyncFunction("dispatchCallableAsync") { callableId: String, args: ReadableMap? ->
32       DevMenuManager.dispatchCallable(callableId, args)
33     }
34 
35     AsyncFunction("hideMenu") {
36       DevMenuManager.hideMenu()
37     }
38 
39     AsyncFunction("closeMenu") {
40       DevMenuManager.closeMenu()
41     }
42 
43     AsyncFunction("setOnboardingFinished") { finished: Boolean ->
44       DevMenuManager.getSettings()?.isOnboardingFinished = finished
45     }
46 
47     AsyncFunction<Unit>("openDevMenuFromReactNative") {
48       val instanceManager = DevMenuManager.getReactInstanceManager() ?: return@AsyncFunction
49       val devSupportManager = instanceManager.devSupportManager
50       val activity = instanceManager.currentReactContext?.currentActivity ?: return@AsyncFunction
51 
52       activity.runOnUiThread {
53         DevMenuManager.closeMenu()
54         devSupportManager.devSupportEnabled = true
55         devSupportManager.showDevOptionsDialog()
56       }
57     }
58 
59     AsyncFunction("onScreenChangeAsync") { currentScreen: String? ->
60       DevMenuManager.setCurrentScreen(currentScreen)
61     }
62 
63     AsyncFunction("fetchDataSourceAsync") { id: String, promise: Promise ->
64       DevMenuManager.coroutineScope.launch {
65         val data = DevMenuManager.fetchDataSource(id)
66         val result = Arguments.fromList(data.map { it.serialize() })
67         promise.resolve(result)
68       }
69     }
70 
71     AsyncFunction("copyToClipboardAsync") { content: String ->
72       val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
73       val clip = ClipData.newPlainText(null, content)
74       clipboard.setPrimaryClip(clip)
75     }
76 
77     AsyncFunction("fireCallback") { name: String ->
78       val callback = DevMenuManager.registeredCallbacks.firstOrNull { it.name == name }
79         ?: throw UnexpectedException("Callback with name: $name is not registered")
80 
81       DevMenuManager.sendEventToDelegateBridge("registeredCallbackFired", name)
82       if (callback.shouldCollapse) {
83         DevMenuManager.closeMenu()
84       }
85     }
86   }
87 }
88