Skip to content

Commit 829360c

Browse files
committed
feat(android): present pageSheet/formSheet as a partial custom tab (bottom sheet)
Android ignored presentationStyle and always opened full-screen. Map pageSheet/formSheet to a partial custom tab via setInitialActivityHeightPx (display height minus a fixed top gap), with a rounded toolbar, draggable to full; fullScreen and unset stay full-screen. Launch via startActivityForResult: Chrome only honors the partial-tab height when launched this way (or with a bound CustomTabsSession); launchUrl() silently opens full-screen regardless of the requested height.
1 parent a178884 commit 829360c

1 file changed

Lines changed: 40 additions & 8 deletions

File tree

android/src/main/java/com/nitroinappbrowser/NitroInAppBrowserImpl.kt

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.browser.customtabs.CustomTabsIntent
88
import com.facebook.react.bridge.ReactApplicationContext
99
import com.margelo.nitro.core.Promise
1010
import com.margelo.nitro.nitroinappbrowser.NitroInAppBrowserOptions
11+
import com.margelo.nitro.nitroinappbrowser.NitroInAppBrowserPresentationStyle
1112
import androidx.core.graphics.toColorInt
1213
import 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

Comments
 (0)