Skip to content

Commit 659daf8

Browse files
committed
Improve ports view
1 parent 8225b8c commit 659daf8

File tree

3 files changed

+53
-48
lines changed

3 files changed

+53
-48
lines changed

extensions/gitpod-web/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@
415415
"remote": [
416416
{
417417
"id": "gitpod.workspace",
418-
"name": "Gitpod Workspace"
418+
"name": "Gitpod Workspace",
419+
"when": "!gitpod.portsView.visible"
419420
}
420421
],
421422
"portsView": [
@@ -425,7 +426,6 @@
425426
"type": "webview",
426427
"contextualTitle": "",
427428
"icon": "$(plug)",
428-
"visibility": "visible",
429429
"when": "gitpod.portsView.visible"
430430
}
431431
]
@@ -517,7 +517,7 @@
517517
{
518518
"id": "portsView",
519519
"title": "Ports",
520-
"icon": ""
520+
"icon": "$(plug)"
521521
}
522522
]
523523
}

extensions/gitpod-web/portsview/src/App.svelte

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@
1111
1212
window.addEventListener("message", (event) => {
1313
if (event.data.command === "updatePorts") {
14-
// TODO: sort with status first, then port number?
15-
ports = event.data.ports.sort(
16-
(a: GitpodPortObject, b: GitpodPortObject) =>
17-
a.status.localPort - b.status.localPort
18-
);
14+
ports = event.data.ports;
1915
}
2016
});
2117
vscode.postMessage({ command: "queryPortData" });

