Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
6.6 KiB
193 lines
6.6 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import App from "../config/app"; |
|
import DEBUG from "../config/debug"; |
|
import replaceContent from "../helpers/dom/replaceContent"; |
|
import apiUpdatesManager from "../lib/appManagers/apiUpdatesManager"; |
|
import { LangPackKey, i18n } from "../lib/langPack"; |
|
import { logger } from "../lib/logger"; |
|
import rootScope from "../lib/rootScope"; |
|
import Button from "./button"; |
|
import ProgressivePreloader from "./preloader"; |
|
import SetTransition from "./singleTransition"; |
|
import sessionStorage from '../lib/sessionStorage'; |
|
import { ConnectionStatus } from "../lib/mtproto/connectionStatus"; |
|
import { cancelEvent } from "../helpers/dom/cancelEvent"; |
|
import apiManager from "../lib/mtproto/mtprotoworker"; |
|
import { attachClickEvent } from "../helpers/dom/clickEvent"; |
|
|
|
export default class ConnectionStatusComponent { |
|
public static CHANGE_STATE_DELAY = 1000; |
|
|
|
private statusContainer: HTMLElement; |
|
private statusEl: HTMLElement; |
|
private statusPreloader: ProgressivePreloader; |
|
|
|
private currentLangPackKey: LangPackKey; |
|
|
|
private hadConnect = false; |
|
private retryAt: number; |
|
private connecting = false; |
|
private timedOut = false; |
|
private updating = false; |
|
|
|
private log: ReturnType<typeof logger>; |
|
|
|
private setFirstConnectionTimeout: number; |
|
private setStateTimeout: number; |
|
|
|
constructor(chatsContainer: HTMLElement) { |
|
this.log = logger('CS', undefined, undefined); |
|
|
|
this.statusContainer = document.createElement('div'); |
|
this.statusContainer.classList.add('connection-status'/* , 'hide' */); |
|
|
|
this.statusEl = Button('btn-primary bg-warning connection-status-button', {noRipple: true}); |
|
this.statusPreloader = new ProgressivePreloader({cancelable: false}); |
|
this.statusPreloader.constructContainer({color: 'transparent', bold: true}); |
|
this.statusContainer.append(this.statusEl); |
|
|
|
chatsContainer.prepend(this.statusContainer); |
|
|
|
rootScope.addEventListener('connection_status_change', (status) => { |
|
console.log(status); |
|
|
|
this.setConnectionStatus(); |
|
}); |
|
|
|
rootScope.addEventListener('state_synchronizing', (channelId) => { |
|
if(!channelId) { |
|
this.updating = true; |
|
DEBUG && this.log('updating', this.updating); |
|
this.setState(); |
|
} |
|
}); |
|
|
|
rootScope.addEventListener('state_synchronized', (channelId) => { |
|
DEBUG && this.log('state_synchronized', channelId); |
|
if(!channelId) { |
|
this.updating = false; |
|
DEBUG && this.log('updating', this.updating); |
|
this.setState(); |
|
} |
|
}); |
|
|
|
this.setFirstConnectionTimeout = window.setTimeout(this.setConnectionStatus, ConnectionStatusComponent.CHANGE_STATE_DELAY + 1e3); |
|
|
|
/* let bool = true; |
|
document.addEventListener('dblclick', () => { |
|
const dcId = 2; |
|
rootScope.dispatchEvent('connection_status_change', { |
|
dcId: dcId, |
|
isFileDownload: false, |
|
isFileNetworker: false, |
|
isFileUpload: false, |
|
name: "NET-" + dcId, |
|
status: bool ? (bool = false, ConnectionStatus.Closed) : (bool = true, ConnectionStatus.Connected), |
|
_: "networkerStatus" |
|
}); |
|
}); */ |
|
} |
|
|
|
private setConnectionStatus = () => { |
|
sessionStorage.get('dc').then(baseDcId => { |
|
if(!baseDcId) { |
|
baseDcId = App.baseDcId; |
|
} |
|
|
|
if(this.setFirstConnectionTimeout) { |
|
clearTimeout(this.setFirstConnectionTimeout); |
|
this.setFirstConnectionTimeout = 0; |
|
} |
|
|
|
const status = rootScope.connectionStatus['NET-' + baseDcId]; |
|
const online = status && status.status === ConnectionStatus.Connected; |
|
|
|
if(this.connecting && online) { |
|
apiUpdatesManager.forceGetDifference(); |
|
} |
|
|
|
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); |
|
this.setState(); |
|
}); |
|
}; |
|
|
|
private setStatusText = (langPackKey: LangPackKey, args?: any[]) => { |
|
if(this.currentLangPackKey === langPackKey) return; |
|
this.currentLangPackKey = langPackKey; |
|
replaceContent(this.statusEl, i18n(langPackKey, args)); |
|
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)); |
|
attachClickEvent(a, (e) => { |
|
cancelEvent(e); |
|
callback(); |
|
}); |
|
|
|
return a; |
|
} |
|
|
|
private setState = () => { |
|
const timeout = ConnectionStatusComponent.CHANGE_STATE_DELAY; |
|
if(this.connecting) { |
|
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; |
|
const setTime = () => { |
|
const now = Date.now(); |
|
timerSpan.innerText = '' + Math.round((retryAt - now) / 1000); |
|
if(now > retryAt) { |
|
clearInterval(interval); |
|
} |
|
}; |
|
const interval = setInterval(setTime, 1e3); |
|
setTime(); |
|
|
|
const a = this.getA('ConnectionStatus.Reconnect', () => apiManager.forceReconnectTimeout()); |
|
this.setStatusText('ConnectionStatus.ReconnectIn', [timerSpan, a]); |
|
} else { |
|
this.setStatusText('ConnectionStatus.Reconnecting'); |
|
} |
|
} else { |
|
this.setStatusText('ConnectionStatus.Waiting'); |
|
} |
|
} else if(this.updating) { |
|
this.setStatusText('Updating'); |
|
} |
|
|
|
DEBUG && this.log('setState', this.connecting || this.updating); |
|
window.requestAnimationFrame(() => { |
|
if(this.setStateTimeout) clearTimeout(this.setStateTimeout); |
|
|
|
const cb = () => { |
|
SetTransition(this.statusContainer, 'is-shown', this.connecting || this.updating, 200); |
|
this.setStateTimeout = 0; |
|
DEBUG && this.log('setState: isShown:', this.connecting || this.updating); |
|
}; |
|
|
|
this.setStateTimeout = window.setTimeout(cb, timeout); |
|
//cb(); |
|
/* if(timeout) this.setStateTimeout = window.setTimeout(cb, timeout); |
|
else cb(); */ |
|
}); |
|
}; |
|
}
|
|
|