Skip to content

Commit 9a694a8

Browse files
AlexTugarevsvenefftinge
authored andcommitted
extract getGitpodService function
1 parent f932dfa commit 9a694a8

File tree

10 files changed

+71
-63
lines changed

10 files changed

+71
-63
lines changed

components/dashboard/src/App.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { CreateWorkspace } from './start/CreateWorkspace';
77
import StartWorkspace from './start/StartWorkspace';
88
import { Login } from './Login';
99
import { UserContext } from './user-context';
10-
import { gitpodService } from './service/service';
10+
import { getGitpodService } from './service/service';
1111

1212
const Account = React.lazy(() => import('./settings/Account'));
1313
const Notifications = React.lazy(() => import('./settings/Notifications'));
@@ -28,8 +28,7 @@ function App() {
2828
useEffect(() => {
2929
(async () => {
3030
try {
31-
const user = await gitpodService.server.getLoggedInUser();
32-
setUser(user);
31+
setUser(await getGitpodService().server.getLoggedInUser());
3332
} catch (error) {
3433
console.log(error);
3534
}
@@ -38,7 +37,7 @@ function App() {
3837
}, []);
3938

4039
if (!loading && !user) {
41-
return (<Login gitpodService={gitpodService} />)
40+
return (<Login />)
4241
};
4342

4443
window.addEventListener("hashchange", () => {
@@ -50,10 +49,10 @@ function App() {
5049

5150
const hash = getURLHash();
5251
if (window.location.pathname === '/' && hash !== '') {
53-
return <CreateWorkspace contextUrl={hash} gitpodService={gitpodService}/>;
52+
return <CreateWorkspace contextUrl={hash} />;
5453
}
5554
if (/\/start\/?/.test(window.location.pathname) && hash !== '') {
56-
return <StartWorkspace workspaceId={hash} gitpodService={gitpodService}/>;
55+
return <StartWorkspace workspaceId={hash} />;
5756
}
5857

5958
return (
@@ -68,7 +67,7 @@ function App() {
6867
{user && (
6968
<React.Fragment>
7069
<Route path={["/", "/workspaces"]} exact render={
71-
() => <Workspaces gitpodService={gitpodService} />} />
70+
() => <Workspaces />} />
7271
<Route path="/account" exact component={Account} />
7372
<Route path="/notifications" exact component={Notifications} />
7473
<Route path="/plans" exact component={Plans} />

components/dashboard/src/Login.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { AuthProviderInfo } from "@gitpod/gitpod-protocol";
22
import { useContext, useEffect, useState } from "react";
33
import { UserContext } from "./user-context";
4-
import { gitpodHostUrl } from "./service/service";
4+
import { getGitpodService, gitpodHostUrl, reconnectGitpodService } from "./service/service";
55

6-
export function Login({ gitpodService }: { gitpodService: GitpodService }) {
6+
export function Login() {
77
const { setUser } = useContext(UserContext);
88

99
const [authProviders, setAuthProviders] = useState<AuthProviderInfo[]>([]);
1010

1111
useEffect(() => {
1212
(async () => {
13-
setAuthProviders(await gitpodService.server.getAuthProviders());
13+
setAuthProviders(await getGitpodService().server.getAuthProviders());
1414
})();
1515

1616
window.addEventListener("message", (event) => {
@@ -24,9 +24,8 @@ export function Login({ gitpodService }: { gitpodService: GitpodService }) {
2424
// todo: not here, but add a button to the /login-success page to close, if this should not work as expected
2525
}
2626
(async () => {
27-
gitpodService.reconnect();
28-
const user = await gitpodService.server.getLoggedInUser();
29-
setUser(user);
27+
reconnectGitpodService();
28+
setUser(await getGitpodService().server.getLoggedInUser());
3029
})();
3130
}
3231
})

components/dashboard/src/service/service-mock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const gitpodServiceMock = createServiceMock({
4444
onDidOpenConnection: Event.None,
4545
onDidCloseConnection: Event.None,
4646

47-
}) as GitpodService;
47+
});
4848

4949
export { gitpodServiceMock };
5050

components/dashboard/src/service/service.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,17 @@
44
* See License-AGPL.txt in the project root for license information.
55
*/
66

7-
import { GitpodClient, GitpodServer, GitpodServerPath, GitpodServiceImpl } from '@gitpod/gitpod-protocol';
7+
import { GitpodClient, GitpodServer, GitpodServerPath, GitpodService, GitpodServiceImpl } from '@gitpod/gitpod-protocol';
88
import { WebSocketConnectionProvider } from '@gitpod/gitpod-protocol/lib/messaging/browser/connection';
99
// import { createWindowMessageConnection } from '@gitpod/gitpod-protocol/lib/messaging/browser/window-connection';
10-
import { JsonRpcProxy /* , JsonRpcProxyFactory */ } from '@gitpod/gitpod-protocol/lib/messaging/proxy-factory';
10+
// import { JsonRpcProxy /* , JsonRpcProxyFactory */ } from '@gitpod/gitpod-protocol/lib/messaging/proxy-factory';
1111
import { GitpodHostUrl } from '@gitpod/gitpod-protocol/lib/util/gitpod-host-url';
1212
import { log } from '@gitpod/gitpod-protocol/lib/util/logging';
13-
// import { gitpodServiceMock } from './service-mock';
1413

1514
export const gitpodHostUrl = new GitpodHostUrl(window.location.toString());
1615

1716
function createGitpodService<C extends GitpodClient, S extends GitpodServer>() {
18-
let proxy: JsonRpcProxy<S>;
19-
let reconnect = () => {
20-
console.log("WebSocket reconnect not possible.");
21-
}
17+
// let proxy: JsonRpcProxy<S>;
2218
// FIXME: https://gitpod.slack.com/archives/C01KGM9BUNS/p1615456669011600
2319
// if (window.top !== window.self) {
2420
// const connection = createWindowMessageConnection('gitpodServer', window.parent, '*');
@@ -32,15 +28,8 @@ function createGitpodService<C extends GitpodClient, S extends GitpodServer>() {
3228
.withApi();
3329

3430
const connectionProvider = new WebSocketConnectionProvider();
35-
let _websocket: any;
36-
const _createWebSocket = connectionProvider.createWebSocket;
37-
connectionProvider.createWebSocket = (url) => {
38-
return (_websocket = _createWebSocket(url));
39-
}
40-
41-
4231
let numberOfErrors = 0;
43-
proxy = connectionProvider.createProxy<S>(host.toString(), undefined, {
32+
const { proxy, webSocket } = connectionProvider.createProxy2<S>(host.toString(), undefined, {
4433
onerror: (event: any) => {
4534
log.error(event);
4635
if (numberOfErrors++ === 5) {
@@ -49,22 +38,33 @@ function createGitpodService<C extends GitpodClient, S extends GitpodServer>() {
4938
}
5039
});
5140

52-
if (_websocket && "reconnect" in _websocket) {
53-
reconnect = () => { (_websocket as any).reconnect() };
54-
}
5541
// }
5642
const service = new GitpodServiceImpl<C, S>(proxy);
57-
(service as any).reconnect = reconnect;
43+
(service as any).reconnect = () => {
44+
const ws = (webSocket as any);
45+
if (typeof ws.reconnect === "function") {
46+
ws.reconnect();
47+
} else {
48+
console.log("WebSocket reconnect not possible.");
49+
}
50+
};
5851
return service;
5952
}
6053

61-
declare global {
62-
type GitpodService = ReturnType<typeof createGitpodService> & { reconnect: () => void }
63-
interface Window { gitpodService?: GitpodService; }
54+
function getGitpodService(): GitpodService {
55+
const w = window as any;
56+
const _gp = w._gp || (w._gp = {});
57+
const service = _gp.gitpodService || (_gp.gitpodService = createGitpodService());
58+
return service;
6459
}
6560

66-
// reuse existing service object if present
67-
let gitpodService: GitpodService = window.gitpodService || (window.gitpodService = createGitpodService() as GitpodService);
68-
// let gitpodService: GitpodService = gitpodServiceMock;
61+
function reconnectGitpodService() {
62+
const service = getGitpodService() as any;
63+
if (service.reconnect) {
64+
service.reconnect();
65+
} else {
66+
console.log("WebSocket reconnect not possible.")
67+
}
68+
}
6969

70-
export { gitpodService };
70+
export { getGitpodService, reconnectGitpodService }

components/dashboard/src/start/CreateWorkspace.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import React, { Suspense } from "react";
2-
import { CreateWorkspaceMode, GitpodService, WorkspaceCreationResult } from "@gitpod/gitpod-protocol";
2+
import { CreateWorkspaceMode, WorkspaceCreationResult } from "@gitpod/gitpod-protocol";
33
import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
44
import Modal from "../components/Modal";
55
import { StartPage, StartPhase } from "../components/StartPage";
66
import StartWorkspace from "./StartWorkspace";
7+
import { getGitpodService } from "../service/service";
78

89
const WorkspaceLogs = React.lazy(() => import('./WorkspaceLogs'));
910

1011
export interface CreateWorkspaceProps {
1112
contextUrl: string;
12-
gitpodService: GitpodService;
1313
}
1414

1515
export interface CreateWorkspaceState {
@@ -35,7 +35,7 @@ export class CreateWorkspace extends React.Component<CreateWorkspaceProps, Creat
3535

3636
async createWorkspace(mode = CreateWorkspaceMode.SelectIfRunning) {
3737
try {
38-
const result = await this.props.gitpodService.server.createWorkspace({
38+
const result = await getGitpodService().server.createWorkspace({
3939
contextUrl: this.props.contextUrl,
4040
mode
4141
});
@@ -77,7 +77,7 @@ export class CreateWorkspace extends React.Component<CreateWorkspaceProps, Creat
7777

7878
const result = this.state?.result;
7979
if (result?.createdWorkspaceId) {
80-
return <StartWorkspace workspaceId={result.createdWorkspaceId} gitpodService={this.props.gitpodService} />;
80+
return <StartWorkspace workspaceId={result.createdWorkspaceId} />;
8181
}
8282

8383
else if (result?.existingWorkspaces) {

components/dashboard/src/start/StartWorkspace.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React from "react";
2-
import { GitpodService, DisposableCollection, WorkspaceInstance } from "@gitpod/gitpod-protocol";
2+
import { DisposableCollection, WorkspaceInstance } from "@gitpod/gitpod-protocol";
33
import { GitpodHostUrl } from "@gitpod/gitpod-protocol/lib/util/gitpod-host-url";
44
import { StartPage, StartPhase } from "../components/StartPage";
5+
import { getGitpodService } from "../service/service";
56

67
export interface StartWorkspaceProps {
78
workspaceId: string;
8-
gitpodService: GitpodService;
99
}
1010

1111
export interface StartWorkspaceState {
@@ -44,7 +44,7 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
4444
}
4545

4646
try {
47-
this.toDispose.push(this.props.gitpodService.registerClient(this));
47+
this.toDispose.push(getGitpodService().registerClient(this));
4848
} catch (error) {
4949
this.setState({ error });
5050
}
@@ -67,7 +67,7 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
6767

6868
const { workspaceId } = this.props;
6969
try {
70-
const result = await this.props.gitpodService.server.startWorkspace(workspaceId, { forceDefaultImage });
70+
const result = await getGitpodService().server.startWorkspace(workspaceId, { forceDefaultImage });
7171
if (!result) {
7272
throw new Error("No result!");
7373
}
@@ -80,7 +80,7 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
8080
this.setState({ startedInstanceId: result.instanceID });
8181
// Explicitly query state to guarantee we get at least one update
8282
// (needed for already started workspaces, and not hanging in 'Starting ...' for too long)
83-
this.props.gitpodService.server.getWorkspace(workspaceId).then(ws => {
83+
getGitpodService().server.getWorkspace(workspaceId).then(ws => {
8484
if (ws.latestInstance) {
8585
this.setState({
8686
contextUrl: ws.workspace.contextURL
@@ -109,7 +109,7 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
109109
}
110110

111111
if (workspaceInstance.status.phase === 'preparing') {
112-
this.props.gitpodService.server.watchWorkspaceImageBuildLogs(workspaceInstance.workspaceId);
112+
getGitpodService().server.watchWorkspaceImageBuildLogs(workspaceInstance.workspaceId);
113113
}
114114

115115
this.setState({ workspaceInstance });

components/dashboard/src/workspaces/WorkspaceEntry.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { GitpodHostUrl } from '@gitpod/gitpod-protocol/lib/util/gitpod-host-url'
33
import ContextMenu, { ContextMenuEntry } from '../components/ContextMenu';
44
import ThreeDots from '../icons/ThreeDots.svg';
55
import moment from 'moment';
6-
import { gitpodService } from '../service/service';
6+
import { getGitpodService } from '../service/service';
77
import Modal from '../components/Modal';
88
import { MouseEvent, useState } from 'react';
99

@@ -60,15 +60,15 @@ export function WorkspaceEntry(desc: WorkspaceInfo) {
6060
title: 'Share',
6161
active: !!ws.shareable,
6262
onClick: () => {
63-
gitpodService.server.controlAdmission(ws.id, ws.shareable ? "owner" : "everyone");
63+
getGitpodService().server.controlAdmission(ws.id, ws.shareable ? "owner" : "everyone");
6464
}
6565
},
6666
{
6767
title: 'Pin',
6868
active: !!ws.pinned,
6969
separator: true,
7070
onClick: () => {
71-
gitpodService.server.updateWorkspaceUserPin(ws.id, 'toggle')
71+
getGitpodService().server.updateWorkspaceUserPin(ws.id, 'toggle')
7272
}
7373
},
7474
{
@@ -133,7 +133,7 @@ export function WorkspaceEntry(desc: WorkspaceInfo) {
133133
<div className="flex">
134134
<div className="flex-1"></div>
135135
<button className="cursor-pointer px-3 py-2 text-white text-sm rounded-md border-2 border-red-800 bg-red-600 hover:bg-red-800"
136-
onClick={()=>gitpodService.server.deleteWorkspace(ws.id)}>
136+
onClick={()=>getGitpodService().server.deleteWorkspace(ws.id)}>
137137
Delete
138138
</button>
139139
</div>

components/dashboard/src/workspaces/Workspaces.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import React from "react";
2-
import { GitpodService, WorkspaceInfo } from "@gitpod/gitpod-protocol";
2+
import { WorkspaceInfo } from "@gitpod/gitpod-protocol";
33
import Header from "../components/Header";
44
import DropDown from "../components/DropDown"
55
import { WorkspaceModel } from "./workspace-model";
66
import { WorkspaceEntry } from "./WorkspaceEntry";
77

88
export interface WorkspacesProps {
9-
gitpodService: GitpodService;
109
}
1110

1211
export interface WorkspacesState {
@@ -19,7 +18,7 @@ export class Workspaces extends React.Component<WorkspacesProps, WorkspacesState
1918

2019
constructor(props: WorkspacesProps) {
2120
super(props);
22-
this.workspaceModel = new WorkspaceModel(props.gitpodService, this.setWorkspaces);
21+
this.workspaceModel = new WorkspaceModel(this.setWorkspaces);
2322
}
2423

2524
protected setWorkspaces = (workspaces: WorkspaceInfo[]) => {

components/dashboard/src/workspaces/workspace-model.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import { Disposable, DisposableCollection, GitpodClient, GitpodService, WorkspaceInfo, WorkspaceInstance } from "@gitpod/gitpod-protocol";
1+
import { Disposable, DisposableCollection, GitpodClient, WorkspaceInfo, WorkspaceInstance } from "@gitpod/gitpod-protocol";
2+
import { getGitpodService } from "../service/service";
23

34
export class WorkspaceModel implements Disposable, Partial<GitpodClient> {
45

56
protected workspaces = new Map<string,WorkspaceInfo>();
67
protected currentlyFetching = new Set<string>();
78
protected disposables = new DisposableCollection();
89

9-
constructor(protected service: GitpodService, protected setWorkspaces: (ws: WorkspaceInfo[]) => void) {
10-
service.server.getWorkspaces({
10+
constructor(protected setWorkspaces: (ws: WorkspaceInfo[]) => void) {
11+
getGitpodService().server.getWorkspaces({
1112
limit: 50
1213
}).then( infos => {
1314
this.updateMap(infos);
1415
this.notifyWorkpaces();
1516
});
16-
this.disposables.push(service.registerClient(this));
17+
this.disposables.push(getGitpodService().registerClient(this));
1718
}
1819

1920
protected updateMap(workspaces: WorkspaceInfo[]) {
@@ -37,7 +38,7 @@ export class WorkspaceModel implements Disposable, Partial<GitpodClient> {
3738
} else if (!this.currentlyFetching.has(instance.workspaceId)) {
3839
try {
3940
this.currentlyFetching.add(instance.workspaceId);
40-
const info = await this.service.server.getWorkspace(instance.workspaceId);
41+
const info = await getGitpodService().server.getWorkspace(instance.workspaceId);
4142
this.workspaces.set(instance.workspaceId, info);
4243
this.notifyWorkpaces();
4344
} finally {

components/gitpod-protocol/src/messaging/browser/connection.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,20 @@ export class WebSocketConnectionProvider {
3131
}, options);
3232
return factory.createProxy();
3333
}
34+
createProxy2<T extends object>(path: string, target?: object, options?: WebSocketOptions): { proxy: JsonRpcProxy<T>, webSocket: WebSocket } {
35+
const factory = new JsonRpcProxyFactory<T>(target);
36+
const webSocket = this.listen({
37+
path,
38+
onConnection: c => factory.listen(c)
39+
}, options);
40+
const proxy = factory.createProxy();
41+
return { proxy, webSocket };
42+
}
3443

3544
/**
3645
* Install a connection handler for the given path.
3746
*/
38-
listen(handler: ConnectionHandler, options?: WebSocketOptions): void {
47+
listen(handler: ConnectionHandler, options?: WebSocketOptions): WebSocket {
3948
const url = handler.path;
4049
const webSocket = this.createWebSocket(url);
4150

@@ -55,6 +64,7 @@ export class WebSocketConnectionProvider {
5564
onConnection: connection => handler.onConnection(connection),
5665
logger
5766
});
67+
return webSocket;
5868
}
5969

6070
protected createLogger(): Logger {

0 commit comments

Comments
 (0)