diff --git a/src/components/connectionStatus.ts b/src/components/connectionStatus.ts index 0f650a7f..0631c771 100644 --- a/src/components/connectionStatus.ts +++ b/src/components/connectionStatus.ts @@ -31,6 +31,7 @@ export default class ConnectionStatusComponent { private hadConnect = false; private retryAt: number; private connecting = false; + private timedOut = false; private updating = false; private log: ReturnType; @@ -114,7 +115,8 @@ export default class ConnectionStatusComponent { if(online && !this.hadConnect) { this.hadConnect = true; } - + + this.timedOut = status && status.status === ConnectionStatus.TimedOut; this.connecting = !online; this.retryAt = status && status.retryAt; DEBUG && this.log('connecting', this.connecting); @@ -129,10 +131,25 @@ export default class ConnectionStatusComponent { this.statusPreloader.attach(this.statusEl); }; + private getA(langPackKey: LangPackKey, callback: () => void) { + const a = document.createElement('a'); + a.classList.add('force-reconnect'); + a.append(i18n(langPackKey)); + a.addEventListener('click', (e) => { + cancelEvent(e); + callback(); + }); + + return a; + } + private setState = () => { const timeout = ConnectionStatusComponent.CHANGE_STATE_DELAY; if(this.connecting) { - if(this.hadConnect) { + if(this.timedOut) { + const a = this.getA('ConnectionStatus.ForceReconnect', () => apiManager.forceReconnect()); + this.setStatusText('ConnectionStatus.TimedOut', [a]); + } else if(this.hadConnect) { if(this.retryAt !== undefined) { const timerSpan = document.createElement('span'); const retryAt = this.retryAt; @@ -146,13 +163,7 @@ export default class ConnectionStatusComponent { setTime(); const interval = setInterval(setTime, 1e3); - const a = document.createElement('a'); - a.classList.add('force-reconnect'); - a.append(i18n('ConnectionStatus.Reconnect')); - a.addEventListener('click', (e) => { - cancelEvent(e); - apiManager.forceReconnect(); - }); + const a = this.getA('ConnectionStatus.Reconnect', () => apiManager.forceReconnectTimeout()); this.setStatusText('ConnectionStatus.ReconnectIn', [timerSpan, a]); } else { this.setStatusText('ConnectionStatus.Reconnecting'); diff --git a/src/config/app.ts b/src/config/app.ts index 81bf4e81..ffd854ad 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -15,7 +15,7 @@ const App = { id: 1025907, hash: '452b0359b988148995f22ff0f4229750', version: '0.5.8', - langPackVersion: '0.2.6', + langPackVersion: '0.2.9', langPack: 'macos', langPackCode: 'en', domains: [] as string[], diff --git a/src/lang.ts b/src/lang.ts index 3e76356d..2231f88b 100644 --- a/src/lang.ts +++ b/src/lang.ts @@ -46,9 +46,11 @@ const lang = { //"ChatList.Menu.Archived": "Archived", "ChatList.Menu.SwitchTo.Webogram": "Switch to Old Version", "ChatList.Menu.SwitchTo.Z": "Switch to Z version", + "ConnectionStatus.ForceReconnect": "force reconnect", "ConnectionStatus.ReconnectIn": "Reconnect in %ds, %s", "ConnectionStatus.Reconnect": "reconnect", "ConnectionStatus.Reconnecting": "Reconnecting...", + "ConnectionStatus.TimedOut": "Request timed out, %s", "ConnectionStatus.Waiting": "Waiting for network...", "Deactivated.Title": "Too many tabs...", "Deactivated.Subtitle": "Telegram supports only one active tab with the app.\nClick anywhere to continue using this tab.", diff --git a/src/lib/mtproto/connectionStatus.ts b/src/lib/mtproto/connectionStatus.ts index d5582704..72ded674 100644 --- a/src/lib/mtproto/connectionStatus.ts +++ b/src/lib/mtproto/connectionStatus.ts @@ -7,7 +7,8 @@ export enum ConnectionStatus { Connected, Connecting, - Closed + Closed, + TimedOut }; export type ConnectionStatusChange = { diff --git a/src/lib/mtproto/mtproto.worker.ts b/src/lib/mtproto/mtproto.worker.ts index b65dfa05..2ec31a45 100644 --- a/src/lib/mtproto/mtproto.worker.ts +++ b/src/lib/mtproto/mtproto.worker.ts @@ -90,7 +90,11 @@ const taskListeners = { online: () => { networkerFactory.forceReconnectTimeout(); - } + }, + + forceReconnect: () => { + networkerFactory.forceReconnect(); + }, }; const onMessage = async(e: any) => { diff --git a/src/lib/mtproto/mtprotoworker.ts b/src/lib/mtproto/mtprotoworker.ts index 3826d967..4d580891 100644 --- a/src/lib/mtproto/mtprotoworker.ts +++ b/src/lib/mtproto/mtprotoworker.ts @@ -189,7 +189,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods { }); window.addEventListener('online', (event) => { - this.forceReconnect(); + this.forceReconnectTimeout(); }); /// #if !MTPROTO_SW @@ -544,9 +544,13 @@ export class ApiManagerProxy extends CryptoWorkerMethods { return this.performTaskWorkerVoid('startAll'); } - public forceReconnect() { + public forceReconnectTimeout() { this.postMessage({type: 'online'}); } + + public forceReconnect() { + this.postMessage({type: 'forceReconnect'}); + } } const apiManagerProxy = new ApiManagerProxy(); diff --git a/src/lib/mtproto/networker.ts b/src/lib/mtproto/networker.ts index 576de5f6..ffcaed60 100644 --- a/src/lib/mtproto/networker.ts +++ b/src/lib/mtproto/networker.ts @@ -382,6 +382,12 @@ export default class MTPNetworker { } } + public forceReconnect() { + if((this.transport as TcpObfuscated).forceReconnect) { + (this.transport as TcpObfuscated).forceReconnect(); + } + } + // private sendPingDelayDisconnect = () => { // if(this.pingPromise || true) return; @@ -696,7 +702,9 @@ export default class MTPNetworker { } this.log.error('timeout', message); - this.setConnectionStatus(ConnectionStatus.Closed); + if(this.isOnline) { + this.setConnectionStatus(ConnectionStatus.TimedOut); + } /* this.getEncryptedOutput(message).then(bytes => { this.log.error('timeout encrypted', bytes); diff --git a/src/lib/mtproto/networkerFactory.ts b/src/lib/mtproto/networkerFactory.ts index ac9017d5..4f2538c1 100644 --- a/src/lib/mtproto/networkerFactory.ts +++ b/src/lib/mtproto/networkerFactory.ts @@ -73,6 +73,15 @@ export class NetworkerFactory { networker.forceReconnectTimeout(); } } + + public forceReconnect() { + for(const networker of this.networkers) { + if(!networker.isFileNetworker) { + networker.forceReconnect(); + break; + } + } + } } const networkerFactory = new NetworkerFactory(); diff --git a/src/lib/mtproto/transports/tcpObfuscated.ts b/src/lib/mtproto/transports/tcpObfuscated.ts index 5aa4e358..b4d549d7 100644 --- a/src/lib/mtproto/transports/tcpObfuscated.ts +++ b/src/lib/mtproto/transports/tcpObfuscated.ts @@ -135,7 +135,7 @@ export default class TcpObfuscated implements MTTransport { } }; - private clear() { + public clear() { this.connected = false; if(this.connection) { @@ -174,14 +174,28 @@ export default class TcpObfuscated implements MTTransport { this.connect(); } + public forceReconnect() { + this.close(); + this.reconnect(); + } + public destroy() { this.setAutoReconnect(false); this.close(); } public close() { - if(this.connection) { - this.connection.close(); + const connection = this.connection; + if(connection) { + const connected = this.connected; + this.clear(); + if(connected) { // wait for buffered messages if they are there + connection.addEventListener('message', this.onMessage); + connection.addEventListener('close', () => { + connection.removeEventListener('message', this.onMessage); + }, true); + connection.close(); + } } } @@ -205,7 +219,6 @@ export default class TcpObfuscated implements MTTransport { private connect() { if(this.connection) { this.close(); - this.clear(); } this.connection = new this.Connection(this.dcId, this.url, this.logSuffix);