Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/react-native/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ let reactFabricComponents = RNTarget(
name: .reactFabricComponents,
path: "ReactCommon/react/renderer",
excludedPaths: [
"components/modal/platform/android",
"components/modal/platform/cxx",
"components/view/platform/android",
"components/view/platform/windows",
"components/view/platform/macos",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import android.os.Build
import android.view.View
import android.view.WindowInsetsController
import android.view.WindowManager
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.facebook.common.logging.FLog
import com.facebook.fbreact.specs.NativeStatusBarManagerAndroidSpec
import com.facebook.react.bridge.GuardedRunnable
Expand All @@ -23,6 +21,7 @@ import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.common.ReactConstants
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.views.view.setStatusBarTranslucency
import com.facebook.react.views.view.setStatusBarVisibility
Expand All @@ -34,32 +33,17 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :

@Suppress("DEPRECATION")
override fun getTypedExportedConstants(): Map<String, Any> {
val currentActivity = reactApplicationContext.currentActivity
val statusBarColor =
reactApplicationContext.getCurrentActivity()?.window?.statusBarColor?.let { color ->
currentActivity?.window?.statusBarColor?.let { color ->
String.format("#%06X", 0xFFFFFF and color)
} ?: "black"
return mapOf(
HEIGHT_KEY to PixelUtil.toDIPFromPixel(getStatusBarHeightPx()),
HEIGHT_KEY to PixelUtil.toDIPFromPixel(getStatusBarHeightPx(currentActivity).toFloat()),
DEFAULT_BACKGROUND_COLOR_KEY to statusBarColor,
)
}

private fun getStatusBarHeightPx(): Float {
val windowInsets =
reactApplicationContext
.getCurrentActivity()
?.window
?.decorView
?.let(ViewCompat::getRootWindowInsets) ?: return 0f
return windowInsets
.getInsets(
WindowInsetsCompat.Type.statusBars() or
WindowInsetsCompat.Type.navigationBars() or
WindowInsetsCompat.Type.displayCutout())
.top
.toFloat()
}

@Suppress("DEPRECATION")
override fun setColor(colorDouble: Double, animated: Boolean) {
val color = colorDouble.toInt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@

package com.facebook.react.uimanager

import android.app.Activity
import android.content.Context
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.WritableNativeMap

Expand Down Expand Up @@ -98,4 +101,14 @@ public object DisplayMetricsHolder {
putDouble("fontScale", fontScale)
putDouble("densityDpi", displayMetrics.densityDpi.toDouble())
}

internal fun getStatusBarHeightPx(activity: Activity?): Int {
val windowInsets = activity?.window?.decorView?.let(ViewCompat::getRootWindowInsets) ?: return 0
return windowInsets
.getInsets(
WindowInsetsCompat.Type.statusBars() or
WindowInsetsCompat.Type.navigationBars() or
WindowInsetsCompat.Type.displayCutout())
.top
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import com.facebook.react.bridge.WritableNativeMap
import com.facebook.react.common.annotations.VisibleForTesting
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.config.ReactFeatureFlags
import com.facebook.react.uimanager.DisplayMetricsHolder
import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
import com.facebook.react.uimanager.JSPointerDispatcher
import com.facebook.react.uimanager.JSTouchDispatcher
import com.facebook.react.uimanager.PixelUtil.pxToDp
Expand All @@ -53,6 +55,7 @@ import com.facebook.react.views.modal.ReactModalHostView.DialogRootViewGroup
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.view.setStatusBarTranslucency
import com.facebook.react.views.view.setSystemBarsTranslucency
import com.facebook.yoga.annotations.DoNotStrip

/**
* ReactModalHostView is a view that sits in the view hierarchy representing a Modal view.
Expand Down Expand Up @@ -122,6 +125,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
private var createNewDialog = false

init {
initStatusBarHeight(context)
dialogRootViewGroup = DialogRootViewGroup(context)
}

Expand Down Expand Up @@ -461,6 +465,26 @@ public class ReactModalHostView(context: ThemedReactContext) :

private companion object {
private const val TAG = "ReactModalHost"

// We store the status bar height to be able to properly position
// the modal on the first render.
private var statusBarHeight = 0

private fun initStatusBarHeight(reactContext: ReactContext) {
statusBarHeight = getStatusBarHeightPx(reactContext.currentActivity)
}

@JvmStatic
@DoNotStrip
private fun getScreenDisplayMetricsWithoutInsets(): Long {
val displayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics()
return encodeFloatsToLong(
displayMetrics.widthPixels.toFloat().pxToDp(),
(displayMetrics.heightPixels - statusBarHeight).toFloat().pxToDp())
}

private fun encodeFloatsToLong(width: Float, height: Float): Long =
(width.toRawBits().toLong()) shl 32 or (height.toRawBits().toLong())
}

/**
Expand All @@ -476,6 +500,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
*/
public class DialogRootViewGroup internal constructor(context: Context) :
ReactViewGroup(context), RootView {

internal var stateWrapper: StateWrapper? = null
internal var eventDispatcher: EventDispatcher? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Pod::Spec.new do |s|
end

ss.subspec "modal" do |sss|
sss.source_files = "react/renderer/components/modal/**/*.{m,mm,cpp,h}"
sss.source_files = "react/renderer/components/modal/*.{m,mm,cpp,h}"
sss.exclude_files = "react/renderer/components/modal/tests"
sss.header_dir = "react/renderer/components/modal"
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ set(CMAKE_VERBOSE_MAKEFILE on)

include(${REACT_COMMON_DIR}/cmake-utils/react-native-flags.cmake)

file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS *.cpp)
file(GLOB rrc_modal_SRC CONFIGURE_DEPENDS
*.cpp
platform/android/*.cpp)

add_library(rrc_modal STATIC ${rrc_modal_SRC})

target_include_directories(rrc_modal PUBLIC ${REACT_COMMON_DIR})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ class ModalHostViewComponentDescriptor final
*shadowNode.getState())
.getData();

layoutableShadowNode.setSize(
Size{stateData.screenSize.width, stateData.screenSize.height});
layoutableShadowNode.setSize(Size{
.width = stateData.screenSize.width,
.height = stateData.screenSize.height});
layoutableShadowNode.setPositionType(YGPositionTypeAbsolute);

ConcreteComponentDescriptor::adopt(shadowNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@

#include <react/renderer/core/graphicsConversions.h>
#include <react/renderer/graphics/Float.h>
#include "ModalHostViewUtils.h"

#ifdef RN_SERIALIZABLE_STATE
#include <folly/dynamic.h>
#endif

#if defined(__APPLE__) && TARGET_OS_IOS
#include "ModalHostViewUtils.h"
#endif

namespace facebook::react {

/*
Expand All @@ -27,21 +24,16 @@ class ModalHostViewState final {
public:
using Shared = std::shared_ptr<const ModalHostViewState>;

#if defined(__APPLE__) && TARGET_OS_IOS
ModalHostViewState() : screenSize(RCTModalHostViewScreenSize()) {
#else
ModalHostViewState(){
#endif
};
ModalHostViewState() : screenSize(ModalHostViewScreenSize()) {}
ModalHostViewState(Size screenSize_) : screenSize(screenSize_){};

#ifdef RN_SERIALIZABLE_STATE
ModalHostViewState(
const ModalHostViewState& previousState,
folly::dynamic data)
: screenSize(Size{
(Float)data["screenWidth"].getDouble(),
(Float)data["screenHeight"].getDouble()}){};
.width = (Float)data["screenWidth"].getDouble(),
.height = (Float)data["screenHeight"].getDouble()}){};
#endif

const Size screenSize{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

#pragma once

#include <react/renderer/core/graphicsConversions.h>
#include <react/renderer/graphics/Size.h>

namespace facebook::react {

Size RCTModalHostViewScreenSize(void);
Size ModalHostViewScreenSize(void);

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace facebook::react {

Size RCTModalHostViewScreenSize(void)
Size ModalHostViewScreenSize(void)
{
CGSize screenSize = RCTScreenSize();
return {screenSize.width, screenSize.height};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <fbjni/fbjni.h>
#include <react/renderer/graphics/Size.h>

namespace facebook::react {

class JReactModalHostView
: public facebook::jni::JavaClass<JReactModalHostView> {
public:
static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/views/modal/ReactModalHostView;";

static Size getDisplayMetrics() {
static auto method =
JReactModalHostView::javaClassStatic()->getStaticMethod<jlong()>(
"getScreenDisplayMetricsWithoutInsets");
auto result = method(javaClassStatic());

// Inspired from yogaMeassureToSize from conversions.h
int32_t wBits = 0xFFFFFFFF & (result >> 32);
int32_t hBits = 0xFFFFFFFF & result;

auto* measuredWidth = reinterpret_cast<float*>(&wBits);
auto* measuredHeight = reinterpret_cast<float*>(&hBits);

return Size{.width = *measuredWidth, .height = *measuredHeight};
}
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include <react/renderer/components/modal/ModalHostViewUtils.h>
#include <react/renderer/graphics/Size.h>
#include "JReactModalHostView.h"

namespace facebook::react {

Size ModalHostViewScreenSize() {
return JReactModalHostView::getDisplayMetrics();
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include <react/renderer/components/modal/ModalHostViewUtils.h>
#include <react/renderer/graphics/Size.h>

namespace facebook::react {

Size ModalHostViewScreenSize() {
return Size{0, 0};
}

} // namespace facebook::react