Skip to content

Commit 7fcaae2

Browse files
committed
Correctly create the first modal state
1 parent b2d9f5f commit 7fcaae2

6 files changed

Lines changed: 67 additions & 64 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import com.facebook.react.internal.interop.InteropEventEmitter;
7171
import com.facebook.react.modules.core.ReactChoreographer;
7272
import com.facebook.react.modules.i18nmanager.I18nUtil;
73+
import com.facebook.react.uimanager.DisplayMetricsHolder;
7374
import com.facebook.react.uimanager.GuardedFrameCallback;
7475
import com.facebook.react.uimanager.IllegalViewOperationException;
7576
import com.facebook.react.uimanager.PixelUtil;
@@ -97,6 +98,7 @@
9798
import java.util.HashSet;
9899
import java.util.List;
99100
import java.util.Map;
101+
import java.util.Objects;
100102
import java.util.Queue;
101103
import java.util.Set;
102104
import java.util.concurrent.CopyOnWriteArrayList;
@@ -727,6 +729,13 @@ public boolean getThemeData(int surfaceId, float[] defaultTextInputPadding) {
727729
return true;
728730
}
729731

732+
private long getEncodedScreenSizeWithoutVerticalInsets(int surfaceId) {
733+
SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
734+
Objects.requireNonNull(surfaceMountingManager);
735+
Objects.requireNonNull(surfaceMountingManager.getContext());
736+
return DisplayMetricsHolder.getEncodedScreenSizeWithoutVerticalInsets(surfaceMountingManager.getContext().getCurrentActivity());
737+
}
738+
730739
@Override
731740
public void addUIManagerEventListener(UIManagerListener listener) {
732741
mListeners.add(listener);

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ package com.facebook.react.uimanager
1010
import android.app.Activity
1111
import android.content.Context
1212
import android.util.DisplayMetrics
13+
import android.util.Log
1314
import android.view.WindowManager
1415
import androidx.core.view.ViewCompat
1516
import androidx.core.view.WindowInsetsCompat
1617
import com.facebook.react.bridge.WritableMap
1718
import com.facebook.react.bridge.WritableNativeMap
19+
import com.facebook.react.uimanager.PixelUtil.pxToDp
20+
import com.facebook.yoga.annotations.DoNotStrip
1821

1922
/**
2023
* Holds an instance of the current DisplayMetrics so we don't have to thread it through all the
2124
* classes that need it.
2225
*/
26+
@DoNotStrip
2327
public object DisplayMetricsHolder {
2428
private const val INITIALIZATION_MISSING_MESSAGE =
2529
"DisplayMetricsHolder must be initialized with initDisplayMetricsIfNotInitialized or initDisplayMetrics"
@@ -111,4 +115,24 @@ public object DisplayMetricsHolder {
111115
WindowInsetsCompat.Type.displayCutout())
112116
.top
113117
}
118+
119+
// This annotation can be removed once FabricUIManager is migrated to Kotlin
120+
@JvmName("getEncodedScreenSizeWithoutVerticalInsets")
121+
@JvmStatic
122+
internal fun getEncodedScreenSizeWithoutVerticalInsets(activity: Activity?): Long {
123+
val windowInsets = activity?.window?.decorView?.let(ViewCompat::getRootWindowInsets) ?: return 0
124+
val insets =
125+
windowInsets.getInsets(
126+
WindowInsetsCompat.Type.statusBars() or
127+
WindowInsetsCompat.Type.navigationBars() or
128+
WindowInsetsCompat.Type.displayCutout())
129+
val verticalInsets = insets.top + insets.bottom
130+
return encodeFloatsToLong(
131+
(checkNotNull(screenDisplayMetrics).widthPixels).toFloat().pxToDp(),
132+
(checkNotNull(screenDisplayMetrics).heightPixels - verticalInsets).toFloat().pxToDp()
133+
)
134+
}
135+
136+
private fun encodeFloatsToLong(width: Float, height: Float): Long =
137+
(width.toRawBits().toLong()) shl 32 or (height.toRawBits().toLong())
114138
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.kt

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ import com.facebook.react.bridge.WritableNativeMap
4040
import com.facebook.react.common.annotations.VisibleForTesting
4141
import com.facebook.react.common.build.ReactBuildConfig
4242
import com.facebook.react.config.ReactFeatureFlags
43-
import com.facebook.react.uimanager.DisplayMetricsHolder
44-
import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
4543
import com.facebook.react.uimanager.JSPointerDispatcher
4644
import com.facebook.react.uimanager.JSTouchDispatcher
4745
import com.facebook.react.uimanager.PixelUtil.pxToDp
@@ -51,7 +49,6 @@ import com.facebook.react.uimanager.ThemedReactContext
5149
import com.facebook.react.uimanager.UIManagerModule
5250
import com.facebook.react.uimanager.events.EventDispatcher
5351
import com.facebook.react.views.common.ContextUtils
54-
import com.facebook.react.views.modal.ReactModalHostView.DialogRootViewGroup
5552
import com.facebook.react.views.view.ReactViewGroup
5653
import com.facebook.react.views.view.disableEdgeToEdge
5754
import com.facebook.react.views.view.enableEdgeToEdge
@@ -131,7 +128,6 @@ public class ReactModalHostView(context: ThemedReactContext) :
131128
private var createNewDialog = false
132129

133130
init {
134-
initStatusBarHeight(context)
135131
dialogRootViewGroup = DialogRootViewGroup(context)
136132
}
137133

@@ -484,26 +480,6 @@ public class ReactModalHostView(context: ThemedReactContext) :
484480

485481
private companion object {
486482
private const val TAG = "ReactModalHost"
487-
488-
// We store the status bar height to be able to properly position
489-
// the modal on the first render.
490-
private var statusBarHeight = 0
491-
492-
private fun initStatusBarHeight(reactContext: ReactContext) {
493-
statusBarHeight = getStatusBarHeightPx(reactContext.currentActivity)
494-
}
495-
496-
@JvmStatic
497-
@DoNotStrip
498-
private fun getScreenDisplayMetricsWithoutInsets(): Long {
499-
val displayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics()
500-
return encodeFloatsToLong(
501-
displayMetrics.widthPixels.toFloat().pxToDp(),
502-
(displayMetrics.heightPixels - statusBarHeight).toFloat().pxToDp())
503-
}
504-
505-
private fun encodeFloatsToLong(width: Float, height: Float): Long =
506-
(width.toRawBits().toLong()) shl 32 or (height.toRawBits().toLong())
507483
}
508484

509485
/**

packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,39 @@ class ModalHostViewComponentDescriptor final
3737

3838
ConcreteComponentDescriptor::adopt(shadowNode);
3939
}
40+
41+
#ifdef ANDROID
42+
virtual State::Shared createInitialState(
43+
const Props::Shared& props,
44+
const ShadowNodeFamily::Shared& family) const override {
45+
int surfaceId = family->getSurfaceId();
46+
47+
const jni::global_ref<jobject>& fabricUIManager =
48+
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
49+
50+
static auto getEncodedScreenSizeWithoutVerticalInsets =
51+
jni::findClassStatic(UIManagerJavaDescriptor)
52+
->getMethod<jlong(jint)>("getEncodedScreenSizeWithoutVerticalInsets");
53+
54+
auto result = getEncodedScreenSizeWithoutVerticalInsets(fabricUIManager, surfaceId);
55+
56+
// Inspired from yogaMeasureToSize from conversions.h
57+
int32_t wBits = 0xFFFFFFFF & (result >> 32);
58+
int32_t hBits = 0xFFFFFFFF & result;
59+
60+
auto* measuredWidth = reinterpret_cast<float*>(&wBits);
61+
auto* measuredHeight = reinterpret_cast<float*>(&hBits);
62+
63+
return std::make_shared<ModalHostViewShadowNode::ConcreteState>(
64+
std::make_shared<const ModalHostViewState>(
65+
ModalHostViewState(Size{.width = *measuredWidth, .height = *measuredHeight})),
66+
family);
67+
}
68+
#endif // ANDROID
69+
70+
private:
71+
constexpr static auto UIManagerJavaDescriptor =
72+
"com/facebook/react/fabric/FabricUIManager";
4073
};
4174

4275
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/components/modal/platform/android/JReactModalHostView.h

Lines changed: 0 additions & 38 deletions
This file was deleted.

packages/react-native/ReactCommon/react/renderer/components/modal/platform/android/ModalHostViewUtils.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77

88
#include <react/renderer/components/modal/ModalHostViewUtils.h>
99
#include <react/renderer/graphics/Size.h>
10-
#include "JReactModalHostView.h"
1110

1211
namespace facebook::react {
1312

1413
Size ModalHostViewScreenSize() {
15-
return JReactModalHostView::getDisplayMetrics();
14+
return Size{0, 0};
1615
}
1716

1817
} // namespace facebook::react

0 commit comments

Comments
 (0)