2012-06-23 14:26:04 +02:00
|
|
|
var helpers = (function (helpers) {
|
|
|
|
helpers.oc = function (a) {
|
|
|
|
// Thanks to Jonathan Snook: http://snook.ca
|
|
|
|
var o = {};
|
|
|
|
for(var i=0; i<a.length; i++) {
|
|
|
|
o[a[i]]='';
|
|
|
|
}
|
|
|
|
return o;
|
|
|
|
};
|
2012-06-24 11:24:10 +02:00
|
|
|
|
|
|
|
helpers.hash = function (str) {
|
2012-06-23 14:26:04 +02:00
|
|
|
// FIXME
|
|
|
|
if (str == 'online-users-container') {
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
var shaobj = new jsSHA(str);
|
|
|
|
return shaobj.getHash("HEX");
|
|
|
|
};
|
2012-06-24 11:24:10 +02:00
|
|
|
|
|
|
|
helpers.size = function (obj) {
|
|
|
|
var size = 0, key;
|
|
|
|
for (key in obj) {
|
|
|
|
if (obj.hasOwnProperty(key)) {
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
};
|
|
|
|
|
2012-06-23 14:26:04 +02:00
|
|
|
return helpers;
|
|
|
|
})(helpers || {});
|
|
|
|
|
|
|
|
var xmppchat = (function (jarnxmpp, $, console) {
|
|
|
|
var ob = jarnxmpp;
|
2012-06-24 13:16:19 +02:00
|
|
|
/* FIXME: XEP-0136 specifies 'urn:xmpp:archive' but the mod_archive_odbc
|
|
|
|
* add-on for ejabberd wants the URL below. This might break for other
|
|
|
|
* Jabber servers.
|
|
|
|
*/
|
|
|
|
ob.Collections = {
|
|
|
|
'URI': 'http://www.xmpp.org/extensions/xep-0136.html#ns'
|
|
|
|
};
|
2012-06-23 14:26:04 +02:00
|
|
|
ob.Messages = jarnxmpp.Messages || {};
|
|
|
|
ob.Presence = jarnxmpp.Presence || {};
|
|
|
|
|
2012-06-24 12:06:37 +02:00
|
|
|
ob.isOwnUser = function (jid) {
|
|
|
|
return (Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(xmppchat.connection.jid));
|
|
|
|
};
|
|
|
|
|
2012-06-23 14:26:04 +02:00
|
|
|
ob.ChatPartners = (function () {
|
|
|
|
/* A mapping of bare JIDs to resources, to keep track of
|
|
|
|
* how many resources we have per chat partner.
|
|
|
|
*/
|
|
|
|
var storage = {};
|
|
|
|
var methods = {};
|
|
|
|
|
|
|
|
methods.add = function (bare_jid, resource) {
|
|
|
|
if (Object.prototype.hasOwnProperty.call(storage, bare_jid)) {
|
|
|
|
if (!(resource in helpers.oc(storage[bare_jid]))) {
|
|
|
|
storage[bare_jid].push(resource);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
storage[bare_jid] = [resource];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
methods.remove = function (bare_jid, resource) {
|
2012-06-24 12:06:37 +02:00
|
|
|
// Removes the resource for a user and returns the number of
|
|
|
|
// resources left over.
|
2012-06-23 14:26:04 +02:00
|
|
|
if (Object.prototype.hasOwnProperty.call(storage, bare_jid)) {
|
|
|
|
if (!(resource in helpers.oc(storage[bare_jid]))) {
|
|
|
|
var idx = storage[bare_jid].indexOf(resource);
|
|
|
|
if (idx !== undefined) {
|
|
|
|
storage[bare_jid].splice(idx, 1);
|
2012-06-24 12:06:37 +02:00
|
|
|
if (storage[bare_jid].length === 0) {
|
|
|
|
delete storage[bare_jid];
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return storage[bare_jid].length;
|
|
|
|
}
|
2012-06-23 14:26:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-06-24 12:06:37 +02:00
|
|
|
return 0;
|
2012-06-23 14:26:04 +02:00
|
|
|
};
|
2012-06-24 11:24:10 +02:00
|
|
|
|
|
|
|
methods.getTotal = function () {
|
|
|
|
return helpers.size(storage);
|
|
|
|
};
|
2012-06-24 12:06:37 +02:00
|
|
|
|
2012-06-23 14:26:04 +02:00
|
|
|
return methods;
|
|
|
|
})();
|
|
|
|
|
2012-07-01 12:03:43 +02:00
|
|
|
ob.Messages.ClientStorage = (function () {
|
|
|
|
methods = {};
|
|
|
|
|
|
|
|
methods.addMessage = function (jid, msg, direction) {
|
|
|
|
var bare_jid = Strophe.getBareJidFromJid(jid),
|
|
|
|
now = new Date().toISOString(),
|
|
|
|
msgs = store.get(bare_jid) || [];
|
|
|
|
if (msgs.length >= 30) {
|
|
|
|
msgs.pop();
|
|
|
|
}
|
|
|
|
msgs.push(now+' '+direction+' '+msg);
|
|
|
|
store.set(bare_jid, msgs);
|
|
|
|
};
|
|
|
|
|
|
|
|
methods.getMessages = function (jid) {
|
|
|
|
return store.get(jid) || [];
|
|
|
|
};
|
|
|
|
return methods;
|
|
|
|
})();
|
|
|
|
|
|
|
|
ob.Messages.getMessages = function (jid, callback) {
|
|
|
|
var bare_jid = Strophe.getBareJidFromJid(jid),
|
|
|
|
msgs = this.ClientStorage.getMessages(bare_jid);
|
|
|
|
callback(msgs);
|
|
|
|
};
|
|
|
|
|
2012-07-01 12:44:38 +02:00
|
|
|
ob.Messages.sendMessage = function (jid, text, callback) {
|
2012-06-23 14:26:04 +02:00
|
|
|
// TODO: Look in ChatPartners to see what resources we have for the recipient.
|
|
|
|
// if we have one resource, we sent to only that resources, if we have multiple
|
|
|
|
// we send to the bare jid.
|
2012-07-01 12:03:43 +02:00
|
|
|
// FIXME: see if @@content-transform is required
|
|
|
|
var message,
|
|
|
|
that = this;
|
2012-06-23 14:26:04 +02:00
|
|
|
$.getJSON(portal_url + '/content-transform?', {text: text}, function (data) {
|
2012-07-01 12:44:38 +02:00
|
|
|
message = $msg({to: jid, type: 'chat'})
|
|
|
|
.c('body').t(data.text).up()
|
|
|
|
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'});
|
2012-06-23 14:26:04 +02:00
|
|
|
xmppchat.connection.send(message);
|
2012-07-01 12:44:38 +02:00
|
|
|
that.ClientStorage.addMessage(jid, data.text, 'to');
|
2012-06-23 14:26:04 +02:00
|
|
|
callback();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
ob.Messages.messageReceived = function (message) {
|
|
|
|
var jid = $(message).attr('from'),
|
|
|
|
bare_jid = Strophe.getBareJidFromJid(jid),
|
|
|
|
resource = Strophe.getResourceFromJid(jid),
|
|
|
|
delayed = $(message).find('delay').length > 0;
|
|
|
|
|
|
|
|
ob.ChatPartners.add(bare_jid, resource);
|
|
|
|
|
|
|
|
var body = $(message).children('body').text();
|
|
|
|
if (body === "") {
|
|
|
|
// TODO:
|
|
|
|
return true; // This is a typing notification, we do not handle it here...
|
|
|
|
}
|
|
|
|
var xhtml_body = $(message).find('html > body').contents(),
|
|
|
|
event = jQuery.Event('jarnxmpp.message');
|
|
|
|
|
2012-07-01 12:03:43 +02:00
|
|
|
|
2012-06-23 14:26:04 +02:00
|
|
|
event.from = jid;
|
|
|
|
event.delayed = delayed;
|
|
|
|
if (xhtml_body.length > 0) {
|
|
|
|
event.mtype = 'xhtml';
|
|
|
|
event.body = xhtml_body.html();
|
|
|
|
} else {
|
|
|
|
event.body = body;
|
|
|
|
event.mtype = 'text';
|
|
|
|
}
|
2012-07-01 12:03:43 +02:00
|
|
|
ob.Messages.ClientStorage.addMessage(jid, event.body, 'from');
|
2012-06-23 14:26:04 +02:00
|
|
|
$(document).trigger(event);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2012-06-24 13:16:19 +02:00
|
|
|
ob.Collections.getLastCollection = function (jid, callback) {
|
|
|
|
var bare_jid = Strophe.getBareJidFromJid(jid),
|
|
|
|
iq = $iq({'type':'get'})
|
|
|
|
.c('list', {'xmlns': this.URI,
|
|
|
|
'with': bare_jid
|
2012-06-23 14:26:04 +02:00
|
|
|
})
|
|
|
|
.c('set', {'xmlns': 'http://jabber.org/protocol/rsm'})
|
2012-06-24 13:16:19 +02:00
|
|
|
.c('before').up()
|
2012-06-23 14:26:04 +02:00
|
|
|
.c('max')
|
2012-06-24 13:16:19 +02:00
|
|
|
.t('1');
|
|
|
|
|
|
|
|
xmppchat.connection.sendIQ(iq,
|
|
|
|
callback,
|
|
|
|
function () {
|
|
|
|
console.log('Error while retrieving collections');
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
ob.Collections.getLastMessages = function (jid, callback) {
|
|
|
|
var that = this;
|
|
|
|
this.getLastCollection(jid, function (result) {
|
2012-06-25 09:28:24 +02:00
|
|
|
// Retrieve the last page of a collection (max 30 elements).
|
2012-06-24 13:16:19 +02:00
|
|
|
var $collection = $(result).find('chat'),
|
|
|
|
jid = $collection.attr('with'),
|
|
|
|
start = $collection.attr('start'),
|
|
|
|
iq = $iq({'type':'get'})
|
|
|
|
.c('retrieve', {'start': start,
|
|
|
|
'xmlns': that.URI,
|
|
|
|
'with': jid
|
|
|
|
})
|
|
|
|
.c('set', {'xmlns': 'http://jabber.org/protocol/rsm'})
|
|
|
|
.c('max')
|
|
|
|
.t('30');
|
2012-06-25 09:28:24 +02:00
|
|
|
xmppchat.connection.sendIQ(iq, callback);
|
2012-06-24 13:16:19 +02:00
|
|
|
});
|
2012-06-23 14:26:04 +02:00
|
|
|
};
|
|
|
|
|
2012-06-24 11:24:10 +02:00
|
|
|
ob.Presence.onlineCount = function () {
|
|
|
|
return xmppchat.ChatPartners.getTotal();
|
|
|
|
};
|
|
|
|
|
2012-06-23 14:26:04 +02:00
|
|
|
ob.Presence.sendPresence = function (type) {
|
|
|
|
if (type === undefined) {
|
|
|
|
type = xmppchat.Storage.get(xmppchat.username+'-xmpp-status') || 'online';
|
|
|
|
}
|
|
|
|
xmppchat.connection.send($pres({'type':type}));
|
|
|
|
};
|
|
|
|
|
|
|
|
ob.Presence.presenceReceived = function (presence) {
|
|
|
|
var jid = $(presence).attr('from'),
|
|
|
|
bare_jid = Strophe.getBareJidFromJid(jid),
|
|
|
|
resource = Strophe.getResourceFromJid(jid),
|
|
|
|
ptype = $(presence).attr('type'),
|
|
|
|
status = '';
|
|
|
|
|
|
|
|
if (ptype === 'subscribe') {
|
|
|
|
// User wants to subscribe to us. Always approve and
|
|
|
|
// ask to subscribe to him
|
|
|
|
jarnxmpp.connection.send($pres({to: jid, type: 'subscribed'}));
|
|
|
|
jarnxmpp.connection.send($pres({to: jid, type: 'subscribe'}));
|
|
|
|
} else if (ptype !== 'error') { // Presence has changed
|
|
|
|
if (ptype === 'unavailable') {
|
|
|
|
status = 'unavailable';
|
|
|
|
} else if (ptype === 'offline') {
|
|
|
|
status = 'offline';
|
|
|
|
} else if (ptype === 'busy') {
|
|
|
|
status = 'busy';
|
|
|
|
} else if (ptype === 'away') {
|
|
|
|
status = 'away';
|
|
|
|
} else {
|
|
|
|
status = ($(presence).find('show').text() === '') ? 'online' : 'away';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((status !== 'offline')&&(status !== 'unavilable')) {
|
|
|
|
xmppchat.ChatPartners.add(bare_jid, resource);
|
|
|
|
} else {
|
|
|
|
xmppchat.ChatPartners.remove(bare_jid, resource);
|
|
|
|
}
|
|
|
|
$(document).trigger('jarnxmpp.presence', [jid, status, presence]);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
ob.Taskbuffer = (function ($) {
|
|
|
|
buffer = {};
|
|
|
|
buffer.tasks = [];
|
|
|
|
buffer.deferred = $.when();
|
|
|
|
buffer.handleTasks = function () {
|
|
|
|
var task;
|
|
|
|
// If the current deferred task is resolved and there are more tasks
|
|
|
|
if (buffer.deferred.isResolved() && buffer.tasks.length > 0) {
|
|
|
|
// Get the next task in the queue and set the new deferred.
|
|
|
|
task = buffer.tasks.shift();
|
|
|
|
|
|
|
|
buffer.deferred = $.when(task.method.apply(task.that, task.parameters));
|
|
|
|
|
|
|
|
if (buffer.tasks.length > 0) {
|
|
|
|
buffer.deferred.done(buffer.handleTasks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return buffer;
|
|
|
|
})(jQuery);
|
|
|
|
|
|
|
|
return ob;
|
|
|
|
})(jarnxmpp || {}, jQuery, console || {log: function(){}});
|
|
|
|
|
|
|
|
|