Skip to content

Commit 9065249

Browse files
patch ReactModalHostview to init with correct sizes (#63)
1 parent 0599a89 commit 9065249

File tree

6 files changed

+93
-10
lines changed

6 files changed

+93
-10
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ import android.view.accessibility.AccessibilityEvent
2727
import android.view.accessibility.AccessibilityNodeInfo
2828
import android.widget.FrameLayout
2929
import androidx.annotation.UiThread
30+
import androidx.core.view.ViewCompat
3031
import androidx.core.content.ContextCompat
3132
import androidx.core.view.WindowCompat
33+
import androidx.core.view.WindowInsetsCompat
34+
import androidx.core.view.WindowInsetsCompat.CONSUMED
3235
import com.facebook.common.logging.FLog
3336
import com.facebook.react.R
3437
import com.facebook.react.bridge.GuardedRunnable
@@ -40,6 +43,7 @@ import com.facebook.react.bridge.WritableNativeMap
4043
import com.facebook.react.common.ReactConstants
4144
import com.facebook.react.common.annotations.VisibleForTesting
4245
import com.facebook.react.config.ReactFeatureFlags
46+
import com.facebook.react.uimanager.DisplayMetricsHolder
4347
import com.facebook.react.uimanager.JSPointerDispatcher
4448
import com.facebook.react.uimanager.JSTouchDispatcher
4549
import com.facebook.react.uimanager.PixelUtil.pxToDp
@@ -52,6 +56,7 @@ import com.facebook.react.views.common.ContextUtils
5256
import com.facebook.react.views.view.ReactViewGroup
5357
import com.facebook.react.views.view.setStatusBarTranslucency
5458
import com.facebook.react.views.view.setSystemBarsTranslucency
59+
import com.facebook.yoga.annotations.DoNotStrip
5560
import java.util.Objects
5661

5762
/**
@@ -122,6 +127,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
122127
private var createNewDialog = false
123128

124129
init {
130+
initStatusBarHeight(context)
125131
dialogRootViewGroup = DialogRootViewGroup(context)
126132
}
127133

@@ -412,6 +418,18 @@ public class ReactModalHostView(context: ThemedReactContext) :
412418
}
413419
}
414420

421+
private fun initStatusBarHeight(reactContext: ReactContext) {
422+
val windowInsets =
423+
reactContext.getCurrentActivity()?.window?.decorView?.let(ViewCompat::getRootWindowInsets)
424+
statusBarHeight =
425+
windowInsets
426+
?.getInsets(
427+
WindowInsetsCompat.Type.statusBars() or
428+
WindowInsetsCompat.Type.navigationBars() or
429+
WindowInsetsCompat.Type.displayCutout())
430+
?.top ?: 0
431+
}
432+
415433
/**
416434
* Sets the testID on the DialogRootViewGroup. Since the accessibility events are not triggered on
417435
* the on the ReactModalHostView, the testID is forwarded to the DialogRootViewGroup to set the
@@ -430,8 +448,22 @@ public class ReactModalHostView(context: ThemedReactContext) :
430448

431449
private companion object {
432450
private const val TAG = "ReactModalHost"
451+
452+
// We store the status bar height to be able to properly position
453+
// the modal on the first render.
454+
private var statusBarHeight = 0
455+
456+
@JvmStatic
457+
@DoNotStrip
458+
private fun getScreenDisplayMetricsWithoutInsets(): FloatArray {
459+
val displayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics()
460+
return floatArrayOf(
461+
displayMetrics.widthPixels.toFloat().pxToDp(),
462+
(displayMetrics.heightPixels - statusBarHeight).toFloat().pxToDp())
463+
}
433464
}
434465

466+
435467
/**
436468
* DialogRootViewGroup is the ViewGroup which contains all the children of a Modal. It gets all
437469
* child information forwarded from [ReactModalHostView] and uses that to create children. It is
@@ -568,3 +600,4 @@ public class ReactModalHostView(context: ThemedReactContext) :
568600
}
569601
}
570602
}
603+

packages/react-native/ReactCommon/react/renderer/components/modal/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ add_compile_options(
1414
-Wpedantic
1515
-DLOG_TAG=\"Fabric\")
1616

17-
file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS *.cpp)
17+
file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS
18+
*.cpp
19+
platform/android/*.cpp)
20+
1821
add_library(rrc_modal STATIC ${rrc_modal_SRC})
1922

2023
target_include_directories(rrc_modal PUBLIC ${REACT_COMMON_DIR})

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99

1010
#include <react/renderer/core/graphicsConversions.h>
1111
#include <react/renderer/graphics/Float.h>
12+
#include "ModalHostViewUtils.h"
1213

1314
#ifdef ANDROID
1415
#include <folly/dynamic.h>
1516
#endif
1617

17-
#if defined(__APPLE__) && TARGET_OS_IOS
1818
#include "ModalHostViewUtils.h"
19-
#endif
2019

2120
namespace facebook::react {
2221

@@ -27,12 +26,7 @@ class ModalHostViewState final {
2726
public:
2827
using Shared = std::shared_ptr<const ModalHostViewState>;
2928

30-
#if defined(__APPLE__) && TARGET_OS_IOS
31-
ModalHostViewState() : screenSize(RCTModalHostViewScreenSize()) {
32-
#else
33-
ModalHostViewState(){
34-
#endif
35-
};
29+
ModalHostViewState() : screenSize(RCTModalHostViewScreenSize()) {}
3630
ModalHostViewState(Size screenSize_) : screenSize(screenSize_){};
3731

3832
#ifdef ANDROID
@@ -54,3 +48,4 @@ class ModalHostViewState final {
5448
};
5549

5650
} // namespace facebook::react
51+

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#pragma once
99

10-
#include <react/renderer/core/graphicsConversions.h>
10+
#include <react/renderer/graphics/Size.h>
1111

1212
namespace facebook::react {
1313

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <fbjni/fbjni.h>
11+
#include <react/renderer/graphics/Size.h>
12+
13+
#include <android/log.h>
14+
15+
namespace facebook::react {
16+
17+
class JReactModalHostView
18+
: public facebook::jni::JavaClass<JReactModalHostView> {
19+
public:
20+
static auto constexpr kJavaDescriptor =
21+
"Lcom/facebook/react/views/modal/ReactModalHostView;";
22+
23+
static Size getDisplayMetrics() {
24+
static auto method = JReactModalHostView::javaClassStatic()
25+
->getStaticMethod<jni::JArrayFloat()>(
26+
"getScreenDisplayMetricsWithoutInsets");
27+
auto result = method(javaClassStatic());
28+
size_t size = result->size();
29+
std::vector<jfloat> elements(size + 1L);
30+
result->getRegion(0, size, elements.data());
31+
return Size{elements[0], elements[1]};
32+
}
33+
};
34+
35+
} // namespace facebook::react
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include <react/renderer/components/modal/ModalHostViewUtils.h>
9+
#include "JReactModalHostView.h"
10+
11+
namespace facebook::react {
12+
13+
Size RCTModalHostViewScreenSize(void) {
14+
return JReactModalHostView::getDisplayMetrics();
15+
}
16+
17+
} // namespace facebook::react

0 commit comments

Comments
 (0)