1 package host.exp.exponent.experience
2 
3 import com.facebook.react.bridge.NativeModule
4 import com.facebook.react.bridge.ReactApplicationContext
5 import expo.modules.adapters.react.ReactModuleRegistryProvider
6 import expo.modules.core.ModuleRegistry
7 import expo.modules.core.interfaces.RegistryLifecycleListener
8 import expo.modules.manifests.core.Manifest
9 import host.exp.exponent.kernel.ExperienceKey
10 import host.exp.exponent.utils.ScopedContext
11 import versioned.host.exp.exponent.modules.universal.ConstantsBinding
12 import versioned.host.exp.exponent.modules.universal.ExpoModuleRegistryAdapter
13 import versioned.host.exp.exponent.modules.universal.ScopedUIManagerModuleWrapper
14 import versioned.host.exp.exponent.modules.universal.UpdatesBinding
15 
16 open class DetachedModuleRegistryAdapter(moduleRegistryProvider: ReactModuleRegistryProvider) :
17   ExpoModuleRegistryAdapter(moduleRegistryProvider) {
18 
createNativeModulesnull19   override fun createNativeModules(
20     scopedContext: ScopedContext,
21     experienceKey: ExperienceKey,
22     experienceProperties: Map<String, Any?>,
23     manifest: Manifest,
24     otherModules: List<NativeModule>
25   ): List<NativeModule> {
26     val reactApplicationContext = scopedContext.context as ReactApplicationContext
27 
28     // We only use React application context, because we're detached -- no scopes
29     val moduleRegistry = mModuleRegistryProvider[reactApplicationContext]
30 
31     moduleRegistry.registerInternalModule(
32       ConstantsBinding(
33         scopedContext,
34         experienceProperties,
35         manifest
36       )
37     )
38 
39     // Overriding expo-updates UpdatesService
40     moduleRegistry.registerInternalModule(UpdatesBinding(scopedContext, experienceProperties))
41 
42     // ReactAdapterPackage requires ReactContext
43     val reactContext = scopedContext.context as ReactApplicationContext
44     for (internalModule in mReactAdapterPackage.createInternalModules(reactContext)) {
45       moduleRegistry.registerInternalModule(internalModule)
46     }
47 
48     // Overriding ScopedUIManagerModuleWrapper from ReactAdapterPackage
49     moduleRegistry.registerInternalModule(ScopedUIManagerModuleWrapper(reactContext))
50 
51     // Adding other modules (not universal) to module registry as consumers.
52     // It allows these modules to refer to universal modules.
53     for (otherModule in otherModules) {
54       if (otherModule is RegistryLifecycleListener) {
55         moduleRegistry.registerExtraListener(otherModule as RegistryLifecycleListener)
56       }
57     }
58     configureModuleRegistry(moduleRegistry, reactApplicationContext)
59     return getNativeModulesFromModuleRegistry(reactApplicationContext, moduleRegistry, null)
60   }
61 
configureModuleRegistrynull62   protected open fun configureModuleRegistry(
63     moduleRegistry: ModuleRegistry,
64     reactContext: ReactApplicationContext
65   ) {
66     // Subclasses may add more modules here.
67   }
68 }
69