@callstack/react-native-brownfield 0.1.0 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +24 -1
  2. package/ReactNativeBrownfield.podspec +10 -3
  3. package/android/build.gradle +89 -16
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt +82 -15
  6. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfieldModule.kt +22 -21
  7. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfieldPackage.kt +9 -9
  8. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt +139 -145
  9. package/ios/ReactNativeBrownfield.swift +119 -0
  10. package/ios/ReactNativeBrownfieldModule.m +8 -11
  11. package/ios/ReactNativeBrownfieldModule.swift +18 -0
  12. package/ios/ReactNativeView.swift +42 -0
  13. package/ios/ReactNativeViewController.swift +66 -0
  14. package/lib/commonjs/RNBrownfieldSpec.js +9 -0
  15. package/lib/commonjs/RNBrownfieldSpec.js.map +1 -0
  16. package/lib/commonjs/index.js +6 -4
  17. package/lib/commonjs/index.js.map +1 -1
  18. package/lib/commonjs/package.json +1 -0
  19. package/lib/module/RNBrownfieldSpec.js +5 -0
  20. package/lib/module/RNBrownfieldSpec.js.map +1 -0
  21. package/lib/module/index.js +8 -5
  22. package/lib/module/index.js.map +1 -1
  23. package/lib/module/package.json +1 -0
  24. package/lib/typescript/src/RNBrownfieldSpec.d.ts +20 -0
  25. package/lib/typescript/src/RNBrownfieldSpec.d.ts.map +1 -0
  26. package/lib/typescript/src/index.d.ts.map +1 -1
  27. package/package.json +32 -27
  28. package/src/RNBrownfieldSpec.ts +23 -0
  29. package/src/index.ts +6 -7
  30. package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeActivity.kt +0 -188
  31. package/ios/ReactNativeBrownfield.h +0 -24
  32. package/ios/ReactNativeBrownfield.m +0 -82
  33. package/ios/ReactNativeBrownfieldNotifications.h +0 -4
  34. package/ios/ReactNativeBrownfieldNotifications.m +0 -4
  35. package/ios/ReactNativeViewController.h +0 -15
  36. package/ios/ReactNativeViewController.m +0 -66
@@ -3,174 +3,168 @@ package com.callstack.reactnativebrownfield;
3
3
  import android.annotation.TargetApi
4
4
  import android.os.Build
5
5
  import android.os.Bundle
6
- import androidx.fragment.app.Fragment
7
6
  import android.view.KeyEvent
8
- import android.view.LayoutInflater
9
- import android.view.View
10
- import android.view.ViewGroup
11
7
  import com.facebook.infer.annotation.Assertions
12
- import com.facebook.react.ReactRootView
8
+ import com.facebook.react.ReactFragment
9
+ import com.facebook.react.ReactHost
10
+ import com.facebook.react.ReactNativeHost
13
11
  import com.facebook.react.bridge.Callback
14
12
  import com.facebook.react.bridge.WritableMap
15
13
  import com.facebook.react.common.LifecycleState
14
+ import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
16
15
  import com.facebook.react.devsupport.DoubleTapReloadRecognizer
17
16
  import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler
18
17
  import com.facebook.react.modules.core.PermissionAwareActivity
19
18
  import com.facebook.react.modules.core.PermissionListener
20
19
 
