From 5fe76604393a7e931559a3ef82564619885dbe43 Mon Sep 17 00:00:00 2001 From: Alan Lee Date: Thu, 5 Sep 2024 17:23:14 -0700 Subject: [PATCH] Set inset based margins on LogBox (#46338) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46338 **Issue:** With forced edge-to-edge on Android 15, LogBox bottom tab bar is hidden behind 3 button nav bar and is unusable. **Solution:** LogBox is using Android Dialog so update it to set margins based on inset values. With this change we can get rid of android header logic from JS. Changelog: [Android][Changed] - Modify LogBox to be usable on Android 15 Reviewed By: mdvacca Differential Revision: D62224124 fbshipit-source-id: 4721753bf340bd813bcd560052c52b63fa58ad4b --- .../LogBox/UI/LogBoxInspectorHeader.js | 13 +------- .../facebook/react/devsupport/LogBoxDialog.kt | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js index 4780db6aa8a496..5637d6ae9efc4d 100644 --- a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js @@ -28,18 +28,7 @@ type Props = $ReadOnly<{ }>; const LogBoxInspectorHeaderSafeArea: React.AbstractComponent = - Platform.OS === 'android' - ? function LogBoxInspectorHeaderSafeArea(props) { - // NOTE: Inline the import of `StatusBar` so that initializing this module - // does not require initializing a TurboModule (and main thread one, too). - const {currentHeight} = require('../../Components/StatusBar/StatusBar'); - const style = StyleSheet.compose( - {paddingTop: currentHeight}, - props.style, - ); - return ; - } - : SafeAreaView; + Platform.OS === 'android' ? View : SafeAreaView; export default function LogBoxInspectorHeader(props: Props): React.Node { if (props.level === 'syntax') { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt index 60bd25c7ef9977..a0b5b086be3cb5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt @@ -9,12 +9,18 @@ package com.facebook.react.devsupport import android.app.Activity import android.app.Dialog +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle import android.view.View import android.view.Window +import android.widget.FrameLayout +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import com.facebook.react.R /** Dialog for displaying JS errors in LogBox. */ -internal class LogBoxDialog(context: Activity, reactRootView: View?) : +internal class LogBoxDialog(context: Activity, private val reactRootView: View?) : Dialog(context, R.style.Theme_Catalyst_LogBox) { init { requestWindowFeature(Window.FEATURE_NO_TITLE) @@ -22,4 +28,26 @@ internal class LogBoxDialog(context: Activity, reactRootView: View?) : setContentView(reactRootView) } } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + // set background color so it will show below transparent system bars on forced edge-to-edge + this.window?.setBackgroundDrawable(ColorDrawable(Color.BLACK)) + // register insets listener to update margins on the ReactRootView to avoid overlap w/ system bars + reactRootView?.let { rootView -> + val insetsType: Int = + WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() + + val windowInsetsListener = { view: View, windowInsets: WindowInsetsCompat -> + val insets = windowInsets.getInsets(insetsType) + + (view.layoutParams as FrameLayout.LayoutParams).apply { + setMargins(insets.left, insets.top, insets.right, insets.bottom) + } + + WindowInsetsCompat.CONSUMED + } + ViewCompat.setOnApplyWindowInsetsListener(rootView, windowInsetsListener) + } + } }