Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cli] point QR code to interstitial page when enabled #18838

Merged
merged 10 commits into from Sep 26, 2022

Conversation

esamelson
Copy link
Contributor

Why

third step of ENG-6120 -- ports most of expo/expo-cli@e901f5e to new CLI

How

  • Add user-agent parsing to deduce the platform in cases where it isn't provided (i.e. when the user has opened the interstitial page via QR code)
  • Allow platform to be optional in getLoadingUrl
  • Show a QR code for the interstitial page when it's enabled (but still print the native runtime URL)
  • Don't restrict iOS interstitial page URL to localhost

Test Plan

Added unit tests for all new functionality. Also tested manually to ensure parity with the old CLI:

  • EXPO_ENABLE_INTERSTITIAL_PAGE=1 npx expo start + scan QR code -> see interstitial page
  • both buttons on interstitial page work
  • EXPO_ENABLE_INTERSTITIAL_PAGE=1 npx expo start --dev-client + scan QR code -> opens in dev client
  • remove expo-dev-client from project, EXPO_ENABLE_INTERSTITIAL_PAGE=1 npx expo start + scan QR code -> opens in Expo Go

Checklist

@linear
Copy link

linear bot commented Aug 26, 2022

ENG-6120 Take user to interstitial when launching dev client project from versioned CLI

  • pressing i
  • pressing a
  • passing ios or android flag

@@ -348,6 +348,13 @@ export abstract class BundlerDevServer {
: this.getUrlCreator().constructUrl({ ...opts, scheme: 'exp' });
}

public getQRCodeUrl(opts: Partial<CreateURLOptions> = {}) {
Copy link
Contributor

Choose a reason for hiding this comment

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

There's no such concept as a "QR Code" URL, all URLs can be represented as a QR code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've removed this and changed interactiveActions to call getInterstitialPageUrl directly.

@@ -36,7 +37,7 @@ export class RuntimeRedirectMiddleware extends ExpoMiddleware {
async handleRequestAsync(req: ServerRequest, res: ServerResponse): Promise<void> {
const { query } = parse(req.url!, true);
const isDevClient = query['choice'] === 'expo-dev-client';
const platform = parsePlatformHeader(req);
const platform = parsePlatformHeader(req) ?? resolvePlatformFromUserAgentHeader(req);
Copy link
Contributor

Choose a reason for hiding this comment

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

parsePlatformHeader is used across almost all middleware, why should the policy for platform detection change for just one use-case.

url: 'http://localhost:3000',
headers: {
'user-agent':
'Mozilla/5.0 (iPhone; CPU iPhone OS 15_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Mobile/15E148 Safari/604.1',
Copy link
Contributor

Choose a reason for hiding this comment

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

These user agent values need annotation about where they come from and how to update them in the future.

resolvePlatformFromUserAgentHeader(
asRequest({
url: 'http://localhost:3000',
headers: {},
Copy link
Contributor

Choose a reason for hiding this comment

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

When would this happen?

@@ -21,6 +21,18 @@ export function parsePlatformHeader(req: ServerRequest): string | null {
return (Array.isArray(platform) ? platform[0] : platform) ?? null;
}

/** Guess the platform from the user-agent header. */
Copy link
Contributor

Choose a reason for hiding this comment

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

Add more informative doc block.

Comment on lines 28 to 36
printQRCode(qrCodeUrl);
Log.log(printItem(chalk`Metro waiting on {underline ${nativeRuntimeUrl}}`));
Copy link
Contributor

Choose a reason for hiding this comment

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

The QR code is just a convenience feature, it should match the actual URL that is displayed. Showing a URL and a conditionally different QR code is confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought that showing a message saying Metro waiting on <interstitial-page-url> would be both confusing and inaccurate. I’ve updated this to print both URLs along with another message when the QR code points to the interstitial page.

@@ -403,6 +410,8 @@ export abstract class BundlerDevServer {
protected shouldUseInterstitialPage(): boolean {
return (
env.EXPO_ENABLE_INTERSTITIAL_PAGE &&
// if user passed --dev-client flag, skip interstitial page
!this.isDevClient &&
Copy link
Contributor

Choose a reason for hiding this comment

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

If the user passed in --dev-client then this function should never be called, openAsync should use the custom option.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without this here, the QR code would now point to interstitial page when --dev-client is passed.

@@ -75,7 +76,7 @@ export class InterstitialPageMiddleware extends ExpoMiddleware {
res = disableResponseCache(res);
res.setHeader('Content-Type', 'text/html');

const platform = parsePlatformHeader(req);
const platform = parsePlatformHeader(req) ?? resolvePlatformFromUserAgentHeader(req);
Copy link
Contributor

Choose a reason for hiding this comment

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

This method is attempting to implement our hosted server's specification with added legacy support for expo-cli which supported the exponent-platform header, is platform sniffing worked into the specification anywhere?

Copy link
Contributor

@EvanBacon EvanBacon left a comment

Choose a reason for hiding this comment

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

check comments

@esamelson
Copy link
Contributor Author

The reason for adding the user-agent detection is because if the interstitial page is opened via a QR code, we need to detect what platform they’re on so that we can open the correct deep link when they press one of the buttons on the page. (This was added to expo-cli in expo/expo-cli@e901f5e.) If you have a different suggestion for how to achieve this, let me know and I can try implementing that instead.

@EvanBacon EvanBacon merged commit 14e5da3 into @eric/cli-ensure-dc-installed Sep 26, 2022
@EvanBacon EvanBacon deleted the @eric/eng-6120-2 branch September 26, 2022 17:07
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.

None yet

3 participants