@@ -8,6 +8,7 @@ import androidx.browser.customtabs.CustomTabsIntent
88import com.facebook.react.bridge.ReactApplicationContext
99import com.margelo.nitro.core.Promise
1010import com.margelo.nitro.nitroinappbrowser.NitroInAppBrowserOptions
11+ import com.margelo.nitro.nitroinappbrowser.NitroInAppBrowserPresentationStyle
1112import androidx.core.graphics.toColorInt
1213import androidx.core.net.toUri
1314
@@ -33,22 +34,45 @@ class NitroInAppBrowserImpl(private val reactContext: ReactApplicationContext?)
3334 customTabParams.setNavigationBarColor(getColor(options.barColor))
3435 }
3536
37+ val currentActivity = reactContext?.currentActivity ? : throw Error (" No Activity" )
38+
3639 val customTabIntent = CustomTabsIntent .Builder ()
3740 customTabIntent.setShowTitle(false )
3841 customTabIntent.setInstantAppsEnabled(false )
3942 customTabIntent.setDefaultColorSchemeParams(customTabParams.build())
4043 customTabIntent.setShareState(CustomTabsIntent .SHARE_STATE_ON )
4144
42- val intent = customTabIntent.build()
43- intent.apply {
44- if (! isPackageInstalled()){
45- Log .d(TAG , " Chrome not installed" )
46- } else {
47- intent.intent.setPackage(chromePackageName)
45+ // pageSheet/formSheet -> partial custom tab (bottom sheet), like iOS;
46+ // fullScreen/unset stay full-screen. Height = display minus a fixed top-gap
47+ // peek; Chrome clamps the minimum to 50% and the user can drag to full.
48+ when (options?.presentationStyle) {
49+ NitroInAppBrowserPresentationStyle .PAGESHEET ,
50+ NitroInAppBrowserPresentationStyle .FORMSHEET -> {
51+ val metrics = currentActivity.resources.displayMetrics
52+ val topGapPx = (TOP_GAP_DP * metrics.density).toInt()
53+ customTabIntent.setInitialActivityHeightPx(
54+ metrics.heightPixels - topGapPx,
55+ CustomTabsIntent .ACTIVITY_HEIGHT_ADJUSTABLE ,
56+ )
57+ customTabIntent.setToolbarCornerRadiusDp(TOOLBAR_CORNER_RADIUS_DP )
4858 }
59+ else -> Unit
4960 }
50- val currentActivity = reactContext?.currentActivity ? : throw Error (" No Activity" )
51- intent.launchUrl(currentActivity, url.toUri())
61+
62+ val intent = customTabIntent.build()
63+ if (! isPackageInstalled()) {
64+ Log .d(TAG , " Chrome not installed" )
65+ } else {
66+ intent.intent.setPackage(chromePackageName)
67+ }
68+ // Partial tabs are only honored when launched via startActivityForResult
69+ // (or a CustomTabsSession); launchUrl() silently ignores the height.
70+ intent.intent.data = url.toUri()
71+ currentActivity.startActivityForResult(
72+ intent.intent,
73+ IN_APP_BROWSER_REQUEST_CODE ,
74+ intent.startAnimationBundle,
75+ )
5276 return Promise .resolved(Unit )
5377 }
5478
@@ -76,5 +100,13 @@ class NitroInAppBrowserImpl(private val reactContext: ReactApplicationContext?)
76100
77101 companion object {
78102 const val TAG = " NitroInAppBrowserImpl"
103+ // Fixed top peek (dp) subtracted from the display height for the sheet's
104+ // initial height — a constant gap across screen sizes, like iOS pageSheet.
105+ private const val TOP_GAP_DP = 80f
106+ // Arbitrary request code: startActivityForResult is required for Chrome to
107+ // honor the partial-tab height; we don't consume the result.
108+ private const val IN_APP_BROWSER_REQUEST_CODE = 0x1A0B
109+ // System clamps the toolbar corner radius at 16dp.
110+ private const val TOOLBAR_CORNER_RADIUS_DP = 16
79111 }
80112}
0 commit comments