@jsxc/jsxc
Version:
Real-time XMPP chat application with video calls, file transfer and encrypted communication
109 lines (81 loc) • 3.21 kB
text/typescript
import { ExtensivePresence, Presence } from './connection/AbstractConnection';
import { Strophe } from './vendor/Strophe';
import Account from './Account';
import Storage from './Storage';
import Log from '@util/Log';
const TARGET_KEY = 'targetPresence';
const CURRENT_KEY = 'currentPresence';
const AGGREGATE = 500;
export default class PresenceController {
private updateTimeout;
constructor(private storage: Storage, private getAccounts: () => Account[]) {}
public setTargetPresence(presence: Presence, status: string = '') {
this.storage.setItem(TARGET_KEY, { presence, status });
}
public getTargetPresence(): Presence {
let extPresence = this.storage.getItem(TARGET_KEY);
let presence = extPresence && typeof extPresence === 'object' ? extPresence.presence : extPresence;
return typeof presence === 'number' ? presence : Presence.offline;
}
public getStatus(): string {
let extPresence = this.storage.getItem(TARGET_KEY);
if (!extPresence || typeof extPresence !== 'object') {
return '';
}
return extPresence.status;
}
public getCurrentPresence(): Presence {
let presence = this.storage.getItem(CURRENT_KEY);
return typeof presence === 'number' ? presence : Presence.offline;
}
public registerTargetPresenceHook(func: (extPresence: ExtensivePresence) => void) {
this.storage.registerHook(TARGET_KEY, func);
}
public unregisterTargetPresenceHook(func: (extPresence: ExtensivePresence) => void) {
this.storage.removeHook(TARGET_KEY, func);
}
public registerCurrentPresenceHook(func: (presence: Presence) => void) {
this.storage.registerHook(CURRENT_KEY, func);
}
public registerAccount(account: Account) {
let sessionStorage = account.getSessionStorage();
this.updateCurrentPresence();
//@REVIEW account.registerPresenceHook ???
sessionStorage.registerHook('presence', () => {
if (this.updateTimeout) {
clearTimeout(this.updateTimeout);
}
this.updateTimeout = setTimeout(() => this.updateCurrentPresence(), AGGREGATE);
});
account.registerConnectionHook(status => {
if (status === Strophe.Status.DISCONNECTED) {
Log.info('Presence Controller: account disconnected');
}
});
}
private updateCurrentPresence() {
let commonPresence = this.getCommonPresence();
if (commonPresence !== false) {
this.storage.setItem(CURRENT_KEY, commonPresence);
}
}
private getCommonPresence(): Presence | false {
let isSamePresence = true;
let commonPresence;
let accounts = this.getAccounts();
//@REVIEW refactor
if (accounts.length === 0) {
this.setTargetPresence(Presence.offline);
return Presence.offline;
}
accounts.forEach(account => {
let presence = account.getPresence();
if (typeof commonPresence === 'undefined') {
commonPresence = presence;
} else if (commonPresence !== presence) {
isSamePresence = false;
}
});
return isSamePresence ? commonPresence : false;
}
}