Skip to content

Prototype development/inline android component - #383

Merged
kieran-osgood-shopify merged 39 commits into
prototype/developmentfrom
prototype-development/inline-android-component
Nov 28, 2025
Merged

kieran-osgood-shopify merged 39 commits into
prototype/developmentfrom
prototype-development/inline-android-component

Conversation

@kieran-osgood-shopify

@kieran-osgood-shopify kieran-osgood-shopify commented Nov 13, 2025 •

Copy link
Copy Markdown
Contributor

What changes are you making?

This PR integrates the CheckoutWebview thats being exposed in this PR Shopify/checkout-sheet-kit-android#397 so that it can be rendered in an "inline" mode - you'll need to have this branch checked out also to run it

How to test

Run the React Native Android sample app and go to the buy now screen, you should be able to do the same address change flow that occurs in the ios react native app


PR Checklist

Important

Releasing a new version of the kit?


Tip

See the Contributing documentation for instructions on how to publish a new version of the library.

@kieran-osgood-shopify

Copy link
Copy Markdown
Contributor Author

Remaining task to be completed here is to update the gradle config to ensure that we are able to build against local android package without modifying lib (JVM_1_8 -> JVM_17)

Comment thread sample/android/settings.gradle Outdated
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the prototype-development/inline-android-component branch from 2e352cc to 37f95c9 Compare November 26, 2025 18:17
@github-actions

github-actions Bot commented Nov 26, 2025 •

Copy link
Copy Markdown

Coverage Report

Lines Statements Branches Functions
Coverage: 82%
81.95% (218/266) 84% (105/125) 80.26% (61/76)


@Override
public void onComplete(@NonNull CheckoutCompleteEvent event) {
public void onCheckoutCompleted(@NonNull CheckoutCompleteEvent event) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe cart before the horse but these should be onComplete present tense for platform consistency.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah not to worry I'm resolving these locally, had to rebase (this is an old branch)

@westeezy westeezy left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a few nits but given the holiday and the fact this overall links really solid im approving :)

@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the prototype-development/inline-android-component branch 2 times, most recently from 83e818f to 565c443 Compare November 27, 2025 11:57
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the prototype-development/inline-android-component branch from 565c443 to 3b9ad9d Compare November 27, 2025 12:14
eventDispatcher.dispatchEvent(new CheckoutEvent(surfaceId, viewId, eventName, params));
}

private class InlineCheckoutEventProcessor extends DefaultCheckoutEventProcessor {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kiftio moved back to RCTCheckoutWebView having its own processor so i could remove all the changes to CustomCheckoutEventProcessor (but I renamed it to SheetCheckoutEventProcessor to distinguish them)

/// resulting in an empty view being rendered. Cannot move setup to constructor as
/// checkoutUrl is undefined until setCheckoutUrl is called by RCTCheckoutWebViewManager
/// requestLayout / invalidate were unsuccessful in remedying this
checkoutWebView.layout(0, 0, getWidth(), getHeight());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to override onLayout ot deal with size changes?

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    if (checkoutWebView != null) {
        checkoutWebView.layout(0, 0, right - left, bottom - top);
    }
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my initial approach which had the race condition

I've got a comment above that hopefully explains it but the onLayout was executing before setupCheckoutWebView (because the FrameLayout is constructed before react props are passed in) meaning we dont have a view to construct yet

Before:
onLayout (dimensions zero) -> setupCheckoutWebView -> view is zero sized

After:
onLayout (dimensions zero) -> setupCheckoutWebView -> re-measure layout after adding view -> view displays

I tried using requestLayout/invalidate to get android to re-run onLayout but didn't see a subsequent execution

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, yeah I was thinking in case the layout changes in some way (orientation?) and we don't resize

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - probably worth keeping it still just incase

private CheckoutConfiguration lastConfiguration = null;
private final Handler mainHandler = new Handler(Looper.getMainLooper());

private record CheckoutConfiguration(String url, String authToken) {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So just thinking about this, I think support for records might have come after what we've defined for

sourceCompatibility
targetCompatibility

Unless the android gradle plugin supports desugaring

errorMap.put("recoverable", checkoutError.isRecoverable());
errorMap.put("code", checkoutError.getErrorCode());
private Map<String, Object> populateErrorDetails(CheckoutException error) {
Map<String, Object> errorMap = new HashMap<>(Map.of(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may want to check when Map.of support was introduced too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since 9 - should be fine?
Image

@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the prototype-development/inline-android-component branch from 9d5e829 to 3a7c499 Compare November 28, 2025 12:01

@kiftio kiftio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@kieran-osgood-shopify
kieran-osgood-shopify merged commit b332283 into prototype/development Nov 28, 2025
7 checks passed
@kieran-osgood-shopify
kieran-osgood-shopify deleted the prototype-development/inline-android-component branch November 28, 2025 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants