microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.1.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/exponent/exponentPlatform.ts

158lines · 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, PlatformType } 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 XDL from "./xdlInterface";
14import * as url from "url";
15import * as nls from "vscode-nls";
16nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
17const localize = nls.loadMessageBundle();
18
19
20export class ExponentPlatform extends GeneralMobilePlatform {
21 private exponentTunnelPath: string | null;
22 private exponentHelper: ExponentHelper;
23 private qrCodeContentProvider: QRCodeContentProvider = new QRCodeContentProvider();
24
25 constructor(runOptions: IExponentRunOptions, platformDeps: MobilePlatformDeps = {}) {
26 super(runOptions, platformDeps);
27 this.exponentHelper = this.packager.getExponentHelper();
28 this.exponentTunnelPath = null;
29 }
30
31 public runApp(): Promise<void> {
32 let extProps = {
33 platform: {
34 value: PlatformType.Exponent,
35 isPii: false,
36 },
37 };
38
39 extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(this.runOptions, this.runOptions.reactNativeVersions, extProps);
40
41 return new Promise((resolve, reject) => {
42 TelemetryHelper.generate("ExponentPlatform.runApp", extProps, () => {
43 return this.loginToExponentOrSkip(this.runOptions.expoHostType)
44 .then(() =>
45 XDL.setOptions(this.projectPath, { packagerPort: this.packager.getPort() })
46 )
47 .then(() =>
48 XDL.startExponentServer(this.projectPath)
49 )
50 .then(() => {
51 if (this.runOptions.expoHostType !== "tunnel") {
52 // the purpose of this is to save the same sequence of handling 'adb reverse' command execution as in Expo
53 // https://github.com/expo/expo-cli/blob/1d515d21200841e181518358fd9dc4c7b24c7cd6/packages/xdl/src/Project.ts#L2226-L2370
54 // we added this to be sure that our Expo launching logic doesn't have any negative side effects
55 return XDL.stopAdbReverse(this.projectPath);
56 }
57 return XDL.startTunnels(this.projectPath);
58 })
59 .then(() => {
60 if (this.runOptions.expoHostType !== "local") return false;
61 // 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
62 return XDL.startAdbReverse(this.projectPath);
63 })
64 .then((isAdbReversed) => {
65 switch (this.runOptions.expoHostType) {
66 case "lan":
67 return XDL.getUrl(this.projectPath, { dev: true, minify: false, hostType: "lan" });
68 case "local":
69 if (isAdbReversed) {
70 this.logger.info(localize("ExpoStartAdbReverseSuccess", "A device or an emulator was found, 'adb reverse' command successfully executed."));
71 } else {
72 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."));
73 }
74
75 return XDL.getUrl(this.projectPath, { dev: true, minify: false, hostType: "localhost" });
76 case "tunnel":
77 default:
78 return XDL.getUrl(this.projectPath, { dev: true, minify: false });
79 }
80 })
81 .then(exponentUrl => {
82 return "exp://" + url.parse(exponentUrl).host;
83 })
84 .then(exponentUrl => {
85 if (this.runOptions.openExpoQR) {
86 let exponentPage = vscode.window.createWebviewPanel("Expo QR Code", "Expo QR Code", vscode.ViewColumn.Two, { });
87 exponentPage.webview.html = this.qrCodeContentProvider.provideTextDocumentContent(vscode.Uri.parse(exponentUrl));
88 }
89 return exponentUrl;
90 })
91 .then(exponentUrl => {
92 if (!exponentUrl) {
93 return reject(ErrorHelper.getInternalError(InternalErrorCode.ExpectedExponentTunnelPath));
94 }
95 this.exponentTunnelPath = exponentUrl;
96 const outputMessage = localize("ExponentServerIsRunningOpenToSeeIt", "Expo server is running. Open your Expo app at {0} to see it.", this.exponentTunnelPath);
97 this.logger.info(outputMessage);
98
99 const copyButton = localize("CopyToClipboard", "Copy to clipboard");
100
101 vscode.window.showInformationMessage(outputMessage, copyButton)
102 .then((selection) => {
103 if (selection === copyButton) {
104 vscode.env.clipboard.writeText(exponentUrl);
105 }
106 });
107
108 return resolve();
109 })
110 .catch(reason => {
111 return reject(reason);
112 });
113 });
114 });
115 }
116
117 public loginToExponentOrSkip(expoHostType?: "tunnel" | "lan" | "local"): Promise<any> {
118 if (expoHostType !== "tunnel") {
119 return Promise.resolve();
120 }
121 return this.exponentHelper.loginToExponent(
122 (message, password) => {
123 return new Promise((resolve, reject) => {
124 vscode.window.showInputBox({ placeHolder: message, password: password })
125 .then(login => {
126 resolve(login || "");
127 }, reject);
128 });
129 },
130 (message) => {
131 return new Promise((resolve, reject) => {
132 const okButton = { title: "Ok" };
133 const cancelButton = { title: "Cancel", isCloseAffordance: true };
134 vscode.window.showInformationMessage(message, {modal: true}, okButton, cancelButton)
135 .then(answer => {
136 if (answer === cancelButton) {
137 reject(ErrorHelper.getInternalError(InternalErrorCode.UserCancelledExpoLogin));
138 }
139 resolve("");
140 }, reject);
141 });
142 }
143 );
144 }
145
146 public beforeStartPackager(): Promise<void> {
147 return this.exponentHelper.configureExponentEnvironment();
148 }
149
150 public enableJSDebuggingMode(): Promise<void> {
151 this.logger.info(localize("ApplicationIsRunningOnExponentShakeDeviceForRemoteDebugging", "Application is running on Expo. Please shake device and select 'Debug JS Remotely' to enable debugging."));
152 return Promise.resolve();
153 }
154
155 public getRunArguments(): string[] {
156 return [];
157 }
158}
159