21
- private const val MODULE_NAME = "com.callstack.reactnativebrownfield.FRAGMENT_MODULE_NAME"
22
- private const val INITIAL_PROPS = "com.callstack.reactnativebrownfield.FRAGMENT_INITIAL_PROPS"
23
-
24
- class ReactNativeFragment : Fragment(), PermissionAwareActivity {
25
-
26
- private var reactRootView: ReactRootView? = null
27
- private lateinit var doubleTapReloadRecognizer: DoubleTapReloadRecognizer
28
- private lateinit var permissionsCallback: Callback
29
- private var permissionListener: PermissionListener? = null
30
-
31
- override fun onCreate(savedInstanceState: Bundle?) {
32
- super.onCreate(savedInstanceState)
33
- val moduleName = arguments?.getString(MODULE_NAME)!!
34
- val initialProps = arguments?.getBundle(INITIAL_PROPS)
35
-
36
- doubleTapReloadRecognizer = DoubleTapReloadRecognizer()
37
-
38
- reactRootView = ReactRootView(context)
39
- reactRootView?.startReactApplication(
40
- ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager,
41
- moduleName,
42
- initialProps
43
- )
44
- }
45
-
46
-
47
- override fun onCreateView(
48
- inflater: LayoutInflater,
49
- container: ViewGroup?,
50
- savedInstanceState: Bundle?
51
- ): View {
52
- return reactRootView!!
20
+ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity {
21
+ private lateinit var doubleTapReloadRecognizer: DoubleTapReloadRecognizer
22
+ private lateinit var permissionsCallback: Callback
23
+ private var permissionListener: PermissionListener? = null
24
+
25
+ override fun onCreate(savedInstanceState: Bundle?) {
26
+ super.onCreate(savedInstanceState)
27
+ doubleTapReloadRecognizer = DoubleTapReloadRecognizer()
28
+ }
29
+
30
+ override fun getReactHost(): ReactHost? {
31
+ return activity?.let {
32
+ getDefaultReactHost(
33
+ it.applicationContext,
34
+ ReactNativeBrownfield.shared.reactNativeHost
35
+ )
53
36
  }
54
-
55
- override fun onResume() {
56
- super.onResume()
57
- if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
58
- ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager?.onHostResume(
59
- activity,
60
- activity as DefaultHardwareBackBtnHandler
61
- )
62
- }
37
+ }
38
+
39
+ override fun getReactNativeHost(): ReactNativeHost? {
40
+ return ReactNativeBrownfield.shared.reactNativeHost
41
+ }
42
+
43
+ override fun onResume() {
44
+ super.onResume()
45
+ if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
46
+ ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager?.onHostResume(
47
+ activity,
48
+ activity as DefaultHardwareBackBtnHandler
49
+ )
63
50
  }
64
-
65
- override fun onPause() {
66
- super.onPause()
67
- if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
68
- ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager?.onHostPause(
69
- activity
70
- )
71
- }
51
+ }
52
+
53
+ override fun onPause() {
54
+ super.onPause()
55
+ if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
56
+ ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager?.onHostPause(
57
+ activity
58
+ )
72
59
  }
60
+ }
73
61
 
74
- override fun onDestroy() {
75
- super.onDestroy()
76
- reactRootView?.unmountReactApplication()
77
- reactRootView = null
78
- if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
79
- val reactInstanceMgr = ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager
80
-
81
- if (reactInstanceMgr.lifecycleState != LifecycleState.RESUMED) {
82
- reactInstanceMgr.onHostDestroy(activity)
83
- }
84
- }
85
- }
62
+ override fun onDestroy() {
63
+ super.onDestroy()
64
+ if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
65
+ val reactInstanceMgr = ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager
86
66
 
87
- override fun onRequestPermissionsResult(
88
- requestCode: Int,
89
- permissions: Array<String>,
90
- grantResults: IntArray
91
- ) {
92
- permissionsCallback = Callback {
93
- if (permissionListener != null) {
94
- permissionListener?.onRequestPermissionsResult(
95
- requestCode,
96
- permissions,
97
- grantResults
98
- )
99
-
100
- permissionListener = null
101
- }
102
- }
67
+ if (reactInstanceMgr.lifecycleState != LifecycleState.RESUMED) {
68
+ reactInstanceMgr.onHostDestroy(activity)
69
+ }
103
70
  }
71
+ }
72
+
73
+ override fun onRequestPermissionsResult(
74
+ requestCode: Int,
75
+ permissions: Array<String>,
76
+ grantResults: IntArray
77
+ ) {
78
+ permissionsCallback = Callback {
79
+ if (permissionListener != null) {
80
+ permissionListener?.onRequestPermissionsResult(
81
+ requestCode,
82
+ permissions,
83
+ grantResults
84
+ )
104
85
 
105
- override fun checkPermission(permission: String, pid: Int, uid: Int): Int {
106
- return requireActivity().checkPermission(permission, pid, uid)
86
+ permissionListener = null
87
+ }
107
88
  }
108
-
109
- @TargetApi(Build.VERSION_CODES.M)
110
- override fun checkSelfPermission(permission: String): Int {
111
- return requireActivity().checkSelfPermission(permission)
89
+ }
90
+
91
+ override fun checkPermission(permission: String, pid: Int, uid: Int): Int {
92
+ return requireActivity().checkPermission(permission, pid, uid)
93
+ }
94
+
95
+ @TargetApi(Build.VERSION_CODES.M)
96
+ override fun checkSelfPermission(permission: String): Int {
97
+ return requireActivity().checkSelfPermission(permission)
98
+ }
99
+
100
+ override fun requestPermissions(
101
+ permissions: Array<String>,
102
+ requestCode: Int,
103
+ listener: PermissionListener?
104
+ ) {
105
+ permissionListener = listener
106
+ this.requestPermissions(permissions, requestCode)
107
+ }
108
+
109
+ override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
110
+ var handled = false
111
+ if (ReactNativeBrownfield.shared.reactNativeHost.useDeveloperSupport && ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
112
+ if (keyCode == KeyEvent.KEYCODE_MENU) {
113
+ ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager.showDevOptionsDialog()
114
+ handled = true
115
+ }
116
+ val didDoubleTapR = activity?.currentFocus?.let {
117
+ Assertions.assertNotNull(doubleTapReloadRecognizer)
118
+ .didDoubleTapR(keyCode, it)
119
+ }
120
+ if (didDoubleTapR == true) {
121
+ ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager.devSupportManager.handleReloadJS()
122
+ handled = true
123
+ }
112
124
  }
113
-
114
- @TargetApi(Build.VERSION_CODES.M)
115
- override fun requestPermissions(
116
- permissions: Array<String>,
117
- requestCode: Int,
118
- listener: PermissionListener
119
- ) {
120
- permissionListener = listener
121
- this.requestPermissions(permissions, requestCode)
125
+ return handled
126
+ }
127
+
128
+ fun onBackPressed(backBtnHandler: DefaultHardwareBackBtnHandler) {
129
+ if (ReactNativeBrownfieldModule.shouldPopToNative) {
130
+ backBtnHandler.invokeDefaultOnBackPressed()
131
+ } else if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
132
+ ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager.onBackPressed()
122
133
  }
123
-
124
- fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
125
- var handled = false
126
- if (ReactNativeBrownfield.shared.reactNativeHost.useDeveloperSupport && ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
127
- if (keyCode == KeyEvent.KEYCODE_MENU) {
128
- ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager.showDevOptionsDialog()
129
- handled = true
130
- }
131
- val didDoubleTapR = activity?.currentFocus?.let {
132
- Assertions.assertNotNull(doubleTapReloadRecognizer)
133
- .didDoubleTapR(keyCode, it)
134
- }
135
- if (didDoubleTapR == true) {
136
- ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager.devSupportManager.handleReloadJS()
137
- handled = true
138
- }
139
- }
140
- return handled
134
+ }
135
+
136
+ companion object {
137
+ @JvmStatic
138
+ @JvmOverloads
139
+ fun createReactNativeFragment(
140
+ moduleName: String,
141
+ initialProps: Bundle? = null
142
+ ): ReactNativeFragment {
143
+ val fragment = ReactNativeFragment()
144
+ val args = Bundle()
145
+ args.putString(ARG_COMPONENT_NAME, moduleName)
146
+ if (initialProps != null) {
147
+ args.putBundle(ARG_LAUNCH_OPTIONS, initialProps)
148
+ }
149
+ fragment.arguments = args
150
+ return fragment
141
151
  }
142
152
 
143
- fun onBackPressed(backBtnHandler: DefaultHardwareBackBtnHandler) {
144
- if(ReactNativeBrownfieldModule.shouldPopToNative) {
145
- backBtnHandler.invokeDefaultOnBackPressed()
146
- } else if (ReactNativeBrownfield.shared.reactNativeHost.hasInstance()) {
147
- ReactNativeBrownfield.shared.reactNativeHost.reactInstanceManager.onBackPressed()
148
- }
153
+ @JvmStatic
154
+ fun createReactNativeFragment(
155
+ moduleName: String,
156
+ initialProps: HashMap<String, *>
157
+ ): ReactNativeFragment {
158
+ return createReactNativeFragment(moduleName, PropsBundle.fromHashMap(initialProps))
149
159
  }
150
160
 
151
- companion object {
152
- @JvmStatic
153
- @JvmOverloads
154
- fun createReactNativeFragment(moduleName: String, initialProps: Bundle? = null): ReactNativeFragment {
155
- val fragment = ReactNativeFragment()
156
- val args = Bundle()
157
- args.putString(MODULE_NAME, moduleName)
158
- if (initialProps != null) {
159
- args.putBundle(INITIAL_PROPS, initialProps)
160
- }
161
- fragment.arguments = args
162
- return fragment
163
- }
164
-
165
- @JvmStatic
166
- fun createReactNativeFragment(moduleName: String, initialProps: HashMap<String, *>): ReactNativeFragment {
167
- return createReactNativeFragment(moduleName, PropsBundle.fromHashMap(initialProps))
168
- }
169
-
170
- @JvmStatic
171
- fun createReactNativeFragment(moduleName: String, initialProps: WritableMap): ReactNativeFragment {
172
- return createReactNativeFragment(moduleName, initialProps.toHashMap())
173
- }
161
+ @JvmStatic
162
+ fun createReactNativeFragment(
163
+ moduleName: String,
164
+ initialProps: WritableMap
165
+ ): ReactNativeFragment {
166
+ return createReactNativeFragment(moduleName, initialProps.toHashMap())
174
167
  }
168
+ }
175
169
 
176
- }
170
+ }
@@ -0,0 +1,119 @@
1
+ import React
2
+ import React_RCTAppDelegate
3
+ import ReactAppDependencyProvider
4
+
5
+ @objc public class ReactNativeBrownfield: RCTDefaultReactNativeFactoryDelegate {
6
+ @objc public static let shared = ReactNativeBrownfield()
7
+ private var onBundleLoaded: (() -> Void)?
8
+
9
+ /**
10
+ * Path to JavaScript root.
11
+ * Default value: "index"
12
+ */
13
+ @objc public var entryFile: String = "index"
14
+ /**
15
+ * Path to bundle fallback resource.
16
+ * Default value: nil
17
+ */
18
+ @objc public var fallbackResource: String? = nil
19
+ /**
20
+ * Path to JavaScript bundle file.
21
+ * Default value: "main.jsbundle"
22
+ */
23
+ @objc public var bundlePath: String = "main.jsbundle"
24
+ /**
25
+ * React Native factory instance created when starting React Native.
26
+ * Default value: nil
27
+ */
28
+ @objc public var reactNativeFactory: RCTReactNativeFactory? = nil
29
+ /**
30
+ * Root view factory used to create React Native views.
31
+ */
32
+ @objc lazy public var rootViewFactory: RCTRootViewFactory? = {
33
+ return reactNativeFactory?.rootViewFactory
34
+ }()
35
+
36
+ /**
37
+ * Starts React Native with default parameters.
38
+ */
39
+ @objc public func startReactNative() {
40
+ startReactNative(onBundleLoaded: nil)
41
+ }
42
+
43
+ /**
44
+ * Starts React Native with optional callback when bundle is loaded.
45
+ *
46
+ * @param onBundleLoaded Optional callback invoked after JS bundle is fully loaded.
47
+ */
48
+ @objc public func startReactNative(onBundleLoaded: (() -> Void)?) {
49
+ startReactNative(onBundleLoaded: onBundleLoaded, launchOptions: nil)
50
+ }
51
+
52
+ /**
53
+ * Starts React Native with optional callback and launch options.
54
+ *
55
+ * @param onBundleLoaded Optional callback invoked after JS bundle is fully loaded.
56
+ * @param launchOptions Launch options, typically passed from AppDelegate.
57
+ */
58
+ @objc public func startReactNative(onBundleLoaded: (() -> Void)?, launchOptions: [AnyHashable: Any]?) {
59
+ guard reactNativeFactory == nil else { return }
60
+
61
+ self.dependencyProvider = RCTAppDependencyProvider()
62
+ self.reactNativeFactory = RCTReactNativeFactory(delegate: self)
63
+
64
+ if let onBundleLoaded {
65
+ self.onBundleLoaded = onBundleLoaded
66
+ if RCTIsNewArchEnabled() {
67
+ NotificationCenter.default.addObserver(
68
+ self,
69
+ selector: #selector(jsLoaded),
70
+ name: NSNotification.Name("RCTInstanceDidLoadBundle"),
71
+ object: nil
72
+ )
73
+ } else {
74
+ NotificationCenter.default.addObserver(
75
+ self,
76
+ selector: #selector(jsLoaded),
77
+ name: NSNotification.Name("RCTJavaScriptDidLoadNotification"),
78
+ object: nil
79
+ )
80
+ }
81
+ }
82
+ }
83
+
84
+ @objc private func jsLoaded(_ notification: Notification) {
85
+ onBundleLoaded?()
86
+ onBundleLoaded = nil
87
+ NotificationCenter.default.removeObserver(self)
88
+ }
89
+
90
+ // MARK: - RCTReactNativeFactoryDelegate Methods
91
+
92
+ @objc public override func sourceURL(for bridge: RCTBridge) -> URL? {
93
+ return bundleURL()
94
+ }
95
+
96
+ public override func bundleURL() -> URL? {
97
+ #if DEBUG
98
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: entryFile)
99
+ #else
100
+ let resourceURLComponents = bundlePath.components(separatedBy: ".")
101
+ let withoutLast = resourceURLComponents[..<(resourceURLComponents.count - 1)]
102
+ let resourceName = withoutLast.joined()
103
+ let fileExtension = resourceURLComponents.last ?? ""
104
+
105
+ return Bundle.main.url(forResource: resourceName, withExtension: fileExtension)
106
+ #endif
107
+ }
108
+ }
109
+
110
+ extension Notification.Name {
111
+ /**
112
+ * Notification sent when React Native wants to navigate back to native screen.
113
+ */
114
+ public static let popToNative = Notification.Name("PopToNativeNotification")
115
+ /**
116
+ * Notification sent to enable/disable the pop gesture recognizer.
117
+ */
118
+ public static let togglePopGestureRecognizer = Notification.Name("TogglePopGestureRecognizerNotification")
119
+ }
@@ -1,24 +1,21 @@
1
1
  #import "ReactNativeBrownfieldModule.h"
