Skip to content
This repository was archived by the owner on Dec 23, 2021. It is now read-only.

Commit 9a667a8

Browse files
Merge pull request #258 from microsoft/users/t-xunguy/getting-started
Getting started page from command palette
2 parents e897b84 + 61f0a11 commit 9a667a8

File tree

15 files changed

+3602
-4774
lines changed

15 files changed

+3602
-4774
lines changed

locales/en/package.i18n.json

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
{
2-
"deviceSimulatorExpressExtension.commands.common.installDependencies": "Install Extension Dependencies",
3-
"deviceSimulatorExpressExtension.commands.common.label": "Device Simulator Express",
4-
"deviceSimulatorExpressExtension.commands.common.runSimulator": "Run Simulator",
5-
"deviceSimulatorExpressExtension.commands.common.changeBaudRate": "Change Baud Rate",
6-
"deviceSimulatorExpressExtension.commands.common.closeSerialMonitor": "Close Serial Monitor",
7-
"deviceSimulatorExpressExtension.commands.common.openSerialMonitor": "Open Serial Monitor",
8-
"deviceSimulatorExpressExtension.commands.common.selectSerialPort": "Select Serial Port",
9-
"deviceSimulatorExpressExtension.commands.cpx.openSimulator": "[Circuit Playground Express] Open Simulator",
10-
"deviceSimulatorExpressExtension.commands.cpx.newFile": "[Circuit Playground Express] New File",
11-
"deviceSimulatorExpressExtension.commands.cpx.deployToDevice": "[Circuit Playground Express] Deploy to Device",
12-
"deviceSimulatorExpressExtension.commands.microbit.deployToDevice": "[micro:bit] Deploy to Device",
13-
"deviceSimulatorExpressExtension.commands.microbit.openSimulator": "[micro:bit] Open Simulator",
14-
"deviceSimulatorExpressExtension.commands.microbit.newFile": "[micro:bit] New File",
15-
"deviceSimulatorExpressExtension.configuration.title": "Device Simulator Express configuration",
16-
"deviceSimulatorExpressExtension.configuration.properties.configEnvOnChange": "When you change the Python interpreter, the Device Simulator Express will automatically configure itself for the required dependencies.",
17-
"deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger.",
18-
"deviceSimulatorExpressExtension.configuration.properties.dependencyChecker": "Whether or not to ask if we can download dependencies. If unchecked, the extension will default to never download dependencies, except when automatically creating a virtual environment in the extension files."
2+
"deviceSimulatorExpressExtension.commands.common.installDependencies": "Install Extension Dependencies",
3+
"deviceSimulatorExpressExtension.commands.common.label": "Device Simulator Express",
4+
"deviceSimulatorExpressExtension.commands.common.runSimulator": "Run Simulator",
5+
"deviceSimulatorExpressExtension.commands.common.gettingStarted": "Getting Started",
6+
7+
"deviceSimulatorExpressExtension.commands.common.changeBaudRate": "Change Baud Rate",
8+
"deviceSimulatorExpressExtension.commands.common.closeSerialMonitor": "Close Serial Monitor",
9+
"deviceSimulatorExpressExtension.commands.common.openSerialMonitor": "Open Serial Monitor",
10+
"deviceSimulatorExpressExtension.commands.common.selectSerialPort": "Select Serial Port",
11+
"deviceSimulatorExpressExtension.commands.cpx.openSimulator": "[Circuit Playground Express] Open Simulator",
12+
"deviceSimulatorExpressExtension.commands.cpx.newFile": "[Circuit Playground Express] New File",
13+
"deviceSimulatorExpressExtension.commands.cpx.deployToDevice": "[Circuit Playground Express] Deploy to Device",
14+
"deviceSimulatorExpressExtension.commands.microbit.deployToDevice": "[micro:bit] Deploy to Device",
15+
"deviceSimulatorExpressExtension.commands.microbit.openSimulator": "[micro:bit] Open Simulator",
16+
"deviceSimulatorExpressExtension.commands.microbit.newFile": "[micro:bit] New File",
17+
"deviceSimulatorExpressExtension.configuration.title": "Device Simulator Express configuration",
18+
"deviceSimulatorExpressExtension.configuration.properties.configEnvOnChange": "When you change the Python interpreter, the Device Simulator Express will automatically configure itself for the required dependencies.",
19+
"deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger.",
20+
"deviceSimulatorExpressExtension.configuration.properties.dependencyChecker": "Whether or not to ask if we can download dependencies. If unchecked, the extension will default to never download dependencies, except when automatically creating a virtual environment in the extension files."
1921
}

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"onCommand:deviceSimulatorExpress.common.openSerialMonitor",
3535
"onCommand:deviceSimulatorExpress.common.runSimulator",
3636
"onCommand:deviceSimulatorExpress.common.selectSerialPort",
37+
"onCommand:deviceSimulatorExpress.common.gettingStarted",
3738
"onCommand:deviceSimulatorExpress.cpx.deployToDevice",
3839
"onCommand:deviceSimulatorExpress.cpx.newFile",
3940
"onCommand:deviceSimulatorExpress.cpx.openSimulator",
@@ -75,6 +76,11 @@
7576
"title": "%deviceSimulatorExpressExtension.commands.common.runSimulator%",
7677
"category": "%deviceSimulatorExpressExtension.commands.common.label%"
7778
},
79+
{
80+
"command": "deviceSimulatorExpress.common.gettingStarted",
81+
"title": "%deviceSimulatorExpressExtension.commands.common.gettingStarted%",
82+
"category": "%deviceSimulatorExpressExtension.commands.common.label%"
83+
},
7884
{
7985
"command": "deviceSimulatorExpress.cpx.deployToDevice",
8086
"title": "%deviceSimulatorExpressExtension.commands.cpx.deployToDevice%",

package.nls.json

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
{
2-
"deviceSimulatorExpressExtension.commands.common.installDependencies": "Install Extension Dependencies",
3-
"deviceSimulatorExpressExtension.commands.common.label": "Device Simulator Express",
4-
"deviceSimulatorExpressExtension.commands.common.runSimulator": "Run Simulator",
5-
"deviceSimulatorExpressExtension.commands.common.changeBaudRate": "Change Baud Rate",
6-
"deviceSimulatorExpressExtension.commands.common.closeSerialMonitor": "Close Serial Monitor",
7-
"deviceSimulatorExpressExtension.commands.common.openSerialMonitor": "Open Serial Monitor",
8-
"deviceSimulatorExpressExtension.commands.common.selectSerialPort": "Select Serial Port",
9-
"deviceSimulatorExpressExtension.commands.cpx.openSimulator": "[Circuit Playground Express] Open Simulator",
10-
"deviceSimulatorExpressExtension.commands.cpx.newFile": "[Circuit Playground Express] New File",
11-
"deviceSimulatorExpressExtension.commands.cpx.deployToDevice": "[Circuit Playground Express] Deploy to Device",
12-
"deviceSimulatorExpressExtension.commands.microbit.deployToDevice": "[micro:bit] Deploy to Device",
13-
"deviceSimulatorExpressExtension.commands.microbit.openSimulator": "[micro:bit] Open Simulator",
14-
"deviceSimulatorExpressExtension.commands.microbit.newFile": "[micro:bit] New File",
15-
"deviceSimulatorExpressExtension.configuration.title": "Device Simulator Express configuration",
16-
"deviceSimulatorExpressExtension.configuration.properties.configEnvOnChange": "When you change the Python interpreter, the Device Simulator Express will automatically configure itself for the required dependencies.",
17-
"deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger.",
18-
"deviceSimulatorExpressExtension.configuration.properties.dependencyChecker": "Whether or not to ask for dependency downloads. If unchecked, the extension will default to never download dependencies, except when automatically creating a virtual environment in the extension files."
2+
"deviceSimulatorExpressExtension.commands.common.installDependencies": "Install Extension Dependencies",
3+
"deviceSimulatorExpressExtension.commands.common.label": "Device Simulator Express",
4+
"deviceSimulatorExpressExtension.commands.common.runSimulator": "Run Simulator",
5+
"deviceSimulatorExpressExtension.commands.common.gettingStarted": "Getting Started",
6+
7+
"deviceSimulatorExpressExtension.commands.common.changeBaudRate": "Change Baud Rate",
8+
"deviceSimulatorExpressExtension.commands.common.closeSerialMonitor": "Close Serial Monitor",
9+
"deviceSimulatorExpressExtension.commands.common.openSerialMonitor": "Open Serial Monitor",
10+
"deviceSimulatorExpressExtension.commands.common.selectSerialPort": "Select Serial Port",
11+
"deviceSimulatorExpressExtension.commands.cpx.openSimulator": "[Circuit Playground Express] Open Simulator",
12+
"deviceSimulatorExpressExtension.commands.cpx.newFile": "[Circuit Playground Express] New File",
13+
"deviceSimulatorExpressExtension.commands.cpx.deployToDevice": "[Circuit Playground Express] Deploy to Device",
14+
"deviceSimulatorExpressExtension.commands.microbit.deployToDevice": "[micro:bit] Deploy to Device",
15+
"deviceSimulatorExpressExtension.commands.microbit.openSimulator": "[micro:bit] Open Simulator",
16+
"deviceSimulatorExpressExtension.commands.microbit.newFile": "[micro:bit] New File",
17+
"deviceSimulatorExpressExtension.configuration.title": "Device Simulator Express configuration",
18+
"deviceSimulatorExpressExtension.configuration.properties.configEnvOnChange": "When you change the Python interpreter, the Device Simulator Express will automatically configure itself for the required dependencies.",
19+
"deviceSimulatorExpressExtension.configuration.properties.debuggerPort": "The port the Server will listen on for communication with the debugger.",
20+
"deviceSimulatorExpressExtension.configuration.properties.dependencyChecker": "Whether or not to ask for dependency downloads. If unchecked, the extension will default to never download dependencies, except when automatically creating a virtual environment in the extension files."
1921
}

src/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ export const CONFIG = {
2525
};
2626

2727
export const CONSTANTS = {
28+
WEBVIEW_TYPE: {
29+
SIMULATOR: "simulator",
30+
TUTORIAL: "tutorial",
31+
},
2832
DEBUG_CONFIGURATION_TYPE: "deviceSimulatorExpress",
2933
DEVICE_NAME: {
3034
CPX: "CPX",
@@ -320,6 +324,7 @@ export enum TelemetryEventName {
320324
COMMAND_SERIAL_MONITOR_OPEN = "COMMAND.SERIAL_MONITOR.OPEN",
321325
COMMAND_SERIAL_MONITOR_BAUD_RATE = "COMMAND.SERIAL_MONITOR.BAUD_RATE",
322326
COMMAND_SERIAL_MONITOR_CLOSE = "COMMAND.SERIAL_MONITOR.CLOSE",
327+
COMMAND_GETTING_STARTED = "COMMAND.GETTING_STARTED",
323328

324329
CPX_COMMAND_DEPLOY_DEVICE = "CPX.COMMAND.DEPLOY.DEVICE",
325330
CPX_COMMAND_NEW_FILE = "CPX.COMMAND.NEW.FILE.CPX",

src/extension.ts

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurati
3535
import getPackageInfo from "./telemetry/getPackageInfo";
3636
import TelemetryAI from "./telemetry/telemetryAI";
3737
import { UsbDetector } from "./usbDetector";
38-
import { VSCODE_MESSAGES_TO_WEBVIEW, WEBVIEW_MESSAGES } from "./view/constants";
38+
import {
39+
VSCODE_MESSAGES_TO_WEBVIEW,
40+
WEBVIEW_MESSAGES,
41+
WEBVIEW_TYPES,
42+
} from "./view/constants";
43+
import { WebviewService } from "./service/webviewService";
3944

4045
let telemetryAI: TelemetryAI;
4146
let pythonExecutablePath: string = GLOBAL_ENV_VARS.PYTHON;
@@ -53,14 +58,6 @@ const fileSelectionService = new FileSelectionService(messagingService);
5358

5459
export let outChannel: vscode.OutputChannel | undefined;
5560

56-
function loadScript(context: vscode.ExtensionContext, scriptPath: string) {
57-
return `<script initialDevice=${deviceSelectionService.getCurrentActiveDevice()} src="${vscode.Uri.file(
58-
context.asAbsolutePath(scriptPath)
59-
)
60-
.with({ scheme: "vscode-resource" })
61-
.toString()}"></script>`;
62-
}
63-
6461
const sendCurrentDeviceMessage = (currentPanel: vscode.WebviewPanel) => {
6562
if (currentPanel) {
6663
currentPanel.webview.postMessage({
@@ -71,14 +68,13 @@ const sendCurrentDeviceMessage = (currentPanel: vscode.WebviewPanel) => {
7168
};
7269
// Extension activation
7370
export async function activate(context: vscode.ExtensionContext) {
74-
console.info(CONSTANTS.INFO.EXTENSION_ACTIVATED);
75-
7671
telemetryAI = new TelemetryAI(context);
7772
setupService = new SetupService(telemetryAI);
7873
let currentPanel: vscode.WebviewPanel | undefined;
7974
let childProcess: cp.ChildProcess | undefined;
8075
let messageListener: vscode.Disposable;
8176
let activeEditorListener: vscode.Disposable;
77+
const webviewService = new WebviewService(context, deviceSelectionService);
8278

8379
// Add our library path to settings.json for autocomplete functionality
8480
updatePythonExtraPaths();
@@ -130,7 +126,7 @@ export async function activate(context: vscode.ExtensionContext) {
130126
currentPanel.reveal(vscode.ViewColumn.Beside);
131127
} else {
132128
currentPanel = vscode.window.createWebviewPanel(
133-
"adafruitSimulator",
129+
CONSTANTS.WEBVIEW_TYPE.SIMULATOR,
134130
CONSTANTS.LABEL.WEBVIEW_PANEL,
135131
{ preserveFocus: true, viewColumn: vscode.ViewColumn.Beside },
136132
{
@@ -147,7 +143,10 @@ export async function activate(context: vscode.ExtensionContext) {
147143
}
148144
);
149145

150-
currentPanel.webview.html = getWebviewContent(context);
146+
currentPanel.webview.html = webviewService.getWebviewContent(
147+
WEBVIEW_TYPES.SIMULATOR,
148+
true
149+
);
151150
messagingService.setWebview(currentPanel.webview);
152151

153152
if (messageListener !== undefined) {
@@ -303,6 +302,16 @@ export async function activate(context: vscode.ExtensionContext) {
303302
openWebview();
304303
};
305304

305+
const gettingStartedOpen: vscode.Disposable = vscode.commands.registerCommand(
306+
"deviceSimulatorExpress.common.gettingStarted",
307+
() => {
308+
telemetryAI.trackFeatureUsage(
309+
TelemetryEventName.COMMAND_GETTING_STARTED
310+
);
311+
webviewService.openTutorialPanel();
312+
}
313+
);
314+
306315
// Open Simulator on the webview
307316
const cpxOpenSimulator: vscode.Disposable = vscode.commands.registerCommand(
308317
"deviceSimulatorExpress.cpx.openSimulator",
@@ -1059,6 +1068,7 @@ export async function activate(context: vscode.ExtensionContext) {
10591068
microbitOpenSimulator,
10601069
microbitNewFile,
10611070
microbitDeployToDevice,
1071+
gettingStartedOpen,
10621072
vscode.debug.registerDebugConfigurationProvider(
10631073
CONSTANTS.DEBUG_CONFIGURATION_TYPE,
10641074
simulatorDebugConfiguration
@@ -1321,27 +1331,6 @@ const updateConfigLists = (
13211331
.update(section, Array.from(extraItemsSet), scope);
13221332
};
13231333

1324-
function getWebviewContent(context: vscode.ExtensionContext) {
1325-
return `<!DOCTYPE html>
1326-
<html lang="en">
1327-
<head>
1328-
<meta charset="UTF-8">
1329-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
1330-
1331-
<title>${CONSTANTS.NAME}</title>
1332-
</head>
1333-
<body>
1334-
<div id="root"></div>
1335-
<script >
1336-
const vscode = acquireVsCodeApi();
1337-
</script>
1338-
<script ></script>
1339-
${loadScript(context, "out/vendor.js")}
1340-
${loadScript(context, "out/simulator.js")}
1341-
</body>
1342-
</html>`;
1343-
}
1344-
13451334
// this method is called when your extension is deactivated
13461335
export async function deactivate() {
13471336
const monitor: SerialMonitor = SerialMonitor.getInstance();

src/service/webviewService.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import * as path from "path";
2+
import * as vscode from "vscode";
3+
import CONSTANTS from "../constants";
4+
import { WEBVIEW_ATTRIBUTES_KEY, WEBVIEW_TYPES } from "../view/constants";
5+
import { DeviceSelectionService } from "./deviceSelectionService";
6+
7+
// Manages different type of webview
8+
export class WebviewService {
9+
private tutorialPanel: vscode.WebviewPanel | undefined;
10+
private context: vscode.ExtensionContext;
11+
private deviceSelectionService: DeviceSelectionService;
12+
13+
constructor(
14+
context: vscode.ExtensionContext,
15+
deviceSelectionService: DeviceSelectionService
16+
) {
17+
this.context = context;
18+
this.deviceSelectionService = deviceSelectionService;
19+
}
20+
21+
public openTutorialPanel() {
22+
if (this.tutorialPanel) {
23+
this.tutorialPanel.reveal(vscode.ViewColumn.Beside);
24+
} else {
25+
this.createTutorialPanel();
26+
}
27+
}
28+
29+
public getWebviewContent(webviewType: string, hasDevice: boolean) {
30+
return `<!DOCTYPE html>
31+
<html lang="en">
32+
<head>
33+
<meta charset="UTF-8">
34+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
35+
36+
<title>${CONSTANTS.NAME}</title>
37+
</head>
38+
<body>
39+
<div id="root"></div>
40+
<script >
41+
const vscode = acquireVsCodeApi();
42+
</script>
43+
<script ></script>
44+
${this.loadScript(
45+
this.context,
46+
webviewType,
47+
"out/vendor.js",
48+
hasDevice
49+
)}
50+
${this.loadScript(
51+
this.context,
52+
webviewType,
53+
"out/simulator.js",
54+
hasDevice
55+
)}
56+
</body>
57+
</html>`;
58+
}
59+
60+
private createTutorialPanel() {
61+
this.tutorialPanel = vscode.window.createWebviewPanel(
62+
CONSTANTS.WEBVIEW_TYPE.TUTORIAL,
63+
CONSTANTS.LABEL.WEBVIEW_PANEL,
64+
{ preserveFocus: true, viewColumn: vscode.ViewColumn.One },
65+
{
66+
enableScripts: true,
67+
}
68+
);
69+
this.tutorialPanel.webview.html = this.getWebviewContent(
70+
WEBVIEW_TYPES.GETTING_STARTED,
71+
false
72+
);
73+
this.tutorialPanel.onDidDispose(() => {
74+
this.disposeTutorialPanel();
75+
});
76+
}
77+
78+
private disposeTutorialPanel() {
79+
this.tutorialPanel = undefined;
80+
}
81+
82+
private loadScript(
83+
context: vscode.ExtensionContext,
84+
attributeValue: string,
85+
scriptPath: string,
86+
hasDevice: boolean
87+
) {
88+
let attributeString: string;
89+
if (hasDevice) {
90+
attributeString = `${
91+
WEBVIEW_ATTRIBUTES_KEY.TYPE
92+
}=${attributeValue} ${
93+
WEBVIEW_ATTRIBUTES_KEY.INITIAL_DEVICE
94+
}=${this.deviceSelectionService.getCurrentActiveDevice()}`;
95+
} else {
96+
attributeString = `${WEBVIEW_ATTRIBUTES_KEY.TYPE}=${attributeValue} `;
97+
}
98+
return `<script ${attributeString} src="${vscode.Uri.file(
99+
context.asAbsolutePath(scriptPath)
100+
)
101+
.with({ scheme: "vscode-resource" })
102+
.toString()}"></script>`;
103+
}
104+
}

0 commit comments

Comments
 (0)