@jsxc/jsxc
Version:
Real-time XMPP chat application with video calls, file transfer and encrypted communication
144 lines (116 loc) • 4.41 kB
text/typescript
import JID from '../../JID';
import { IConnection } from '../Connection.interface';
import Log from '../../util/Log';
import Account from '../../Account';
import { AbstractConnection, STANZA_IQ_KEY, STANZA_KEY, STANZA_JINGLE_KEY } from '../AbstractConnection';
import { Strophe } from '../../vendor/Strophe';
import JingleHandler from '../JingleHandler';
export default class StorageConnection extends AbstractConnection implements IConnection {
protected connection: any = {};
private handlers = [];
constructor(protected account: Account) {
super(account);
this.connection = {
jid: account.getJID().full,
send: this.send,
sendIQ: (elem, success, error) => {
this.sendIQ(elem).then(success).catch(error);
},
addHandler: () => {},
};
for (let k in (<any>Strophe)._connectionPlugins) {
if ((<any>Strophe)._connectionPlugins.hasOwnProperty(k)) {
let ptype = (<any>Strophe)._connectionPlugins[k];
// jslint complaints about the below line, but this is fine
let F = function () {}; // jshint ignore:line
F.prototype = ptype;
this.connection[k] = new F();
this.connection[k].init(this.connection);
}
}
this.getStorage().registerHook(STANZA_JINGLE_KEY, this.storageJingleHook);
}
public registerHandler(
handler: (stanza: string) => boolean,
ns?: string,
name?: string,
type?: string,
id?: string,
from?: string
) {
this.handlers.push(arguments);
}
public getHandlers() {
return this.handlers;
}
public getJingleHandler() {
if (!this.jingleHandler) {
this.jingleHandler = new JingleHandler(this.account, this);
}
return this.jingleHandler;
}
public getCapabilitiesByJid(jid: JID): any {
Log.info('[SC] getCapabilitiesByJid');
}
public hasFeatureByJid(jid: JID, feature: string);
public hasFeatureByJid(jid: JID, feature: string[]);
public hasFeatureByJid() {
Log.info('[SC] has feature by jid');
}
public logout() {
Log.info('[SC] logout');
}
public send(stanzaElement: Element);
public send(stanzaElement: Strophe.Builder);
public send() {
let storage = this.getStorage();
let stanzaString = this.stanzaElementToString(arguments[0]);
let key = storage.generateKey(STANZA_KEY, stanzaString.length + '', new Date().getTime() + '');
storage.setItem(key, stanzaString);
}
protected sendIQ(stanzaElement: Element): Promise<Element>;
protected sendIQ(stanzaElement: Strophe.Builder): Promise<Element>;
protected sendIQ() {
let storage = this.getStorage();
let stanzaString = this.stanzaElementToString(arguments[0]);
let key = storage.generateKey(STANZA_IQ_KEY, stanzaString.length + '', new Date().getTime() + '');
storage.setItem(key, stanzaString);
return new Promise<Element>(function (resolve, reject) {
storage.registerHook(key, function (newValue: { type: 'success' | 'error'; stanza: string }) {
if (!newValue) {
return;
}
let stanzaElement = $.parseXML(newValue.stanza).documentElement;
if (newValue.type === 'success') {
resolve(stanzaElement);
} else if (newValue.type === 'error') {
reject(stanzaElement);
}
});
});
}
public close() {
this.getStorage().removeHook(STANZA_JINGLE_KEY, this.storageJingleHook);
}
private stanzaElementToString(stanzaElement: Element): string;
private stanzaElementToString(stanzaElement: Strophe.Builder): string;
private stanzaElementToString() {
let stanzaString: string;
let stanzaElement = arguments[0] || {};
if (typeof stanzaElement.outerHTML === 'string') {
stanzaString = stanzaElement.outerHTML;
} else {
stanzaString = stanzaElement.toString();
}
return stanzaString;
}
private storageJingleHook = (newValue, oldValue, key) => {
if (newValue && !oldValue) {
this.processJingleStanza(newValue);
}
};
private processJingleStanza(stanzaString) {
let iqElement = $.parseXML(stanzaString).getElementsByTagName('iq')[0];
this.getJingleHandler().onJingle(iqElement);
}
}