diff --git a/android/src/main/java/com/nitroinappbrowser/NitroInAppBrowserImpl.kt b/android/src/main/java/com/nitroinappbrowser/NitroInAppBrowserImpl.kt index 444fd53..acff050 100644 --- a/android/src/main/java/com/nitroinappbrowser/NitroInAppBrowserImpl.kt +++ b/android/src/main/java/com/nitroinappbrowser/NitroInAppBrowserImpl.kt @@ -8,6 +8,7 @@ import androidx.browser.customtabs.CustomTabsIntent import com.facebook.react.bridge.ReactApplicationContext import com.margelo.nitro.core.Promise import com.margelo.nitro.nitroinappbrowser.NitroInAppBrowserOptions +import com.margelo.nitro.nitroinappbrowser.NitroInAppBrowserPresentationStyle import androidx.core.graphics.toColorInt import androidx.core.net.toUri @@ -33,22 +34,45 @@ class NitroInAppBrowserImpl(private val reactContext: ReactApplicationContext?) customTabParams.setNavigationBarColor(getColor(options.barColor)) } + val currentActivity = reactContext?.currentActivity ?: throw Error("No Activity") + val customTabIntent = CustomTabsIntent.Builder() customTabIntent.setShowTitle(false) customTabIntent.setInstantAppsEnabled(false) customTabIntent.setDefaultColorSchemeParams(customTabParams.build()) customTabIntent.setShareState(CustomTabsIntent.SHARE_STATE_ON) - val intent = customTabIntent.build() - intent.apply { - if (!isPackageInstalled()){ - Log.d(TAG, "Chrome not installed") - } else { - intent.intent.setPackage(chromePackageName) + // pageSheet/formSheet -> partial custom tab (bottom sheet), like iOS; + // fullScreen/unset stay full-screen. Height = display minus a fixed top-gap + // peek; Chrome clamps the minimum to 50% and the user can drag to full. + when (options?.presentationStyle) { + NitroInAppBrowserPresentationStyle.PAGESHEET, + NitroInAppBrowserPresentationStyle.FORMSHEET -> { + val metrics = currentActivity.resources.displayMetrics + val topGapPx = (TOP_GAP_DP * metrics.density).toInt() + customTabIntent.setInitialActivityHeightPx( + metrics.heightPixels - topGapPx, + CustomTabsIntent.ACTIVITY_HEIGHT_ADJUSTABLE, + ) + customTabIntent.setToolbarCornerRadiusDp(TOOLBAR_CORNER_RADIUS_DP) } + else -> Unit } - val currentActivity = reactContext?.currentActivity ?: throw Error("No Activity") - intent.launchUrl(currentActivity, url.toUri()) + + val intent = customTabIntent.build() + if (!isPackageInstalled()) { + Log.d(TAG, "Chrome not installed") + } else { + intent.intent.setPackage(chromePackageName) + } + // Partial tabs are only honored when launched via startActivityForResult + // (or a CustomTabsSession); launchUrl() silently ignores the height. + intent.intent.data = url.toUri() + currentActivity.startActivityForResult( + intent.intent, + IN_APP_BROWSER_REQUEST_CODE, + intent.startAnimationBundle, + ) return Promise.resolved(Unit) } @@ -76,5 +100,13 @@ class NitroInAppBrowserImpl(private val reactContext: ReactApplicationContext?) companion object { const val TAG = "NitroInAppBrowserImpl" + // Fixed top peek (dp) subtracted from the display height for the sheet's + // initial height — a constant gap across screen sizes, like iOS pageSheet. + private const val TOP_GAP_DP = 80f + // Arbitrary request code: startActivityForResult is required for Chrome to + // honor the partial-tab height; we don't consume the result. + private const val IN_APP_BROWSER_REQUEST_CODE = 0x1A0B + // System clamps the toolbar corner radius at 16dp. + private const val TOOLBAR_CORNER_RADIUS_DP = 16 } } \ No newline at end of file