extensions/gitpod-web/src/extension.ts

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ type GitpodWorkspaceElement = PortsTreeItem | PortTreeItem;
284284
export class GitpodWorkspaceTreeDataProvider implements vscode.TreeDataProvider<GitpodWorkspaceElement> {
285285

286286
readonly ports = new PortsTreeItem('Ports', vscode.TreeItemCollapsibleState.Expanded);
287-
readonly portViewNotice = new PortsTreeItem('Please try new Ports view and provide your feedback', vscode.TreeItemCollapsibleState.None);
288287

289288
protected readonly onDidChangeTreeDataEmitter = new vscode.EventEmitter<GitpodWorkspaceElement | undefined>();
290289
readonly onDidChangeTreeData = this.onDidChangeTreeDataEmitter.event;
@@ -293,12 +292,11 @@ export class GitpodWorkspaceTreeDataProvider implements vscode.TreeDataProvider<
293292
readonly onDidExposeServedPort = this.onDidExposeServedPortEmitter.event;
294293

295294

296-
constructor(private readonly context: GitpodExtensionContext, private readonly isPortsViewExperimentEnable?: boolean) {
297-
this.portViewNotice.iconPath = new vscode.ThemeIcon('info', new vscode.ThemeColor('foreground'));
298-
this.portViewNotice.command = {
299-
title: '',
300-
command: 'gitpod.portsView.focus'
301-
};
295+
constructor(private readonly context: GitpodExtensionContext, private isPortsViewExperimentEnable?: boolean) { }
296+
297+
updateIsPortsViewExperimentEnable(value: boolean) {
298+
this.isPortsViewExperimentEnable = value;
299+
this.onDidChangeTreeDataEmitter.fire(undefined);
302300
}
303301

304302
getTreeItem(element: GitpodWorkspaceElement): vscode.TreeItem {
@@ -310,11 +308,7 @@ export class GitpodWorkspaceTreeDataProvider implements vscode.TreeDataProvider<
310308
return [this.ports];
311309
}
312310
if (element === this.ports) {
313-
const list: GitpodWorkspaceElement[] = [...this.ports.ports.values()];
314-
if (this.isPortsViewExperimentEnable) {
315-
list.unshift(this.portViewNotice);
316-
}
317-
return list;
311+
return [...this.ports.ports.values()];
318312
}
319313
return [];
320314
}
@@ -432,11 +426,6 @@ export class GitpodPortViewProvider implements vscode.WebviewViewProvider {
432426
const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this.context.extensionUri, 'portsview', 'public', 'bundle.js'));
433427
const styleUri = webview.asWebviewUri(vscode.Uri.joinPath(this.context.extensionUri, 'portsview', 'public', 'bundle.css'));
434428
const nonce = getNonce();
435-
// <meta
436-
// csp-nonce
437-
// http-equiv="Content-Security-Policy"
438-
// content="default-src 'none'; img-src data: ${webview.cspSource}; font-src ${webview.cspSource}; style-src ${webview.cspSource} 'nonce-${nonce}'; script-src 'nonce-${nonce}';"
439-
// />
440429
return `<!DOCTYPE html>
441430
<html lang="en">
442431
<head>
@@ -527,8 +516,7 @@ export function getNonce() {
527516
interface PortItem { port: GitpodWorkspacePort; isWebview?: boolean }
528517

529518
export function registerPorts(context: GitpodExtensionContext): void {
530-
const experimentCfg = vscode.workspace.getConfiguration('gitpod.experimental');
531-
const isPortsViewExperimentEnable = experimentCfg.get<boolean>('portsView.enabled');
519+
const isPortsViewExperimentEnable = vscode.workspace.getConfiguration('gitpod.experimental.portsView').get<boolean>('enabled');
532520

533521
const portMap = new Map<number, GitpodWorkspacePort>();
534522
const tunnelMap = new Map<number, vscode.TunnelDescription>();
@@ -539,12 +527,27 @@ export function registerPorts(context: GitpodExtensionContext): void {
539527
context.subscriptions.push(treeView);
540528

541529
// register webview
542-
let portViewProvider: GitpodPortViewProvider | undefined;
543-
if (isPortsViewExperimentEnable) {
544-
vscode.commands.executeCommand('setContext', 'gitpod.portsView.visible', true);
545-
portViewProvider = new GitpodPortViewProvider(context);
546-
context.subscriptions.push(vscode.window.registerWebviewViewProvider(GitpodPortViewProvider.viewType, portViewProvider, { webviewOptions: { retainContextWhenHidden: true } }));
547-
}
530+
const portViewProvider = new GitpodPortViewProvider(context);
531+
context.subscriptions.push(vscode.window.registerWebviewViewProvider(GitpodPortViewProvider.viewType, portViewProvider, { webviewOptions: { retainContextWhenHidden: true } }));
532+
533+
// new Ports view - try it out
534+
let hasShownTryItOut = false;
535+
treeView.onDidChangeVisibility(async (e) => {
536+
const config = vscode.workspace.getConfiguration('gitpod.experimental.portsView');
537+
if (hasShownTryItOut || !e.visible || config.get<boolean>('enabled') || config.get<boolean>('neverPrompt') === true) {
538+
return;
539+
}
540+
hasShownTryItOut = true;
541+
const openAction = 'Open';
542+
const neverAgain = 'Don\'t Show Again';
543+
const action = await vscode.window.showInformationMessage('Do you want to try with our new experimental Ports view?', openAction, neverAgain);
544+
if (action === openAction) {
545+
config.update('enabled', true, true);
546+
setTimeout(() => vscode.commands.executeCommand('gitpod.portsView.focus'), 2000);
547+
} else if (action === neverAgain) {
548+
config.update('neverPrompt', true, true);
549+
}
550+
});
548551

549552
function openExternal(port: GitpodWorkspacePort) {
550553
return vscode.env.openExternal(vscode.Uri.parse(port.localUrl));
@@ -570,7 +573,7 @@ export function registerPorts(context: GitpodExtensionContext): void {
570573
const portNumber = e.getLocalPort();
571574
portMap.set(portNumber, new GitpodWorkspacePort(portNumber, context, e, tunnelMap.get(portNumber)));
572575
});
573-
portViewProvider?.updatePortsStatus(update);
576+
portViewProvider.updatePortsStatus(update);
574577
gitpodWorkspaceTreeDataProvider.updatePortsStatus(update);
575578
});
576579
});
@@ -607,8 +610,8 @@ export function registerPorts(context: GitpodExtensionContext): void {
607610
return false;
608611
};
609612
if (!tryResolve()) {
610-
const listenerWebview = portViewProvider?.onDidChangePorts(element => {
611-
if (element === portViewProvider?.portMap && tryResolve()) {
613+
const listenerWebview = portViewProvider.onDidChangePorts(element => {
614+
if (element === portViewProvider.portMap && tryResolve()) {
612615
listenerWebview?.dispose();
613616
}
614617
});
@@ -694,15 +697,13 @@ export function registerPorts(context: GitpodExtensionContext): void {
694697

695698
portsStatusBarItem.text = text;
696699
portsStatusBarItem.tooltip = tooltip;
700+
const isPortsViewExperimentEnable = vscode.workspace.getConfiguration('gitpod.experimental.portsView').get<boolean>('enabled');
697701
portsStatusBarItem.command = isPortsViewExperimentEnable ? 'gitpod.portsView.focus' : 'gitpod.ports.reveal';
698702
portsStatusBarItem.show();
699703
}
700704
updateStatusBar();
701-
if (isPortsViewExperimentEnable && !!portViewProvider) {
702-
context.subscriptions.push(portViewProvider.onDidChangePorts(() => updateStatusBar()));
703-
} else {
704-
context.subscriptions.push(gitpodWorkspaceTreeDataProvider.onDidChangeTreeData(() => updateStatusBar()));
705-
}
705+
706+
context.subscriptions.push(portViewProvider.onDidChangePorts(() => updateStatusBar()));
706707
context.subscriptions.push(gitpodWorkspaceTreeDataProvider.onDidChangeTreeData(() => updateStatusBar()));
707708

708709
context.subscriptions.push(vscode.commands.registerCommand('gitpod.ports.reveal', () => {
@@ -745,11 +746,7 @@ export function registerPorts(context: GitpodExtensionContext): void {
745746
preserveFocus: true
746747
});
747748
}
748-
let provider: GitpodWorkspaceTreeDataProvider | GitpodPortViewProvider = gitpodWorkspaceTreeDataProvider;
749-
if (isPortsViewExperimentEnable && !!portViewProvider) {
750-
provider = portViewProvider;
751-
}
752-
context.subscriptions.push(provider.onDidExposeServedPort(port => {
749+
const onDidExposeServedPortListener = (port: ExposedServedGitpodWorkspacePort) => {
753750
if (port.status.exposed.onExposed === OnPortExposedAction.IGNORE) {
754751
return;
755752
}
@@ -773,7 +770,9 @@ export function registerPorts(context: GitpodExtensionContext): void {
773770
showOpenServiceNotification(port, port.status.exposed.visibility !== PortVisibility.PUBLIC);
774771
return;
775772
}
776-
}));
773+
};
774+
context.subscriptions.push(gitpodWorkspaceTreeDataProvider.onDidExposeServedPort(onDidExposeServedPortListener));
775+
context.subscriptions.push(portViewProvider.onDidExposeServedPort(onDidExposeServedPortListener));
777776

778777
let updateTunnelsTokenSource: vscode.CancellationTokenSource | undefined;
779778
async function updateTunnels(): Promise<void> {
@@ -791,7 +790,7 @@ export function registerPorts(context: GitpodExtensionContext): void {
791790
currentTunnels.forEach(tunnel => {
792791
tunnelMap.set(tunnel.remoteAddress.port, tunnel);
793792
});
794-
portViewProvider?.updateTunnels(tunnelMap);
793+
portViewProvider.updateTunnels(tunnelMap);
795794
gitpodWorkspaceTreeDataProvider.updateTunnels(tunnelMap);
796795
}
797796
updateTunnels();
@@ -839,6 +838,16 @@ export function registerPorts(context: GitpodExtensionContext): void {
839838
vscode.commands.executeCommand('gitpod.api.connectLocalApp', apiPort);
840839
}
841840
}));
841+
vscode.workspace.onDidChangeConfiguration((e: vscode.ConfigurationChangeEvent) => {
842+
if (!e.affectsConfiguration('gitpod.experimental.portsView.enabled')) {
843+
return;
844+
}
845+
const isPortsViewExperimentEnable = vscode.workspace.getConfiguration('gitpod.experimental.portsView').get<boolean>('enabled');
846+
vscode.commands.executeCommand('setContext', 'gitpod.portsView.visible', isPortsViewExperimentEnable);
847+
gitpodWorkspaceTreeDataProvider.updateIsPortsViewExperimentEnable(isPortsViewExperimentEnable ?? false);
848+
updateStatusBar();
849+
});
850+
vscode.commands.executeCommand('setContext', 'gitpod.portsView.visible', isPortsViewExperimentEnable);
842851
}
843852

844853
export function registerWelcomeWalkthroughCommands(context: GitpodExtensionContext): void {

0 commit comments

Comments
 (0)