Skip to content

Commit aa063db

Browse files
authored
1 parent 69b546a commit aa063db

8 files changed

Lines changed: 868 additions & 19 deletions

File tree

src/vs/platform/actions/common/actions.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ export const enum MenuId {
9797
StatusBarWindowIndicatorMenu,
9898
TouchBarContext,
9999
TitleBarContext,
100+
TunnelContext,
101+
TunnelInline,
102+
TunnelTitle,
100103
ViewItemContext,
101104
ViewTitle,
102105
CommentThreadTitle,

src/vs/platform/remote/common/tunnel.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,26 @@
55

66
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
77
import { URI } from 'vs/base/common/uri';
8+
import { Event } from 'vs/base/common/event';
89

910
export const ITunnelService = createDecorator<ITunnelService>('tunnelService');
1011

1112
export interface RemoteTunnel {
1213
readonly tunnelRemotePort: number;
1314
readonly tunnelLocalPort: number;
14-
15+
readonly localAddress?: URI;
1516
dispose(): void;
1617
}
1718

1819
export interface ITunnelService {
1920
_serviceBrand: undefined;
2021

2122
readonly tunnels: Promise<readonly RemoteTunnel[]>;
23+
readonly onTunnelOpened: Event<RemoteTunnel>;
24+
readonly onTunnelClosed: Event<number>;
2225

23-
openTunnel(remotePort: number): Promise<RemoteTunnel> | undefined;
26+
openTunnel(remotePort: number, localPort?: number): Promise<RemoteTunnel> | undefined;
27+
closeTunnel(remotePort: number): Promise<void>;
2428
}
2529

2630
export function extractLocalHostUriMetaDataForPortMapping(uri: URI): { address: string, port: number } | undefined {

src/vs/platform/remote/common/tunnelService.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
7+
import { Event, Emitter } from 'vs/base/common/event';
78

89
export class NoOpTunnelService implements ITunnelService {
910
_serviceBrand: undefined;
1011

1112
public readonly tunnels: Promise<readonly RemoteTunnel[]> = Promise.resolve([]);
12-
13+
private _onTunnelOpened: Emitter<RemoteTunnel> = new Emitter();
14+
public onTunnelOpened: Event<RemoteTunnel> = this._onTunnelOpened.event;
15+
private _onTunnelClosed: Emitter<number> = new Emitter();
16+
public onTunnelClosed: Event<number> = this._onTunnelClosed.event;
1317
openTunnel(_remotePort: number): Promise<RemoteTunnel> | undefined {
1418
return undefined;
1519
}
20+
async closeTunnel(_remotePort: number): Promise<void> {
21+
}
1622
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
.customview-tree .tunnel-view-label {
7+
flex: 1;
8+
}
9+
10+
.customview-tree .tunnel-view-label .action-label.codicon {
11+
margin-top: 4px;
12+
}

src/vs/workbench/contrib/remote/browser/remote.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ import { isStringArray } from 'vs/base/common/types';
4444
import { IRemoteExplorerService, HelpInformation } from 'vs/workbench/services/remote/common/remoteExplorerService';
4545
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
4646
import { startsWith } from 'vs/base/common/strings';
47+
import { TunnelPanelDescriptor, TunnelViewModel } from 'vs/workbench/contrib/remote/browser/tunnelView';
48+
import { IAddedViewDescriptorRef } from 'vs/workbench/browser/parts/views/views';
49+
import { ViewletPane } from 'vs/workbench/browser/parts/views/paneViewlet';
4750

4851
class HelpModel {
4952
items: IHelpItem[] | undefined;
@@ -263,6 +266,7 @@ class HelpAction extends Action {
263266

264267
export class RemoteViewlet extends FilterViewContainerViewlet {
265268
private actions: IAction[] | undefined;
269+
private tunnelPanelDescriptor: TunnelPanelDescriptor | undefined;
266270

267271
constructor(
268272
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@@ -274,7 +278,8 @@ export class RemoteViewlet extends FilterViewContainerViewlet {
274278
@IThemeService themeService: IThemeService,
275279
@IContextMenuService contextMenuService: IContextMenuService,
276280
@IExtensionService extensionService: IExtensionService,
277-
@IRemoteExplorerService remoteExplorerService: IRemoteExplorerService
281+
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService,
282+
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
278283
) {
279284
super(VIEWLET_ID, remoteExplorerService.onDidChangeTargetType, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
280285
}
@@ -308,6 +313,17 @@ export class RemoteViewlet extends FilterViewContainerViewlet {
308313
const title = nls.localize('remote.explorer', "Remote Explorer");
309314
return title;
310315
}
316+
317+
onDidAddViews(added: IAddedViewDescriptorRef[]): ViewletPane[] {
318+
// Call to super MUST be first, since registering the additional view will cause this to be called again.
319+
const panels: ViewletPane[] = super.onDidAddViews(added);
320+
if (this.environmentService.configuration.remoteAuthority && !this.tunnelPanelDescriptor && this.configurationService.getValue<boolean>('remote.forwardedPortsView.visible')) {
321+
this.tunnelPanelDescriptor = new TunnelPanelDescriptor(new TunnelViewModel(this.remoteExplorerService), this.environmentService);
322+
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
323+
viewsRegistry.registerViews([this.tunnelPanelDescriptor!], VIEW_CONTAINER);
324+
}
325+
return panels;
326+
}
311327
}
312328

313329
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(ViewletDescriptor.create(

0 commit comments

Comments
 (0)