microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
c036b0d343245c82886cd5906e37ff50b8b30d34

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/extension/exponent/exponentPlatform.ts

147lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import { ErrorHelper } from "../../common/error/errorHelper";
5import { InternalErrorCode } from "../../common/error/internalErrorCode";
6import { IExponentRunOptions } from "../launchArgs";
7import { GeneralMobilePlatform, MobilePlatformDeps } from "../generalMobilePlatform";
8import { ExponentHelper } from "./exponentHelper";
9import { TelemetryHelper } from "../../common/telemetryHelper";
10import { QRCodeContentProvider } from "../qrCodeContentProvider";
11
12import * as vscode from "vscode";
13import * as Q from "q";
14import * as XDL from "./xdlInterface";
15import * as url from "url";
16import * as nls from "vscode-nls";
17nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
18const localize = nls.loadMessageBundle();
19
20
21export class ExponentPlatform extends GeneralMobilePlatform {
22 private exponentTunnelPath: string | null;
23 private exponentHelper: ExponentHelper;
24 private qrCodeContentProvider: QRCodeContentProvider = new QRCodeContentProvider();
25
26 constructor(runOptions: IExponentRunOptions, platformDeps: MobilePlatformDeps = {}) {
27 super(runOptions, platformDeps);
28 this.exponentHelper = this.packager.getExponentHelper();
29 this.exponentTunnelPath = null;
30 }
31
32 public runApp(): Q.Promise<void> {
33 let extProps = {
34 platform: {
35 value: "exponent",
36 isPii: false,
37 },
38 };
39
40 extProps = TelemetryHelper.addPropertyToTelemetryProperties(this.runOptions.reactNativeVersions.reactNativeVersion, "reactNativeVersion", extProps);
41 extProps = TelemetryHelper.addPropertyToTelemetryProperties(this.runOptions.expoHostType, "expoHostType", extProps);
42
43 return TelemetryHelper.generate("ExponentPlatform.runApp", extProps, () => {
44 return this.loginToExponentOrSkip(this.runOptions.expoHostType)
45 .then(() =>
46 XDL.setOptions(this.projectPath, { packagerPort: this.packager.getPort() })
47 )
48 .then(() =>
49 XDL.startExponentServer(this.projectPath)
50 )
51 .then(() => {
52 if (this.runOptions.expoHostType !== "tunnel") {
53 // the purpose of this is to save the same sequence of handling 'adb reverse' command execution as in Expo
54 // https://github.com/expo/expo-cli/blob/1d515d21200841e181518358fd9dc4c7b24c7cd6/packages/xdl/src/Project.ts#L2226-L2370
55 // we added this to be sure that our Expo launching logic doesn't have any negative side effects
56 return XDL.stopAdbReverse(this.projectPath);
57 }
58 return XDL.startTunnels(this.projectPath);
59 })
60 .then(() => {
61 if (this.runOptions.expoHostType !== "local") return false;
62 // we need to execute 'adb reverse' command to bind ports used by Expo and RN of local machine to ports of a connected Android device or a running emulator
63 return XDL.startAdbReverse(this.projectPath);
64 })
65 .then((isAdbReversed) => {
66 switch (this.runOptions.expoHostType) {
67 case "lan":
68 return XDL.getUrl(this.projectPath, { dev: true, minify: false, hostType: "lan" });
69 case "local":
70 if (isAdbReversed) {
71 this.logger.info(localize("ExpoStartAdbReverseSuccess", "A device or an emulator was found, 'adb reverse' command successfully executed."));
72 } else {
73 this.logger.warning(localize("ExpoStartAdbReverseFailure", "Adb reverse command failed. Couldn't find connected over usb device or running emulator. Also please make sure that there is only one currently connected device or running emulator."));
74 }
75
76 return XDL.getUrl(this.projectPath, { dev: true, minify: false, hostType: "localhost" });
77 case "tunnel":
78 default:
79 return XDL.getUrl(this.projectPath, { dev: true, minify: false });
80 }
81 })
82 .then(exponentUrl => {
83 return "exp://" + url.parse(exponentUrl).host;
84 })
85 .catch(reason => {
86 return Q.reject<string>(reason);
87 })
88 .then(exponentUrl => {
89 let exponentPage = vscode.window.createWebviewPanel("Expo QR Code", "Expo QR Code", vscode.ViewColumn.Two, { });
90 exponentPage.webview.html = this.qrCodeContentProvider.provideTextDocumentContent(vscode.Uri.parse(exponentUrl));
91 return exponentUrl;
92 })
93 .then(exponentUrl => {
94 if (!exponentUrl) {
95 return Q.reject<void>(ErrorHelper.getInternalError(InternalErrorCode.ExpectedExponentTunnelPath));
96 }
97 this.exponentTunnelPath = exponentUrl;
98 const outputMessage = localize("ApplicationIsRunningOnExponentOpenToSeeIt", "Application is running on Expo. Open your Expo app at {0} to see it.", this.exponentTunnelPath);
99 this.logger.info(outputMessage);
100
101 return Q.resolve(void 0);
102 });
103 });
104 }
105
106 public loginToExponentOrSkip(expoHostType?: "tunnel" | "lan" | "local") {
107 if (expoHostType !== "tunnel") {
108 return Q({});
109 }
110 return this.exponentHelper.loginToExponent(
111 (message, password) => {
112 return Q.Promise((resolve, reject) => {
113 vscode.window.showInputBox({ placeHolder: message, password: password })
114 .then(login => {
115 resolve(login || "");
116 }, reject);
117 });
118 },
119 (message) => {
120 return Q.Promise((resolve, reject) => {
121 const okButton = { title: "Ok" };
122 const cancelButton = { title: "Cancel", isCloseAffordance: true };
123 vscode.window.showInformationMessage(message, {modal: true}, okButton, cancelButton)
124 .then(answer => {
125 if (answer === cancelButton) {
126 reject(ErrorHelper.getInternalError(InternalErrorCode.UserCancelledExpoLogin));
127 }
128 resolve("");
129 }, reject);
130 });
131 }
132 );
133 }
134
135 public beforeStartPackager(): Q.Promise<void> {
136 return this.exponentHelper.configureExponentEnvironment();
137 }
138
139 public enableJSDebuggingMode(): Q.Promise<void> {
140 this.logger.info(localize("ApplicationIsRunningOnExponentShakeDeviceForRemoteDebugging", "Application is running on Expo. Please shake device and select 'Debug JS Remotely' to enable debugging."));
141 return Q.resolve<void>(void 0);
142 }
143
144 public getRunArguments(): string[] {
145 return [];
146 }
147}
148