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.
148 lines
4.0 KiB
148 lines
4.0 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
* |
|
* Originally from: |
|
* https://github.com/zhukov/webogram |
|
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com> |
|
* https://github.com/zhukov/webogram/blob/master/LICENSE |
|
*/ |
|
|
|
import { MOUNT_CLASS_TO } from "../../config/debug"; |
|
import { nextRandomUint } from "../../helpers/random"; |
|
import { logger } from "../logger"; |
|
import rootScope from "../rootScope"; |
|
import sessionStorage from "../sessionStorage"; |
|
import apiManager from "./mtprotoworker"; |
|
|
|
export type AppInstance = { |
|
id: number, |
|
idle: boolean, |
|
time: number |
|
}; |
|
|
|
const CHECK_INSTANCE_INTERVAL = 5000; |
|
const DEACTIVATE_TIMEOUT = 30000; |
|
const MULTIPLE_TABS_THRESHOLD = 20000; |
|
|
|
export class SingleInstance { |
|
private instanceID: number; |
|
private started: boolean; |
|
private masterInstance: boolean; |
|
private deactivateTimeout: number; |
|
private deactivated: boolean; |
|
private initial: boolean; |
|
private log = logger('INSTANCE'); |
|
|
|
public start() { |
|
if(!this.started/* && !Config.Navigator.mobile && !Config.Modes.packed */) { |
|
this.started = true; |
|
|
|
this.reset(); |
|
//IdleManager.start(); |
|
|
|
rootScope.addEventListener('idle', this.checkInstance); |
|
setInterval(this.checkInstance, CHECK_INSTANCE_INTERVAL); |
|
this.checkInstance(); |
|
|
|
try { |
|
document.documentElement.addEventListener('beforeunload', this.clearInstance); |
|
} catch(e) {} |
|
} |
|
} |
|
|
|
public reset() { |
|
this.instanceID = nextRandomUint(32); |
|
this.masterInstance = false; |
|
if(this.deactivateTimeout) clearTimeout(this.deactivateTimeout); |
|
this.deactivateTimeout = 0; |
|
this.deactivated = false; |
|
this.initial = false; |
|
} |
|
|
|
public clearInstance = () => { |
|
if(this.masterInstance && !this.deactivated) { |
|
this.log.warn('clear master instance'); |
|
sessionStorage.delete('xt_instance'); |
|
} |
|
}; |
|
|
|
public activateInstance() { |
|
if(this.deactivated) { |
|
this.reset(); |
|
this.checkInstance(false); |
|
rootScope.dispatchEvent('instance_activated'); |
|
} |
|
} |
|
|
|
public deactivateInstance = () => { |
|
if(this.masterInstance || this.deactivated) { |
|
return false; |
|
} |
|
|
|
this.log('deactivate'); |
|
this.deactivateTimeout = 0; |
|
this.deactivated = true; |
|
this.clearInstance(); |
|
//$modalStack.dismissAll(); |
|
|
|
//document.title = _('inactive_tab_title_raw') |
|
|
|
rootScope.idle.deactivated = true; |
|
rootScope.dispatchEvent('instance_deactivated'); |
|
}; |
|
|
|
public checkInstance = (idle = rootScope.idle && rootScope.idle.isIDLE) => { |
|
if(this.deactivated) { |
|
return false; |
|
} |
|
|
|
const time = Date.now(); |
|
const newInstance: AppInstance = { |
|
id: this.instanceID, |
|
idle, |
|
time |
|
}; |
|
|
|
sessionStorage.get('xt_instance', false).then((curInstance: AppInstance) => { |
|
// this.log('check instance', newInstance, curInstance) |
|
if(!idle || |
|
!curInstance || |
|
curInstance.id === this.instanceID || |
|
curInstance.time < (time - MULTIPLE_TABS_THRESHOLD)) { |
|
sessionStorage.set({xt_instance: newInstance}); |
|
|
|
if(!this.masterInstance) { |
|
apiManager.startAll(); |
|
if(!this.initial) { |
|
this.initial = true; |
|
} else { |
|
this.log.warn('now master instance', newInstance); |
|
} |
|
|
|
this.masterInstance = true; |
|
} |
|
|
|
if(this.deactivateTimeout) { |
|
clearTimeout(this.deactivateTimeout); |
|
this.deactivateTimeout = 0; |
|
} |
|
} else { |
|
if(this.masterInstance) { |
|
apiManager.stopAll(); |
|
this.log.warn('now idle instance', newInstance); |
|
if(!this.deactivateTimeout) { |
|
this.deactivateTimeout = window.setTimeout(this.deactivateInstance, DEACTIVATE_TIMEOUT); |
|
} |
|
|
|
this.masterInstance = false; |
|
} |
|
} |
|
}); |
|
}; |
|
} |
|
|
|
const singleInstance = new SingleInstance(); |
|
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.singleInstance = singleInstance); |
|
export default singleInstance;
|
|
|