2
- #import "ReactNativeBrownfieldNotifications.h"
2
+
3
+ #if __has_include("ReactNativeBrownfield/ReactNativeBrownfield-Swift.h")
4
+ #import "ReactNativeBrownfield/ReactNativeBrownfield-Swift.h"
5
+ #else
6
+ #import "ReactNativeBrownfield-Swift.h"
7
+ #endif
3
8
 
4
9
  @implementation ReactNativeBrownfieldModule
5
10
 
6
11
  RCT_EXPORT_MODULE(ReactNativeBrownfield);
7
12
 
8
13
  RCT_EXPORT_METHOD(setPopGestureRecognizerEnabled:(BOOL)enabled) {
9
- NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@(enabled) forKey:@"enabled"];
10
-
11
- [[NSNotificationCenter defaultCenter]
12
- postNotificationName:TogglePopGestureRecognizerNotification
13
- object:nil userInfo:userInfo];
14
+ [ReactNativeBrownfieldModuleImpl setPopGestureRecognizerEnabled:enabled];
14
15
  }
15
16
 
16
17
  RCT_EXPORT_METHOD(popToNative:(BOOL)animated) {
17
- NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@(animated) forKey:@"animated"];
18
-
19
- [[NSNotificationCenter defaultCenter]
20
- postNotificationName:PopToNativeNotification
21
- object:nil userInfo:userInfo];
18
+ [ReactNativeBrownfieldModuleImpl popToNativeWithAnimated:animated];
22
19
  }
