@@ -2,180 +2,32 @@ package com.mendix.mendixnative.fragment
22
33import android.content.Intent
44import android.os.Bundle
5- import android.view.KeyEvent
65import android.view.LayoutInflater
76import android.view.View
87import android.view.ViewGroup
9- import androidx.fragment.app.Fragment
10- import com.facebook.react.ReactApplication
11- import com.facebook.react.ReactDelegate
12- import com.facebook.react.ReactHost
13- import com.facebook.react.modules.core.PermissionAwareActivity
14- import com.facebook.react.modules.core.PermissionListener
15- import com.mendix.mendixnative.react.CopiedFrom
16-
178
189/* *
19- * Fragment for creating a React View. This allows the developer to "embed" a React Application
20- * inside native components such as a Drawer, ViewPager, etc.
10+ * Mendix's [com.facebook.react.ReactFragment] extension.
11+ *
12+ * Adds two behaviors on top of upstream that aren't available in RN itself:
13+ * - tapjacking protection on the react root view
14+ * - always forwarding [onActivityResult] to the React instance, since Mendix embeds React
15+ * fragments inside native navigation (Drawer/ViewPager/Nav) where the host activity's result
16+ * is meant for the React app.
2117 */
22- @CopiedFrom(com.facebook.react.ReactFragment ::class )
23- open class ReactFragment : Fragment (), PermissionAwareActivity {
24- private var mReactDelegate: ReactDelegate ? = null
25- private var mPermissionListener: PermissionListener ? = null
26-
27- // region Lifecycle
28- override fun onCreate (savedInstanceState : Bundle ? ) {
29- super .onCreate(savedInstanceState)
30- var mainComponentName: String? = null
31- var launchOptions: Bundle ? = null
32- if (arguments != null ) {
33- mainComponentName = requireArguments().getString(ARG_COMPONENT_NAME )
34- launchOptions = requireArguments().getBundle(ARG_LAUNCH_OPTIONS )
35- }
36- checkNotNull(mainComponentName) { " Cannot loadApp if component name is null" }
37- mReactDelegate = activity?.let { ReactDelegate (it, reactHost!! , mainComponentName, launchOptions) }
38- }
39-
40- /* *
41- * Get the [ReactHost] used by this app. By default, assumes [ ][Activity.getApplication] is an
42- * instance of [ReactApplication] and calls [ ][ReactApplication.getReactHost]. Override this
43- * method if your application class does not implement `ReactApplication` or you simply have a
44- * different mechanism for storing a `ReactHost`, e.g. as a static field somewhere.
45- */
46- protected val reactHost: ReactHost ?
47- get() = (requireActivity().application as ReactApplication ).reactHost
18+ open class ReactFragment : com.facebook.react.ReactFragment () {
4819
4920 override fun onCreateView (
5021 inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ?
5122 ): View ? {
52- mReactDelegate!! .loadApp()
53- // Adds tapjacking protection to the rootview
54- mReactDelegate!! .reactRootView?.filterTouchesWhenObscured = true
55- return mReactDelegate!! .reactRootView
56- }
57-
58- override fun onResume () {
59- super .onResume()
60- mReactDelegate!! .onHostResume()
61- }
62-
63- override fun onPause () {
64- super .onPause()
65- mReactDelegate!! .onHostPause()
23+ val view = super .onCreateView(inflater, container, savedInstanceState)
24+ reactDelegate.reactRootView?.filterTouchesWhenObscured = true
25+ return view
6626 }
6727
68- override fun onDestroy () {
69- super .onDestroy()
70- mReactDelegate!! .onHostDestroy()
71- }
72-
73- // endregion
28+ @Suppress(" DEPRECATION" )
7429 override fun onActivityResult (requestCode : Int , resultCode : Int , data : Intent ? ) {
7530 super .onActivityResult(requestCode, resultCode, data)
76- mReactDelegate!! .onActivityResult(requestCode, resultCode, data, true )
77- }
78-
79- /* *
80- * Helper to forward hardware back presses to our React Native Host
81- *
82- *
83- * This must be called via a forward from your host Activity
84- */
85- fun onBackPressed (): Boolean {
86- return mReactDelegate!! .onBackPressed()
87- }
88-
89- /* *
90- * Helper to forward onKeyUp commands from our host Activity. This allows ReactFragment to handle
91- * double tap reloads and dev menus
92- *
93- *
94- * This must be called via a forward from your host Activity
95- *
96- * @param keyCode keyCode
97- * @param event event
98- * @return true if we handled onKeyUp
99- */
100- open fun onKeyUp (keyCode : Int , event : KeyEvent ? ): Boolean {
101- return mReactDelegate!! .shouldShowDevMenuOrReload(keyCode, event)
102- }
103-
104- override fun onRequestPermissionsResult (
105- requestCode : Int , permissions : Array <String >, grantResults : IntArray
106- ) {
107- super .onRequestPermissionsResult(requestCode, permissions, grantResults)
108- if (mPermissionListener != null
109- && mPermissionListener!! .onRequestPermissionsResult(requestCode, permissions, grantResults)
110- ) {
111- mPermissionListener = null
112- }
113- }
114-
115- override fun checkPermission (permission : String , pid : Int , uid : Int ): Int {
116- return requireActivity().checkPermission(permission, pid, uid)
117- }
118-
119- override fun checkSelfPermission (permission : String ): Int {
120- return requireActivity().checkSelfPermission(permission)
121- }
122-
123- override fun requestPermissions (
124- permissions : Array <String >,
125- requestCode : Int ,
126- listener : PermissionListener ?
127- ) {
128- mPermissionListener = listener
129- requestPermissions(permissions, requestCode)
130- }
131-
132- /* * Builder class to help instantiate a ReactFragment */
133- class Builder {
134- var mComponentName: String? = null
135- var mLaunchOptions: Bundle ? = null
136-
137- /* *
138- * Set the Component name for our React Native instance.
139- *
140- * @param componentName The name of the component
141- * @return Builder
142- */
143- fun setComponentName (componentName : String? ): Builder {
144- mComponentName = componentName
145- return this
146- }
147-
148- /* *
149- * Set the Launch Options for our React Native instance.
150- *
151- * @param launchOptions launchOptions
152- * @return Builder
153- */
154- fun setLaunchOptions (launchOptions : Bundle ? ): Builder {
155- mLaunchOptions = launchOptions
156- return this
157- }
158-
159- fun build (): ReactFragment {
160- return newInstance(mComponentName, mLaunchOptions)
161- }
162- }
163-
164- companion object {
165- private const val ARG_COMPONENT_NAME = " arg_component_name"
166- private const val ARG_LAUNCH_OPTIONS = " arg_launch_options"
167-
168- /* *
169- * @param componentName The name of the react native component
170- * @return A new instance of fragment ReactFragment.
171- */
172- private fun newInstance (componentName : String? , launchOptions : Bundle ? ): ReactFragment {
173- val fragment = ReactFragment ()
174- val args = Bundle ()
175- args.putString(ARG_COMPONENT_NAME , componentName)
176- args.putBundle(ARG_LAUNCH_OPTIONS , launchOptions)
177- fragment.arguments = args
178- return fragment
179- }
31+ reactDelegate.onActivityResult(requestCode, resultCode, data, true )
18032 }
18133}
0 commit comments