var Session;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Session = (function() {
function Session() {
this.xmpp = new Strophe.Connection('/xmpp');
this.roster = {};
this.listeners = {
card: [],
message: [],
presence: [],
roster: []
};
}
Session.prototype.connect = function(jid, password, callback) {
return this.xmpp.connect(jid, password, __bind(function(status) {
switch (status) {
case Strophe.Status.CONNFAIL:
return callback(false);
case Strophe.Status.CONNECTED:
this.xmpp.addHandler((__bind(function(el) {
return this.handleIq(el);
}, this)), null, 'iq');
this.xmpp.addHandler((__bind(function(el) {
return this.handleMessage(el);
}, this)), null, 'message');
this.xmpp.addHandler((__bind(function(el) {
return this.handlePresence(el);
}, this)), null, 'presence');
callback(true);
return this.findRoster(__bind(function() {
this.notify('roster');
this.xmpp.send($('').get(0));
return this.findCards();
}, this));
}
}, this));
};
Session.prototype.disconnect = function() {
return this.xmpp.disconnect();
};
Session.prototype.onCard = function(callback) {
return this.listeners['card'].push(callback);
};
Session.prototype.onRoster = function(callback) {
return this.listeners['roster'].push(callback);
};
Session.prototype.onMessage = function(callback) {
return this.listeners['message'].push(callback);
};
Session.prototype.onPresence = function(callback) {
return this.listeners['presence'].push(callback);
};
Session.prototype.connected = function() {
return this.xmpp.jid && this.xmpp.jid.length > 0;
};
Session.prototype.jid = function() {
return this.xmpp.jid;
};
Session.prototype.bareJid = function() {
return this.xmpp.jid.split('/')[0];
};
Session.prototype.uniqueId = function() {
return this.xmpp.getUniqueId();
};
Session.prototype.avatar = function(jid) {
var card;
card = this.loadCard(jid);
if (card && card.photo) {
return "data:" + card.photo.type + ";base64," + card.photo.binval;
} else {
return '/lib/images/default-user.png';
}
};
Session.prototype.loadCard = function(jid) {
var found;
jid = jid.split('/')[0];
found = localStorage['vcard:' + jid];
if (found) {
return JSON.parse(found);
}
};
Session.prototype.storeCard = function(card) {
return localStorage['vcard:' + card.jid] = JSON.stringify(card);
};
Session.prototype.findCards = function() {
var contacts, jid, jids, success;
jids = (function() {
var _ref, _results;
_ref = this.roster;
_results = [];
for (jid in _ref) {
contacts = _ref[jid];
if (!this.loadCard(jid)) {
_results.push(jid);
}
}
return _results;
}).call(this);
if (!this.loadCard(this.bareJid())) {
jids.push(this.bareJid());
}
success = __bind(function(card) {
this.findCard(jids.shift(), success);
if (card) {
this.storeCard(card);
return this.notify('card', card);
}
}, this);
return this.findCard(jids.shift(), success);
};
Session.prototype.findCard = function(jid, callback) {
var node;
if (!jid) {
return;
}
node = this.xml("\n \n");
return this.sendIQ(node, function(result) {
var bin, card, photo, type, vcard;
card = $('vCard', result);
photo = $('PHOTO', card);
type = $('TYPE', photo).text();
bin = $('BINVAL', photo).text();
photo = type && bin ? {
type: type,
binval: bin.replace(/\n/g, '')
} : null;
vcard = {
jid: jid,
photo: photo,
retrieved: new Date()
};
return callback(card.size() > 0 ? vcard : null);
});
};
Session.prototype.parseRoster = function(node) {
return $('item', node).map(function() {
return new Contact(this);
}).get();
};
Session.prototype.findRoster = function(callback) {
var node;
node = $("\n \n");
return this.sendIQ(node.get(0), __bind(function(result) {
var contact, contacts, _i, _len;
contacts = this.parseRoster(result);
for (_i = 0, _len = contacts.length; _i < _len; _i++) {
contact = contacts[_i];
this.roster[contact.jid] = contact;
}
return callback();
}, this));
};
Session.prototype.sendMessage = function(jid, message) {
var node;
node = this.xml("\n \n");
$('body', node).text(message);
return this.xmpp.send(node);
};
Session.prototype.sendPresence = function(away, status) {
var node;
node = $('');
if (away) {
node.append($('xa'));
if (status !== 'Away') {
node.append($('').text(status));
}
} else {
if (status !== 'Available') {
node.append($('').text(status));
}
}
return this.xmpp.send(node.get(0));
};
Session.prototype.sendIQ = function(node, callback) {
return this.xmpp.sendIQ(node, callback, callback, 5000);
};
Session.prototype.updateContact = function(contact, add) {
var group, node, _i, _len, _ref;
node = $("\n \n \n \n");
$('item', node).attr('name', contact.name);
_ref = contact.groups;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
group = _ref[_i];
$('item', node).append($('').text(group));
}
this.xmpp.send(node.get(0));
if (add) {
return this.sendSubscribe(contact.jid);
}
};
Session.prototype.removeContact = function(jid) {
var node;
node = $("\n \n - \n
\n");
return this.xmpp.send(node.get(0));
};
Session.prototype.sendSubscribe = function(jid) {
return this.xmpp.send(this.presence(jid, 'subscribe'));
};
Session.prototype.sendSubscribed = function(jid) {
return this.xmpp.send(this.presence(jid, 'subscribed'));
};
Session.prototype.sendUnsubscribed = function(jid) {
return this.xmpp.send(this.presence(jid, 'unsubscribed'));
};
Session.prototype.presence = function(to, type) {
return $("").get(0);
};
Session.prototype.handleIq = function(node) {
var contact, contacts, ns, old, type, _i, _len;
node = $(node);
type = node.attr('type');
ns = node.find('query').attr('xmlns');
if (type === 'set' && ns === 'jabber:iq:roster') {
contacts = this.parseRoster(node);
for (_i = 0, _len = contacts.length; _i < _len; _i++) {
contact = contacts[_i];
if (contact.subscription === 'remove') {
delete this.roster[contact.jid];
} else {
old = this.roster[contact.jid];
if (old) {
contact.presence = old.presence;
}
this.roster[contact.jid] = contact;
}
}
this.notify('roster');
}
return true;
};
Session.prototype.handleMessage = function(node) {
var body, from, to, type;
node = $(node);
to = node.attr('to');
from = node.attr('from');
type = node.attr('type');
body = node.find('body').first();
if (type === 'chat' && body.size() > 0) {
this.notify('message', {
to: to,
from: from,
type: type,
text: body.text(),
received: new Date()
});
}
return true;
};
Session.prototype.handlePresence = function(node) {
var contact, from, presence, show, status, to, type;
node = $(node);
to = node.attr('to');
from = node.attr('from');
type = node.attr('type');
show = node.find('show').first();
status = node.find('status').first();
presence = {
to: to,
from: from,
status: status.text(),
show: show.text(),
type: type,
offline: type === 'unavailable' || type === 'error',
away: show.text() === 'away' || show.text() === 'xa',
dnd: show.text() === 'dnd'
};
contact = this.roster[from.split('/')[0]];
if (contact) {
contact.update(presence);
}
this.notify('presence', presence);
return true;
};
Session.prototype.notify = function(type, obj) {
var callback, _i, _len, _ref, _results;
_ref = this.listeners[type] || [];
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
callback = _ref[_i];
_results.push(callback(obj));
}
return _results;
};
Session.prototype.xml = function(xml) {
return $.parseXML(xml).documentElement;
};
return Session;
})();