1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | exports.ApplicationConnectionStatusContribution = exports.FrontendConnectionStatusService = exports.AbstractConnectionStatusService = exports.PingService = exports.ConnectionStatusOptions = exports.ConnectionStatus = exports.ConnectionStatusService = void 0;
|
19 | const tslib_1 = require("tslib");
|
20 | const inversify_1 = require("inversify");
|
21 | const logger_1 = require("../common/logger");
|
22 | const event_1 = require("../common/event");
|
23 | const frontend_application_contribution_1 = require("./frontend-application-contribution");
|
24 | const status_bar_1 = require("./status-bar/status-bar");
|
25 | const common_1 = require("../common");
|
26 | const ws_connection_source_1 = require("./messaging/ws-connection-source");
|
27 |
|
28 |
|
29 |
|
30 | exports.ConnectionStatusService = Symbol('ConnectionStatusService');
|
31 |
|
32 |
|
33 |
|
34 | var ConnectionStatus;
|
35 | (function (ConnectionStatus) {
|
36 | |
37 |
|
38 |
|
39 | ConnectionStatus[ConnectionStatus["ONLINE"] = 0] = "ONLINE";
|
40 | |
41 |
|
42 |
|
43 | ConnectionStatus[ConnectionStatus["OFFLINE"] = 1] = "OFFLINE";
|
44 | })(ConnectionStatus = exports.ConnectionStatus || (exports.ConnectionStatus = {}));
|
45 | let ConnectionStatusOptions = class ConnectionStatusOptions {
|
46 | };
|
47 | ConnectionStatusOptions.DEFAULT = {
|
48 | offlineTimeout: 5000,
|
49 | };
|
50 | ConnectionStatusOptions = (0, tslib_1.__decorate)([
|
51 | (0, inversify_1.injectable)()
|
52 | ], ConnectionStatusOptions);
|
53 | exports.ConnectionStatusOptions = ConnectionStatusOptions;
|
54 | exports.PingService = Symbol('PingService');
|
55 | let AbstractConnectionStatusService = class AbstractConnectionStatusService {
|
56 | constructor(options = ConnectionStatusOptions.DEFAULT) {
|
57 | this.options = options;
|
58 | this.statusChangeEmitter = new event_1.Emitter();
|
59 | this.connectionStatus = ConnectionStatus.ONLINE;
|
60 | }
|
61 | get onStatusChange() {
|
62 | return this.statusChangeEmitter.event;
|
63 | }
|
64 | get currentStatus() {
|
65 | return this.connectionStatus;
|
66 | }
|
67 | dispose() {
|
68 | this.statusChangeEmitter.dispose();
|
69 | }
|
70 | updateStatus(success) {
|
71 | const previousStatus = this.connectionStatus;
|
72 | const newStatus = success ? ConnectionStatus.ONLINE : ConnectionStatus.OFFLINE;
|
73 | if (previousStatus !== newStatus) {
|
74 | this.connectionStatus = newStatus;
|
75 | this.fireStatusChange(newStatus);
|
76 | }
|
77 | }
|
78 | fireStatusChange(status) {
|
79 | this.statusChangeEmitter.fire(status);
|
80 | }
|
81 | };
|
82 | (0, tslib_1.__decorate)([
|
83 | (0, inversify_1.inject)(logger_1.ILogger),
|
84 | (0, tslib_1.__metadata)("design:type", Object)
|
85 | ], AbstractConnectionStatusService.prototype, "logger", void 0);
|
86 | AbstractConnectionStatusService = (0, tslib_1.__decorate)([
|
87 | (0, inversify_1.injectable)(),
|
88 | (0, tslib_1.__param)(0, (0, inversify_1.inject)(ConnectionStatusOptions)),
|
89 | (0, tslib_1.__param)(0, (0, inversify_1.optional)()),
|
90 | (0, tslib_1.__metadata)("design:paramtypes", [ConnectionStatusOptions])
|
91 | ], AbstractConnectionStatusService);
|
92 | exports.AbstractConnectionStatusService = AbstractConnectionStatusService;
|
93 | let FrontendConnectionStatusService = class FrontendConnectionStatusService extends AbstractConnectionStatusService {
|
94 | init() {
|
95 | this.wsConnectionProvider.onSocketDidOpen(() => {
|
96 | this.updateStatus(true);
|
97 | this.schedulePing();
|
98 | });
|
99 | this.wsConnectionProvider.onSocketDidClose(() => {
|
100 | this.clearTimeout(this.scheduledPing);
|
101 | this.updateStatus(false);
|
102 | });
|
103 | this.wsConnectionProvider.onIncomingMessageActivity(() => {
|
104 |
|
105 | this.updateStatus(true);
|
106 | this.schedulePing();
|
107 | });
|
108 | }
|
109 | schedulePing() {
|
110 | this.clearTimeout(this.scheduledPing);
|
111 | this.scheduledPing = this.setTimeout(async () => {
|
112 | await this.performPingRequest();
|
113 | this.schedulePing();
|
114 | }, this.options.offlineTimeout);
|
115 | }
|
116 | async performPingRequest() {
|
117 | try {
|
118 | await this.pingService.ping();
|
119 | this.updateStatus(true);
|
120 | }
|
121 | catch (e) {
|
122 | this.updateStatus(false);
|
123 | await this.logger.error(e);
|
124 | }
|
125 | }
|
126 |
|
127 | setTimeout(handler, timeout) {
|
128 | return window.setTimeout(handler, timeout);
|
129 | }
|
130 | clearTimeout(handle) {
|
131 | if (handle !== undefined) {
|
132 | window.clearTimeout(handle);
|
133 | }
|
134 | }
|
135 | };
|
136 | (0, tslib_1.__decorate)([
|
137 | (0, inversify_1.inject)(ws_connection_source_1.WebSocketConnectionSource),
|
138 | (0, tslib_1.__metadata)("design:type", ws_connection_source_1.WebSocketConnectionSource)
|
139 | ], FrontendConnectionStatusService.prototype, "wsConnectionProvider", void 0);
|
140 | (0, tslib_1.__decorate)([
|
141 | (0, inversify_1.inject)(exports.PingService),
|
142 | (0, tslib_1.__metadata)("design:type", Object)
|
143 | ], FrontendConnectionStatusService.prototype, "pingService", void 0);
|
144 | (0, tslib_1.__decorate)([
|
145 | (0, inversify_1.postConstruct)(),
|
146 | (0, tslib_1.__metadata)("design:type", Function),
|
147 | (0, tslib_1.__metadata)("design:paramtypes", []),
|
148 | (0, tslib_1.__metadata)("design:returntype", void 0)
|
149 | ], FrontendConnectionStatusService.prototype, "init", null);
|
150 | FrontendConnectionStatusService = (0, tslib_1.__decorate)([
|
151 | (0, inversify_1.injectable)()
|
152 | ], FrontendConnectionStatusService);
|
153 | exports.FrontendConnectionStatusService = FrontendConnectionStatusService;
|
154 | let ApplicationConnectionStatusContribution = class ApplicationConnectionStatusContribution extends frontend_application_contribution_1.DefaultFrontendApplicationContribution {
|
155 | constructor(connectionStatusService, statusBar, logger) {
|
156 | super();
|
157 | this.connectionStatusService = connectionStatusService;
|
158 | this.statusBar = statusBar;
|
159 | this.logger = logger;
|
160 | this.toDisposeOnOnline = new common_1.DisposableCollection();
|
161 | this.statusbarId = 'connection-status';
|
162 | this.connectionStatusService.onStatusChange(state => this.onStateChange(state));
|
163 | }
|
164 | onStateChange(state) {
|
165 | switch (state) {
|
166 | case ConnectionStatus.OFFLINE: {
|
167 | this.handleOffline();
|
168 | break;
|
169 | }
|
170 | case ConnectionStatus.ONLINE: {
|
171 | this.handleOnline();
|
172 | break;
|
173 | }
|
174 | }
|
175 | }
|
176 | handleOnline() {
|
177 | this.toDisposeOnOnline.dispose();
|
178 | }
|
179 | handleOffline() {
|
180 | this.statusBar.setElement(this.statusbarId, {
|
181 | alignment: status_bar_1.StatusBarAlignment.LEFT,
|
182 | text: common_1.nls.localize('theia/core/offline', 'Offline'),
|
183 | tooltip: common_1.nls.localize('theia/localize/offlineTooltip', 'Cannot connect to backend.'),
|
184 | priority: 5000
|
185 | });
|
186 | this.toDisposeOnOnline.push(common_1.Disposable.create(() => this.statusBar.removeElement(this.statusbarId)));
|
187 | document.body.classList.add('theia-mod-offline');
|
188 | this.toDisposeOnOnline.push(common_1.Disposable.create(() => document.body.classList.remove('theia-mod-offline')));
|
189 | }
|
190 | };
|
191 | ApplicationConnectionStatusContribution = (0, tslib_1.__decorate)([
|
192 | (0, inversify_1.injectable)(),
|
193 | (0, tslib_1.__param)(0, (0, inversify_1.inject)(exports.ConnectionStatusService)),
|
194 | (0, tslib_1.__param)(1, (0, inversify_1.inject)(status_bar_1.StatusBar)),
|
195 | (0, tslib_1.__param)(2, (0, inversify_1.inject)(logger_1.ILogger)),
|
196 | (0, tslib_1.__metadata)("design:paramtypes", [Object, Object, Object])
|
197 | ], ApplicationConnectionStatusContribution);
|
198 | exports.ApplicationConnectionStatusContribution = ApplicationConnectionStatusContribution;
|
199 |
|
\ | No newline at end of file |