23
20
 
24
21
  @end
@@ -0,0 +1,18 @@
1
+ import React
2
+
3
+ @objcMembers
4
+ public class ReactNativeBrownfieldModuleImpl: NSObject {
5
+ static public func setPopGestureRecognizerEnabled(_ enabled: Bool) {
6
+ let userInfo = ["enabled": enabled]
7
+ DispatchQueue.main.async {
8
+ NotificationCenter.default.post(name: Notification.Name.togglePopGestureRecognizer, object: nil, userInfo: userInfo)
9
+ }
10
+ }
11
+
12
+ static public func popToNative(animated: Bool) {
13
+ let userInfo = ["animated": animated]
14
+ DispatchQueue.main.async {
15
+ NotificationCenter.default.post(name: Notification.Name.popToNative, object: nil, userInfo: userInfo)
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,42 @@
1
+ import SwiftUI
2
+
3
+ /**
4
+ A UIViewControllerRepresentable that bridges ReactNativeViewController to SwiftUI.
5
+ */
6
+ struct ReactNativeViewRepresentable: UIViewControllerRepresentable {
7
+ var moduleName: String
8
+ var initialProperties: [String: Any] = [:]
9
+
10
+ func makeUIViewController(context: Context) -> UIViewController {
11
+ return ReactNativeViewController(moduleName: moduleName)
12
+ }
13
+
14
+ func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
15
+ }
16
+
17
+ /**
18
+ Exposes React Native view to SwiftUI.
19
+ Supports pop to native when using SwiftUI's NavigationView or NavigationStack.
20
+ */
21
+ public struct ReactNativeView: View {
22
+ @Environment(\.dismiss) var dismiss
23
+ var moduleName: String
24
+ var initialProperties: [String: Any] = [:]
25
+
26
+ public init(moduleName: String, initialProperties: [String : Any] = [:]) {
27
+ self.moduleName = moduleName
28
+ self.initialProperties = initialProperties
29
+ }
30
+
31
+ public var body: some View {
32
+ ReactNativeViewRepresentable(
33
+ moduleName: moduleName,
34
+ initialProperties: initialProperties
35
+ )
36
+ .ignoresSafeArea(.all)
37
+ .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name.popToNative))
38
+ { notification in
39
+ dismiss()
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,66 @@
1
+ import UIKit
2
+ import React
3
+
4
+ @objc public class ReactNativeViewController: UIViewController {
5
+ private var moduleName: String
6
+ private var initialProperties: [String: Any]?
7
+
8
+ @objc public init(moduleName: String, initialProperties: [String: Any]? = nil) {
9
+ self.moduleName = moduleName
10
+ self.initialProperties = initialProperties
11
+ super.init(nibName: nil, bundle: nil)
12
+ }
13
+
14
+ required init?(coder: NSCoder) {
15
+ fatalError("init(coder:) has not been implemented")
16
+ }
17
+
18
+ public override func viewDidLoad() {
19
+ super.viewDidLoad()
20
+
21
+ guard let factory = ReactNativeBrownfield.shared.rootViewFactory else {
22
+ print("Error: You need to start React Native in order to use ReactNativeViewController, make sure to run BridgeManager.shared.startReactNative() before instantiating it.")
23
+ return
24
+ }
25
+
26
+ if !moduleName.isEmpty {
27
+ view = factory.view(withModuleName: moduleName, initialProperties: initialProperties)
28
+
29
+ NotificationCenter.default.addObserver(
30
+ self,
31
+ selector: #selector(togglePopGestureRecognizer(_:)),
32
+ name: NSNotification.Name.togglePopGestureRecognizer,
33
+ object: nil
34
+ )
35
+
36
+ NotificationCenter.default.addObserver(
37
+ self,
38
+ selector: #selector(popToNative(_:)),
39
+ name: NSNotification.Name.popToNative,
40
+ object: nil
41
+ )
42
+ }
43
+ }
44
+
45
+ deinit {
46
+ NotificationCenter.default.removeObserver(self)
47
+ }
48
+
49
+ @objc private func togglePopGestureRecognizer(_ notification: Notification) {
50
+ guard let userInfo = notification.userInfo,
51
+ let enabled = userInfo["enabled"] as? Bool else { return }
52
+
53
+ DispatchQueue.main.async { [weak self] in
54
+ self?.navigationController?.interactivePopGestureRecognizer?.isEnabled = enabled
55
+ }
56
+ }
57
+
58
+ @objc private func popToNative(_ notification: Notification) {
59
+ guard let userInfo = notification.userInfo,
60
+ let animated = userInfo["animated"] as? Bool else { return }
61
+
62
+ DispatchQueue.main.async { [weak self] in
63
+ self?.navigationController?.popViewController(animated: animated)
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _reactNative = require("react-native");
8
+ var _default = exports.default = _reactNative.TurboModuleRegistry.getEnforcing('ReactNativeBrownfield');
9
+ //# sourceMappingURL=RNBrownfieldSpec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["RNBrownfieldSpec.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAqBpCC,gCAAmB,CAACC,YAAY,CAAO,uBAAuB,CAAC","ignoreList":[]}
@@ -5,21 +5,23 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _reactNative = require("react-native");
8
+ var _RNBrownfieldSpec = _interopRequireDefault(require("./RNBrownfieldSpec"));
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
10
  const ReactNativeBrownfield = {
9
11
  popToNative: animated => {
10
12
  if (_reactNative.Platform.OS === 'ios') {
11
- _reactNative.NativeModules.ReactNativeBrownfield.popToNative(animated);
13
+ _RNBrownfieldSpec.default.popToNative(animated);
12
14
  } else if (_reactNative.Platform.OS === 'android') {
13
- _reactNative.NativeModules.ReactNativeBrownfield.popToNative();
15
+ _RNBrownfieldSpec.default.popToNative();
14
16
  } else {
15
17
  console.warn('Not implemented: popToNative');
16
18
  }
17
19
  },
18
20
  setNativeBackGestureAndButtonEnabled: enabled => {
19
21
  if (_reactNative.Platform.OS === 'ios') {
20
- _reactNative.NativeModules.ReactNativeBrownfield.setPopGestureRecognizerEnabled(enabled);
22
+ _RNBrownfieldSpec.default.setPopGestureRecognizerEnabled(enabled);
21
23
  } else if (_reactNative.Platform.OS === 'android') {
22
- _reactNative.NativeModules.ReactNativeBrownfield.setHardwareBackButtonEnabled(enabled);
24
+ _RNBrownfieldSpec.default.setHardwareBackButtonEnabled(enabled);
23
25
  } else {
24
26
  console.warn('Not implemented: setNativeGesturesAndButtonsEnabled');
25
27
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","ReactNativeBrownfield","popToNative","animated","Platform","OS","NativeModules","console","warn","setNativeBackGestureAndButtonEnabled","enabled","setPopGestureRecognizerEnabled","setHardwareBackButtonEnabled","_default","exports","default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,qBAAqB,GAAG;EAC5BC,WAAW,EAAGC,QAAkB,IAAW;IACzC,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzBC,0BAAa,CAACL,qBAAqB,CAACC,WAAW,CAACC,QAAQ,CAAC;IAC3D,CAAC,MAAM,IAAIC,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;MACpCC,0BAAa,CAACL,qBAAqB,CAACC,WAAW,CAAC,CAAC;IACnD,CAAC,MAAM;MACLK,OAAO,CAACC,IAAI,CAAC,8BAA8B,CAAC;IAC9C;EACF,CAAC;EAEDC,oCAAoC,EAAGC,OAAgB,IAAW;IAChE,IAAIN,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzBC,0BAAa,CAACL,qBAAqB,CAACU,8BAA8B,CAChED,OACF,CAAC;IACH,CAAC,MAAM,IAAIN,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;MACpCC,0BAAa,CAACL,qBAAqB,CAACW,4BAA4B,CAACF,OAAO,CAAC;IAC3E,CAAC,MAAM;MACLH,OAAO,CAACC,IAAI,CAAC,qDAAqD,CAAC;IACrE;EACF;AACF,CAAC;AAAC,IAAAK,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEad,qBAAqB","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_RNBrownfieldSpec","_interopRequireDefault","e","__esModule","default","ReactNativeBrownfield","popToNative","animated","Platform","OS","ReactNativeBrownfieldModule","console","warn","setNativeBackGestureAndButtonEnabled","enabled","setPopGestureRecognizerEnabled","setHardwareBackButtonEnabled","_default","exports"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,iBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAA6D,SAAAE,uBAAAC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE7D,MAAMG,qBAAqB,GAAG;EAC5BC,WAAW,EAAGC,QAAkB,IAAW;IACzC,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzBC,yBAA2B,CAACJ,WAAW,CAACC,QAAQ,CAAC;IACnD,CAAC,MAAM,IAAIC,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;MACpCC,yBAA2B,CAACJ,WAAW,CAAC,CAAC;IAC3C,CAAC,MAAM;MACLK,OAAO,CAACC,IAAI,CAAC,8BAA8B,CAAC;IAC9C;EACF,CAAC;EAEDC,oCAAoC,EAAGC,OAAgB,IAAW;IAChE,IAAIN,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzBC,yBAA2B,CAACK,8BAA8B,CAACD,OAAO,CAAC;IACrE,CAAC,MAAM,IAAIN,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;MACpCC,yBAA2B,CAACM,4BAA4B,CAACF,OAAO,CAAC;IACnE,CAAC,MAAM;MACLH,OAAO,CAACC,IAAI,CAAC,qDAAqD,CAAC;IACrE;EACF;AACF,CAAC;AAAC,IAAAK,QAAA,GAAAC,OAAA,CAAAd,OAAA,GAEaC,qBAAqB","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+ export default TurboModuleRegistry.getEnforcing('ReactNativeBrownfield');
5
+ //# sourceMappingURL=RNBrownfieldSpec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["RNBrownfieldSpec.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AAqBlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,uBAAuB,CAAC","ignoreList":[]}