diff --git a/lib/android/app/build.gradle b/lib/android/app/build.gradle index cbd41d9c0fc..5abc5ac36bc 100644 --- a/lib/android/app/build.gradle +++ b/lib/android/app/build.gradle @@ -106,6 +106,10 @@ android { dimension "RNN.reactNativeVersion" buildConfigField("int", "REACT_NATVE_VERSION_MINOR", "63") } + reactNative68 { + dimension "RNN.reactNativeVersion" + buildConfigField("int", "REACT_NATVE_VERSION_MINOR", "68") + } } def flavor = resolveFlavor() @@ -122,7 +126,9 @@ String resolveFlavor() { Integer reactNativeMinorComponent = reactNativeVersionComponents[1].toInteger() Integer reactNativePatchComponent = reactNativeVersionComponents[2].toInteger() - if (reactNativeMinorComponent >= 63) { + if (reactNativeMinorComponent >= 68) { + return "reactNative68" + } else if (reactNativeMinorComponent >= 63) { return "reactNative63" } else if (reactNativeMinorComponent >= 62) { return "reactNative62" diff --git a/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative51/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt similarity index 100% rename from lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt rename to lib/android/app/src/reactNative51/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt diff --git a/lib/android/app/src/reactNative55/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative55/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..da7d5b1b4f9 --- /dev/null +++ b/lib/android/app/src/reactNative55/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,81 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative56/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative56/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..da7d5b1b4f9 --- /dev/null +++ b/lib/android/app/src/reactNative56/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,81 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..da7d5b1b4f9 --- /dev/null +++ b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,81 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative57_5/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative57_5/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..da7d5b1b4f9 --- /dev/null +++ b/lib/android/app/src/reactNative57_5/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,81 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative60/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative60/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..da7d5b1b4f9 --- /dev/null +++ b/lib/android/app/src/reactNative60/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,81 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative62/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative62/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..da7d5b1b4f9 --- /dev/null +++ b/lib/android/app/src/reactNative62/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,81 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative63/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative63/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..da7d5b1b4f9 --- /dev/null +++ b/lib/android/app/src/reactNative63/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,81 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/options/parsers/ColorParser.kt b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/options/parsers/ColorParser.kt new file mode 100644 index 00000000000..857af348911 --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/options/parsers/ColorParser.kt @@ -0,0 +1,38 @@ +package com.reactnativenavigation.options.parsers + +import android.content.Context +import com.facebook.react.bridge.ColorPropConverter +import com.reactnativenavigation.options.params.Colour +import com.reactnativenavigation.options.params.DontApplyColour +import com.reactnativenavigation.options.params.NullColor +import com.reactnativenavigation.options.params.ReactPlatformColor +import org.json.JSONObject + +object ColorParser { + private const val KEY_RESOURCE_PATHS = "resource_paths" + private const val VAL_NO_COLOR = "NoColor" + + @JvmStatic + fun parse(context: Context?, json: JSONObject, colorName: String?): Colour { + if (json.has(KEY_RESOURCE_PATHS)) { + return ReactPlatformColor(JSONParser.convert(json)) + } + return when (val color = json.opt(colorName)) { + null, VAL_NO_COLOR -> { + DontApplyColour() + } + is Int -> { + Colour(json.optInt(colorName)) + } + is JSONObject -> { + ColorPropConverter.getColor(color, context)?.let { + Colour(it) + } ?: NullColor() + } + else -> { + NullColor() + } + } + + } +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/DevBundleDownloadListenerAdapter.java b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/DevBundleDownloadListenerAdapter.java new file mode 100644 index 00000000000..d5ad33c75c5 --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/DevBundleDownloadListenerAdapter.java @@ -0,0 +1,22 @@ +package com.reactnativenavigation.react; + +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; + +import javax.annotation.Nullable; + +public class DevBundleDownloadListenerAdapter implements DevBundleDownloadListener, NavigationDevBundleDownloadListener { + @Override + public void onSuccess() { + onSuccess(); + } + + @Override + public void onProgress(@Nullable String status, @Nullable Integer done, @Nullable Integer total) { + + } + + @Override + public void onFailure(Exception cause) { + + } +} diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/JsDevReloadHandlerFacade.java b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/JsDevReloadHandlerFacade.java new file mode 100644 index 00000000000..feb40fb680e --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/JsDevReloadHandlerFacade.java @@ -0,0 +1,22 @@ +package com.reactnativenavigation.react; + +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; + +import javax.annotation.Nullable; + +public class JsDevReloadHandlerFacade implements DevBundleDownloadListener, NavigationDevBundleDownloadListener { + @Override + public void onSuccess() { + onSuccess(); + } + + @Override + public void onProgress(@Nullable String status, @Nullable Integer done, @Nullable Integer total) { + + } + + @Override + public void onFailure(Exception cause) { + + } +} diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/NavigationReactNativeHost.java b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/NavigationReactNativeHost.java new file mode 100644 index 00000000000..9b1bd158f3a --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/NavigationReactNativeHost.java @@ -0,0 +1,66 @@ +package com.reactnativenavigation.react; + +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactInstanceManagerBuilder; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.common.LifecycleState; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.reactnativenavigation.NavigationApplication; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public abstract class NavigationReactNativeHost extends ReactNativeHost implements BundleDownloadListenerProvider { + + private @Nullable NavigationDevBundleDownloadListener bundleListener; + private final DevBundleDownloadListener bundleListenerMediator = new DevBundleDownloadListenerAdapter() { + @Override + public void onSuccess() { + if (bundleListener != null) { + bundleListener.onSuccess(); + } + } + }; + + public NavigationReactNativeHost(NavigationApplication application) { + super(application); + } + + @Override + public void setBundleLoaderListener(NavigationDevBundleDownloadListener listener) { + bundleListener = listener; + } + + protected ReactInstanceManager createReactInstanceManager() { + ReactInstanceManagerBuilder builder = ReactInstanceManager.builder() + .setApplication(getApplication()) + .setJSMainModulePath(getJSMainModuleName()) + .setUseDeveloperSupport(getUseDeveloperSupport()) + .setRedBoxHandler(getRedBoxHandler()) + .setJavaScriptExecutorFactory(getJavaScriptExecutorFactory()) + .setUIImplementationProvider(getUIImplementationProvider()) + .setInitialLifecycleState(LifecycleState.BEFORE_CREATE) + .setJSIModulesPackage(getJSIModulePackage()) + .setDevBundleDownloadListener(getDevBundleDownloadListener()); + + for (ReactPackage reactPackage : getPackages()) { + builder.addPackage(reactPackage); + } + + String jsBundleFile = getJSBundleFile(); + if (jsBundleFile != null) { + builder.setJSBundleFile(jsBundleFile); + } else { + builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName())); + } + return builder.build(); + } + + @SuppressWarnings("WeakerAccess") + @NonNull + protected DevBundleDownloadListener getDevBundleDownloadListener() { + return bundleListenerMediator; + } +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReactGateway.java b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReactGateway.java new file mode 100644 index 00000000000..035ec31b2c5 --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReactGateway.java @@ -0,0 +1,72 @@ +package com.reactnativenavigation.react; + +import android.app.Activity; +import android.content.Intent; +import android.content.res.Configuration; + +import com.facebook.react.ReactNativeHost; +import com.reactnativenavigation.NavigationActivity; + +import androidx.annotation.NonNull; + +public class ReactGateway { + + private final ReactNativeHost host; + private final NavigationReactInitializer initializer; + private final JsDevReloadHandler jsDevReloadHandler; + + public ReactGateway(ReactNativeHost host) { + this.host = host; + initializer = new NavigationReactInitializer(host.getReactInstanceManager(), host.getUseDeveloperSupport()); + jsDevReloadHandler = new JsDevReloadHandler(host.getReactInstanceManager().getDevSupportManager()); + if (host instanceof BundleDownloadListenerProvider) { + ((BundleDownloadListenerProvider) host).setBundleLoaderListener(jsDevReloadHandler); + } + } + + public void onActivityCreated(NavigationActivity activity) { + initializer.onActivityCreated(); + jsDevReloadHandler.setReloadListener(activity); + } + + public void onActivityResumed(NavigationActivity activity) { + initializer.onActivityResumed(activity); + jsDevReloadHandler.onActivityResumed(activity); + } + + public boolean onNewIntent(Intent intent) { + if (host.hasInstance()) { + host.getReactInstanceManager().onNewIntent(intent); + return true; + } + return false; + } + + public void onConfigurationChanged(NavigationActivity activity, @NonNull Configuration newConfig) { + if (host.hasInstance()) { + host.getReactInstanceManager().onConfigurationChanged(activity, newConfig); + } + } + + public void onActivityPaused(NavigationActivity activity) { + initializer.onActivityPaused(activity); + jsDevReloadHandler.onActivityPaused(activity); + } + + public void onActivityDestroyed(NavigationActivity activity) { + jsDevReloadHandler.removeReloadListener(activity); + initializer.onActivityDestroyed(activity); + } + + public boolean onKeyUp(Activity activity, int keyCode) { + return jsDevReloadHandler.onKeyUp(activity, keyCode); + } + + public void onBackPressed() { + host.getReactInstanceManager().onBackPressed(); + } + + public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { + host.getReactInstanceManager().onActivityResult(activity, requestCode, resultCode, data); + } +} diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReloadHandlerFacade.java b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReloadHandlerFacade.java new file mode 100644 index 00000000000..f30f66b91b6 --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReloadHandlerFacade.java @@ -0,0 +1,22 @@ +package com.reactnativenavigation.react; + +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; + +import javax.annotation.Nullable; + +public abstract class ReloadHandlerFacade implements DevBundleDownloadListener { + @Override + public void onSuccess() { + + } + + @Override + public void onProgress(@Nullable String status, @Nullable Integer done, @Nullable Integer total) { + + } + + @Override + public void onFailure(Exception cause) { + + } +} diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt new file mode 100644 index 00000000000..ea8516fee7f --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt @@ -0,0 +1,87 @@ +package com.reactnativenavigation.react.modal + +import android.content.Context +import android.view.MotionEvent +import android.view.View +import com.facebook.react.bridge.* +import com.facebook.react.uimanager.* +import com.facebook.react.uimanager.events.EventDispatcher +import com.facebook.react.views.view.ReactViewGroup + + +class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{ + private var hasAdjustedSize = false + private var viewWidth = 0 + private var viewHeight = 0 + private val mJSTouchDispatcher = JSTouchDispatcher(this) + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + viewWidth = w + viewHeight = h + this.updateFirstChildView() + } + private fun updateFirstChildView() { + if (this.childCount > 0) { + hasAdjustedSize = false + val viewTag = getChildAt(0).id + val reactContext: ReactContext = this.getReactContext() + reactContext.runOnNativeModulesQueueThread(object : GuardedRunnable(reactContext) { + override fun runGuarded() { + val uiManager = this@ModalContentLayout.getReactContext().getNativeModule( + UIManagerModule::class.java + ) as UIManagerModule + uiManager.updateNodeSize( + viewTag, + this@ModalContentLayout.viewWidth, + this@ModalContentLayout.viewHeight + ) + } + }) + } else { + hasAdjustedSize = true + } + } + + override fun addView(child: View?, index: Int, params: LayoutParams?) { + super.addView(child, index, params) + if (hasAdjustedSize) { + updateFirstChildView() + } + } + override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent?) { + mJSTouchDispatcher.onChildEndedNativeGesture(androidEvent, this.getEventDispatcher()) + } + override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} + private fun getEventDispatcher(): EventDispatcher? { + val reactContext: ReactContext = this.getReactContext() + return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher + } + + + override fun handleException(t: Throwable?) { + getReactContext().handleException(RuntimeException(t)) + } + + private fun getReactContext(): ReactContext { + return this.context as ReactContext + } + + override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + return super.onInterceptTouchEvent(event) + } + + override fun onTouchEvent(event: MotionEvent?): Boolean { + mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) + super.onTouchEvent(event) + return true + } + +} \ No newline at end of file diff --git a/lib/android/app/src/reactNative68/java/com/reactnativenavigation/viewcontrollers/viewcontroller/YellowBoxHelper.java b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/viewcontrollers/viewcontroller/YellowBoxHelper.java new file mode 100644 index 00000000000..3cd7dae3763 --- /dev/null +++ b/lib/android/app/src/reactNative68/java/com/reactnativenavigation/viewcontrollers/viewcontroller/YellowBoxHelper.java @@ -0,0 +1,12 @@ +package com.reactnativenavigation.viewcontrollers.viewcontroller; + +import android.view.View; +import android.view.ViewGroup; + +public class YellowBoxHelper { + boolean isYellowBox(View parent, View child) { + return parent instanceof ViewGroup && + child instanceof ViewGroup && + ((ViewGroup) parent).indexOfChild(child) >= 1; + } +}