Revert "Modal bugfix for statusBarTranslucent prop and Android 15 (#46359)"

This reverts commit 4475e01570.
This commit is contained in:
Riccardo Cipolleschi
2025-02-06 11:22:32 +00:00
parent 25e76a2717
commit 43bbd476c1
5 changed files with 92 additions and 20 deletions
@@ -6506,10 +6506,13 @@ public final class com/facebook/react/views/modal/ReactModalHostManager : com/fa
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
public synthetic fun addEventEmitters (Lcom/facebook/react/uimanager/ThemedReactContext;Landroid/view/View;)V
public fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/LayoutShadowNode;
public synthetic fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/ReactShadowNode;
public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
public fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate;
public fun getExportedCustomDirectEventTypeConstants ()Ljava/util/Map;
public fun getName ()Ljava/lang/String;
public fun getShadowNodeClass ()Ljava/lang/Class;
public synthetic fun onAfterUpdateTransaction (Landroid/view/View;)V
public synthetic fun onDropViewInstance (Landroid/view/View;)V
public fun onDropViewInstance (Lcom/facebook/react/views/modal/ReactModalHostView;)V
@@ -6576,10 +6579,12 @@ public final class com/facebook/react/views/modal/ReactModalHostView : android/v
public final fun setStatusBarTranslucent (Z)V
public final fun setTransparent (Z)V
public final fun showOrUpdate ()V
public final fun updateState (II)V
}
public final class com/facebook/react/views/modal/ReactModalHostView$DialogRootViewGroup : com/facebook/react/views/view/ReactViewGroup, com/facebook/react/uimanager/RootView {
public fun <init> (Lcom/facebook/react/views/modal/ReactModalHostView;Landroid/content/Context;)V
public fun addView (Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
public fun handleException (Ljava/lang/Throwable;)V
public fun onChildEndedNativeGesture (Landroid/view/View;Landroid/view/MotionEvent;)V
public fun onChildStartedNativeGesture (Landroid/view/View;Landroid/view/MotionEvent;)V
@@ -8050,3 +8055,4 @@ public final class com/facebook/react/views/view/ViewGroupClickEvent : com/faceb
public fun canCoalesce ()Z
public fun getEventName ()Ljava/lang/String;
}
@@ -13,7 +13,6 @@ import android.graphics.Point
import android.view.WindowManager
/** Helper class for Modals. */
@Deprecated("This class is no longer used and will be removed soon.")
internal object ModalHostHelper {
private val MIN_POINT = Point()
private val MAX_POINT = Point()
@@ -9,6 +9,7 @@ package com.facebook.react.views.modal
import com.facebook.react.uimanager.LayoutShadowNode
import com.facebook.react.uimanager.ReactShadowNodeImpl
import com.facebook.react.views.modal.ModalHostHelper.getModalHostSize
/**
* We implement the Modal by using an Android Dialog. That will fill the entire window of the
@@ -18,7 +19,6 @@ import com.facebook.react.uimanager.ReactShadowNodeImpl
* to be the window size. This will then cause the children of the Modal to layout as if they can
* fill the window.
*/
@Deprecated("This class is no longer used and will be removed soon.")
internal class ModalHostShadowNode : LayoutShadowNode() {
/**
* We need to set the styleWidth and styleHeight of the one child (represented by the
@@ -27,5 +27,8 @@ internal class ModalHostShadowNode : LayoutShadowNode() {
*/
override fun addChildAt(child: ReactShadowNodeImpl, i: Int) {
super.addChildAt(child, i)
val modalSize = getModalHostSize(themedContext)
child.setStyleWidth(modalSize.x.toFloat())
child.setStyleHeight(modalSize.y.toFloat())
}
}
@@ -11,6 +11,7 @@ import android.content.DialogInterface.OnShowListener
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.common.MapBuilder
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.LayoutShadowNode
import com.facebook.react.uimanager.ReactStylesDiffMap
import com.facebook.react.uimanager.StateWrapper
import com.facebook.react.uimanager.ThemedReactContext
@@ -20,6 +21,7 @@ import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.ModalHostViewManagerDelegate
import com.facebook.react.viewmanagers.ModalHostViewManagerInterface
import com.facebook.react.views.modal.ModalHostHelper.getModalHostSize
import com.facebook.react.views.modal.ReactModalHostView.OnRequestCloseListener
/** View manager for [ReactModalHostView] components. */
@@ -33,6 +35,11 @@ public class ReactModalHostManager :
protected override fun createViewInstance(reactContext: ThemedReactContext): ReactModalHostView =
ReactModalHostView(reactContext)
public override fun createShadowNodeInstance(): LayoutShadowNode = ModalHostShadowNode()
public override fun getShadowNodeClass(): Class<out LayoutShadowNode> =
ModalHostShadowNode::class.java
public override fun onDropViewInstance(view: ReactModalHostView) {
super.onDropViewInstance(view)
view.onDropInstance()
@@ -129,6 +136,8 @@ public class ReactModalHostManager :
stateWrapper: StateWrapper
): Any? {
view.stateWrapper = stateWrapper
val modalSize = getModalHostSize(view.context)
view.updateState(modalSize.x, modalSize.y)
return null
}
@@ -30,6 +30,7 @@ import com.facebook.react.R
import com.facebook.react.bridge.GuardedRunnable
import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.WritableNativeMap
@@ -44,9 +45,9 @@ import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.common.ContextUtils
import com.facebook.react.views.view.setStatusBarTranslucency
import com.facebook.react.views.view.ReactViewGroup
import java.util.Objects
import kotlin.math.abs
/**
* ReactModalHostView is a view that sits in the view hierarchy representing a Modal view.
@@ -287,7 +288,16 @@ public class ReactModalHostView(context: ThemedReactContext) :
* changed. This has the pleasant side-effect of us not having to preface all Modals with "top:
* statusBarHeight", since that margin will be included in the FrameLayout.
*/
get() = FrameLayout(context).apply { addView(dialogRootViewGroup) }
get() {
val frameLayout = FrameLayout(context)
frameLayout.addView(hostView)
if (statusBarTranslucent) {
frameLayout.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
} else {
frameLayout.fitsSystemWindows = true
}
return frameLayout
}
/**
* updateProperties will update the properties that do not require us to recreate the dialog
@@ -314,8 +324,6 @@ public class ReactModalHostView(context: ThemedReactContext) :
}
}
dialogWindow.setStatusBarTranslucency(statusBarTranslucent)
if (transparent) {
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
} else {
@@ -349,6 +357,10 @@ public class ReactModalHostView(context: ThemedReactContext) :
}
}
public fun updateState(width: Int, height: Int) {
hostView.updateState(width, height)
}
// This listener is called when the user presses KeyEvent.KEYCODE_BACK
// An event is then passed to JS which can either close or not close the Modal by setting the
// visible property
@@ -374,6 +386,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
public inner class DialogRootViewGroup(context: Context?) : ReactViewGroup(context), RootView {
internal var stateWrapper: StateWrapper? = null
private var hasAdjustedSize = false
private var viewWidth = 0
private var viewHeight = 0
private val jSTouchDispatcher: JSTouchDispatcher = JSTouchDispatcher(this)
@@ -393,8 +406,31 @@ public class ReactModalHostView(context: ThemedReactContext) :
super.onSizeChanged(w, h, oldw, oldh)
viewWidth = w
viewHeight = h
updateFirstChildView()
}
updateState(viewWidth, viewHeight)
private fun updateFirstChildView() {
if (childCount > 0) {
hasAdjustedSize = false
val viewTag: Int = getChildAt(0).id
if (stateWrapper != null) {
// This will only be called under Fabric
updateState(viewWidth, viewHeight)
} else {
// TODO: T44725185 remove after full migration to Fabric
val reactContext: ReactContext = reactContext
reactContext.runOnNativeModulesQueueThread(
object : GuardedRunnable(reactContext) {
override fun runGuarded() {
this@DialogRootViewGroup.reactContext.reactApplicationContext
.getNativeModule(UIManagerModule::class.java)
?.updateNodeSize(viewTag, viewWidth, viewHeight)
}
})
}
} else {
hasAdjustedSize = true
}
}
@UiThread
@@ -402,24 +438,43 @@ public class ReactModalHostView(context: ThemedReactContext) :
val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat())
val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat())
// Check incoming state values. If they're already the correct value, return early to prevent
// infinite UpdateState/SetState loop.
val currentState: ReadableMap? = stateWrapper?.getStateData()
if (currentState != null) {
val delta = 0.9f
val stateScreenHeight =
if (currentState.hasKey("screenHeight")) {
currentState.getDouble("screenHeight").toFloat()
} else {
0f
}
val stateScreenWidth =
if (currentState.hasKey("screenWidth")) {
currentState.getDouble("screenWidth").toFloat()
} else {
0f
}
if (abs((stateScreenWidth - realWidth).toDouble()) < delta &&
abs((stateScreenHeight - realHeight).toDouble()) < delta) {
return
}
}
stateWrapper?.let { sw ->
// new architecture
val newStateData: WritableMap = WritableNativeMap()
newStateData.putDouble("screenWidth", realWidth.toDouble())
newStateData.putDouble("screenHeight", realHeight.toDouble())
sw.updateState(newStateData)
} ?: run {
// old architecture
// TODO: T44725185 remove after full migration to Fabric
reactContext.runOnNativeModulesQueueThread(
object : GuardedRunnable(reactContext) {
override fun runGuarded() {
reactContext.reactApplicationContext
.getNativeModule(UIManagerModule::class.java)
?.updateNodeSize(id, viewWidth, viewHeight)
}
})
}
}
}
override fun addView(child: View, index: Int, params: LayoutParams) {
super.addView(child, index, params)
if (hasAdjustedSize) {
updateFirstChildView()
}
}
override fun handleException(t: Throwable) {